Skip to content

Commit d7b428c

Browse files
committed
Added cedarx decoder.
1 parent 7231c61 commit d7b428c

File tree

8 files changed

+370
-1
lines changed

8 files changed

+370
-1
lines changed

QtAV.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ win32 {
3030
OptionalDepends += dxva
3131
}
3232
unix {
33-
OptionalDepends += xv vaapi
33+
OptionalDepends += xv vaapi libcedarv
3434
}
3535

3636
include(root.pri)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONFIG -= qt
2+
CONFIG += console
3+
SOURCES += main.cpp
4+
5+
LIBS += -lvecore -lcedarv

config.tests/libcedarv/main.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/******************************************************************************
2+
QtAV: Media play library based on Qt and FFmpeg
3+
Copyright (C) 2013 Wang Bin <[email protected]>
4+
5+
* This file is part of QtAV
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
******************************************************************************/
21+
#include <libcedarv/libcedarv.h>
22+
23+
int main()
24+
{
25+
return 0;
26+
}

src/AVPlayer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ AVPlayer::AVPlayer(QObject *parent) :
119119
#if QTAV_HAVE(VAAPI)
120120
<< VideoDecoderId_VAAPI
121121
#endif //QTAV_HAVE(VAAPI)
122+
#if QTAV_HAVE(CEDARV)
123+
<< VideoDecoderId_Cedarv
124+
#endif //QTAV_HAVE(CEDARV)
122125
<< VideoDecoderId_FFmpeg;
123126
}
124127

src/QtAV/VideoDecoderTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg;
3737
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_CUDA;
3838
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_DXVA;
3939
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_VAAPI;
40+
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_Cedarv;
4041
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDPAU;
4142
extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDA;
4243

src/VideoDecoderCedarv.cpp

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/******************************************************************************
2+
QtAV: Media play library based on Qt and FFmpeg
3+
Copyright (C) 2013 Wang Bin <[email protected]>
4+
5+
* This file is part of QtAV
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
******************************************************************************/
21+
22+
#include "QtAV/VideoDecoderFFmpeg.h"
23+
#include "private/VideoDecoderFFmpeg_p.h"
24+
#include <QtAV/Packet.h>
25+
#include <QtAV/QtAV_Compat.h>
26+
#include "prepost.h"
27+
28+
#include <QDebug>
29+
30+
#include <libavcodec/avcodec.h>
31+
extern "C"
32+
{
33+
#include <libcedarv/libcedarv.h>
34+
}
35+
36+
static void map32x32_to_yuv_Y(unsigned char* srcY, unsigned char* tarY, unsigned int coded_width, unsigned int coded_height)
37+
{
38+
unsigned int i,j,l,m,n;
39+
unsigned int mb_width,mb_height,twomb_line,recon_width;
40+
unsigned long offset;
41+
unsigned char *ptr;
42+
43+
ptr = srcY;
44+
mb_width = (coded_width+15)>>4;
45+
mb_height = (coded_height+15)>>4;
46+
twomb_line = (mb_height+1)>>1;
47+
recon_width = (mb_width+1)&0xfffffffe;
48+
49+
for(i=0;i<twomb_line;i++)
50+
{
51+
for(j=0;j<recon_width;j+=2)
52+
{
53+
for(l=0;l<32;l++)
54+
{
55+
//first mb
56+
m=i*32 + l;
57+
n= j*16;
58+
if(m<coded_height && n<coded_width)
59+
{
60+
offset = m*coded_width + n;
61+
memcpy(tarY+offset,ptr,16);
62+
ptr += 16;
63+
}
64+
else
65+
ptr += 16;
66+
67+
//second mb
68+
n= j*16+16;
69+
if(m<coded_height && n<coded_width)
70+
{
71+
offset = m*coded_width + n;
72+
memcpy(tarY+offset,ptr,16);
73+
ptr += 16;
74+
}
75+
else
76+
ptr += 16;
77+
}
78+
}
79+
}
80+
}
81+
82+
static void map32x32_to_yuv_C(unsigned char* srcC,unsigned char* tarCb,unsigned char* tarCr,unsigned int coded_width,unsigned int coded_height)
83+
{
84+
/*
85+
unsigned int i,j,k;
86+
87+
for (i = 0; i < coded_width; ++i) {
88+
k = i * coded_width;
89+
for (j = 0; j < coded_height; ++j) {
90+
*(tarCb + k) = srcC[2*k];
91+
*(tarCr + k) = srcC[2*k+1];
92+
k++;
93+
}
94+
}
95+
*/
96+
unsigned int i,j,l,m,n,k;
97+
unsigned int mb_width,mb_height,fourmb_line,recon_width;
98+
unsigned char line[16];
99+
unsigned long offset;
100+
unsigned char *ptr;
101+
102+
ptr = srcC;
103+
mb_width = (coded_width+7)>>3;
104+
mb_height = (coded_height+7)>>3;
105+
fourmb_line = (mb_height+3)>>2;
106+
recon_width = (mb_width+1)&0xfffffffe;
107+
108+
for(i=0;i<fourmb_line;i++)
109+
{
110+
for(j=0;j<recon_width;j+=2)
111+
{
112+
for(l=0;l<32;l++)
113+
{
114+
//first mb
115+
m=i*32 + l;
116+
n= j*8;
117+
if(m<coded_height && n<coded_width)
118+
{
119+
offset = m*coded_width + n;
120+
memcpy(line,ptr,16);
121+
for(k=0;k<8;k++)
122+
{
123+
*(tarCb + offset + k) = line[2*k];
124+
*(tarCr + offset + k) = line[2*k+1];
125+
}
126+
ptr += 16;
127+
}
128+
else
129+
ptr += 16;
130+
131+
//second mb
132+
n= j*8+8;
133+
if(m<coded_height && n<coded_width)
134+
{
135+
offset = m*coded_width + n;
136+
memcpy(line,ptr,16);
137+
for(k=0;k<8;k++)
138+
{
139+
*(tarCb + offset + k) = line[2*k];
140+
*(tarCr + offset + k) = line[2*k+1];
141+
}
142+
ptr += 16;
143+
}
144+
else
145+
ptr += 16;
146+
}
147+
}
148+
}
149+
}
150+
151+
namespace QtAV {
152+
153+
class VideoDecoderCedarvPrivate;
154+
class VideoDecoderCedarv : public VideoDecoderFFmpeg
155+
{
156+
DPTR_DECLARE_PRIVATE(VideoDecoderCedarv)
157+
public:
158+
VideoDecoderCedarv();
159+
bool prepare();
160+
bool decode(const QByteArray &encoded);
161+
VideoFrame frame();
162+
};
163+
164+
extern VideoDecoderId VideoDecoderId_Cedarv;
165+
FACTORY_REGISTER_ID_AUTO(VideoDecoder, Cedarv, "Cedarv")
166+
167+
void RegisterVideoDecoderCedarv_Man()
168+
{
169+
FACTORY_REGISTER_ID_MAN(VideoDecoder, Cedarv, "Cedarv")
170+
}
171+
172+
class VideoDecoderCedarvPrivate : public VideoDecoderFFmpegPrivate
173+
{
174+
public:
175+
VideoDecoderCedarvPrivate() {
176+
cedarv = 0;
177+
}
178+
179+
~VideoDecoderCedarvPrivate() {
180+
//TODO:
181+
}
182+
183+
CEDARV_DECODER *cedarv;
184+
cedarv_picture_t cedarPicture;
185+
QByteArray y;
186+
QByteArray u;
187+
QByteArray v;
188+
};
189+
190+
VideoDecoderCedarv::VideoDecoderCedarv()
191+
: VideoDecoderFFmpeg(*new VideoDecoderCedarvPrivate())
192+
{
193+
}
194+
195+
196+
bool VideoDecoderCedarv::prepare()
197+
{
198+
DPTR_D(VideoDecoderCedarv);
199+
if (!d.cedarv) {
200+
int ret;
201+
d.cedarv = libcedarv_init(&ret);
202+
if (ret < 0 || d.cedarv == NULL)
203+
return false;
204+
}
205+
206+
d.codec_ctx->opaque = &d; //is it ok?
207+
208+
cedarv_stream_info_t cedarStreamInfo;
209+
memset(&cedarStreamInfo, 0, sizeof cedarStreamInfo);
210+
211+
switch (d.codec_ctx->codec_id) {
212+
case AV_CODEC_ID_H264:
213+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_H264;
214+
break;
215+
case AV_CODEC_ID_VP8:
216+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_VP8;
217+
break;
218+
case AV_CODEC_ID_VC1:
219+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_VC1;
220+
break;
221+
case AV_CODEC_ID_MPEG4:
222+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_MPEG4;
223+
cedarStreamInfo.sub_format = CEDARV_MPEG4_SUB_FORMAT_XVID;
224+
break;
225+
case AV_CODEC_ID_MPEG2VIDEO:
226+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_MPEG2;
227+
break;
228+
case AV_CODEC_ID_RV40:
229+
cedarStreamInfo.format = CEDARV_STREAM_FORMAT_REALVIDEO;
230+
break;
231+
default:
232+
return false;
233+
}
234+
cedarStreamInfo.video_width = d.codec_ctx->width;
235+
cedarStreamInfo.video_height = d.codec_ctx->height;
236+
if (d.codec_ctx->extradata_size) {
237+
cedarStreamInfo.init_data = d.codec_ctx->extradata;
238+
cedarStreamInfo.init_data_len = d.codec_ctx->extradata_size;
239+
}
240+
241+
int cedarvRet;
242+
cedarvRet = d.cedarv->set_vstream_info(d.cedarv, &cedarStreamInfo);
243+
if (cedarvRet < 0)
244+
return false;
245+
cedarvRet = d.cedarv->open(d.cedarv);
246+
if (cedarvRet < 0)
247+
return false;
248+
249+
d.cedarv->ioctrl(d.cedarv, CEDARV_COMMAND_PLAY, 0);
250+
251+
return true;
252+
}
253+
254+
bool VideoDecoderCedarv::decode(const QByteArray &encoded)
255+
{
256+
DPTR_D(VideoDecoderCedarv);
257+
258+
//d.cedarv->ioctrl(d.cedarv, CEDARV_COMMAND_JUMP, 0);
259+
260+
AVPacket packet;
261+
av_new_packet(&packet, encoded.size());
262+
memcpy(packet.data, encoded.data(), encoded.size());
263+
264+
if (packet.size == 0) {
265+
return true;
266+
}
267+
268+
u32 bufsize0, bufsize1;
269+
u8 *buf0, *buf1;
270+
271+
if (d.cedarv->request_write(d.cedarv, packet.size, &buf0, &bufsize0, &buf1, &bufsize1) >= 0) {
272+
memcpy(buf0, packet.data, bufsize0);
273+
if ((u32)packet.size > bufsize0) {
274+
memcpy(buf1, packet.data + bufsize0, bufsize1);
275+
}
276+
cedarv_stream_data_info_t stream_data_info;
277+
stream_data_info.type = 0;
278+
stream_data_info.lengh = packet.size;
279+
stream_data_info.pts = packet.pts;
280+
stream_data_info.flags = CEDARV_FLAG_FIRST_PART | CEDARV_FLAG_LAST_PART | CEDARV_FLAG_PTS_VALID;
281+
d.cedarv->update_data(d.cedarv, &stream_data_info);
282+
if (d.cedarv->decode(d.cedarv) >= 0 && !d.cedarv->display_request(d.cedarv, &d.cedarPicture)) {
283+
}
284+
else {
285+
if (d.cedarPicture.id) {
286+
d.cedarv->display_release(d.cedarv, d.cedarPicture.id);
287+
d.cedarPicture.id = 0;
288+
}
289+
}
290+
}
291+
return true;
292+
}
293+
294+
295+
VideoFrame VideoDecoderCedarv::frame()
296+
{
297+
DPTR_D(VideoDecoderCedarv);
298+
if (!d.cedarPicture.id) {
299+
return VideoFrame();
300+
}
301+
VideoFrame frame = VideoFrame(d.cedarPicture.width, d.cedarPicture.height, VideoFormat(VideoFormat::Format_YUV420P));
302+
if ((unsigned int)d.y.size() != d.cedarPicture.size_y) {
303+
d.y.resize(d.cedarPicture.size_y);
304+
}
305+
if ((unsigned int)d.u.size() != d.cedarPicture.size_u / 2) {
306+
d.u.resize(d.cedarPicture.size_u / 2);
307+
}
308+
if ((unsigned int)d.v.size() != d.cedarPicture.size_u / 2) {
309+
d.v.resize(d.cedarPicture.size_u / 2);
310+
}
311+
int bitsPerLine_Y = d.cedarPicture.size_y / d.cedarPicture.height;
312+
int bitsPerRow_Y = d.cedarPicture.size_y / bitsPerLine_Y;
313+
map32x32_to_yuv_Y(d.cedarPicture.y, (uchar *)d.y.data(), bitsPerLine_Y, bitsPerRow_Y);
314+
map32x32_to_yuv_C(d.cedarPicture.u, (uchar *)d.u.data(), (uchar *)d.v.data(), bitsPerLine_Y / 2, bitsPerRow_Y / 2);
315+
frame.setBits((uchar *)d.y.data(), 0);
316+
frame.setBytesPerLine(d.cedarPicture.size_y / d.cedarPicture.height, 0);
317+
frame.setBits((uchar *)d.u.data(), 1);
318+
frame.setBytesPerLine(bitsPerLine_Y / 2, 1);
319+
frame.setBits((uchar *)d.v.data(), 2);
320+
frame.setBytesPerLine(bitsPerLine_Y / 2, 2);
321+
322+
d.cedarv->display_release(d.cedarv, d.cedarPicture.id);
323+
d.cedarPicture.id = 0;
324+
return frame;
325+
}
326+
327+
328+
} // namespace QtAV

src/VideoDecoderTypes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ VideoDecoderId VideoDecoderId_FFmpeg = 1;
77
VideoDecoderId VideoDecoderId_CUDA = 2;
88
VideoDecoderId VideoDecoderId_DXVA = 3;
99
VideoDecoderId VideoDecoderId_VAAPI = 4;
10+
VideoDecoderId VideoDecoderId_Cedarv = 5;
1011

1112
QVector<VideoDecoderId> GetRegistedVideoDecoderIds()
1213
{

0 commit comments

Comments
 (0)