From d7b428c1dae66b2a85b7a6bfa7b253980b5b963c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bend=C3=ADk?= Date: Mon, 16 Dec 2013 18:31:51 +0100 Subject: [PATCH] Added cedarx decoder. --- QtAV.pro | 2 +- config.tests/libcedarv/libcedardrv.pro | 5 + config.tests/libcedarv/main.cpp | 26 ++ src/AVPlayer.cpp | 3 + src/QtAV/VideoDecoderTypes.h | 1 + src/VideoDecoderCedarv.cpp | 328 +++++++++++++++++++++++++ src/VideoDecoderTypes.cpp | 1 + src/libQtAV.pro | 5 + 8 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 config.tests/libcedarv/libcedardrv.pro create mode 100644 config.tests/libcedarv/main.cpp create mode 100644 src/VideoDecoderCedarv.cpp diff --git a/QtAV.pro b/QtAV.pro index ea3c2a080..cf8006046 100644 --- a/QtAV.pro +++ b/QtAV.pro @@ -30,7 +30,7 @@ win32 { OptionalDepends += dxva } unix { - OptionalDepends += xv vaapi + OptionalDepends += xv vaapi libcedarv } include(root.pri) diff --git a/config.tests/libcedarv/libcedardrv.pro b/config.tests/libcedarv/libcedardrv.pro new file mode 100644 index 000000000..2d6b9232a --- /dev/null +++ b/config.tests/libcedarv/libcedardrv.pro @@ -0,0 +1,5 @@ +CONFIG -= qt +CONFIG += console +SOURCES += main.cpp + +LIBS += -lvecore -lcedarv diff --git a/config.tests/libcedarv/main.cpp b/config.tests/libcedarv/main.cpp new file mode 100644 index 000000000..4e0c7ab3c --- /dev/null +++ b/config.tests/libcedarv/main.cpp @@ -0,0 +1,26 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ +#include + +int main() +{ + return 0; +} diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index 3e80c14d1..860454525 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -119,6 +119,9 @@ AVPlayer::AVPlayer(QObject *parent) : #if QTAV_HAVE(VAAPI) << VideoDecoderId_VAAPI #endif //QTAV_HAVE(VAAPI) +#if QTAV_HAVE(CEDARV) + << VideoDecoderId_Cedarv +#endif //QTAV_HAVE(CEDARV) << VideoDecoderId_FFmpeg; } diff --git a/src/QtAV/VideoDecoderTypes.h b/src/QtAV/VideoDecoderTypes.h index b1a6af154..b095da31b 100644 --- a/src/QtAV/VideoDecoderTypes.h +++ b/src/QtAV/VideoDecoderTypes.h @@ -37,6 +37,7 @@ extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg; extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_CUDA; extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_DXVA; extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_VAAPI; +extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_Cedarv; extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDPAU; extern Q_AV_EXPORT VideoDecoderId VideoDecoderId_FFmpeg_VDA; diff --git a/src/VideoDecoderCedarv.cpp b/src/VideoDecoderCedarv.cpp new file mode 100644 index 000000000..5376b9d6d --- /dev/null +++ b/src/VideoDecoderCedarv.cpp @@ -0,0 +1,328 @@ +/****************************************************************************** + QtAV: Media play library based on Qt and FFmpeg + Copyright (C) 2013 Wang Bin + +* This file is part of QtAV + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +******************************************************************************/ + +#include "QtAV/VideoDecoderFFmpeg.h" +#include "private/VideoDecoderFFmpeg_p.h" +#include +#include +#include "prepost.h" + +#include + +#include +extern "C" +{ + #include +} + +static void map32x32_to_yuv_Y(unsigned char* srcY, unsigned char* tarY, unsigned int coded_width, unsigned int coded_height) +{ + unsigned int i,j,l,m,n; + unsigned int mb_width,mb_height,twomb_line,recon_width; + unsigned long offset; + unsigned char *ptr; + + ptr = srcY; + mb_width = (coded_width+15)>>4; + mb_height = (coded_height+15)>>4; + twomb_line = (mb_height+1)>>1; + recon_width = (mb_width+1)&0xfffffffe; + + for(i=0;i>3; + mb_height = (coded_height+7)>>3; + fourmb_line = (mb_height+3)>>2; + recon_width = (mb_width+1)&0xfffffffe; + + for(i=0;iopaque = &d; //is it ok? + + cedarv_stream_info_t cedarStreamInfo; + memset(&cedarStreamInfo, 0, sizeof cedarStreamInfo); + + switch (d.codec_ctx->codec_id) { + case AV_CODEC_ID_H264: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_H264; + break; + case AV_CODEC_ID_VP8: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_VP8; + break; + case AV_CODEC_ID_VC1: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_VC1; + break; + case AV_CODEC_ID_MPEG4: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_MPEG4; + cedarStreamInfo.sub_format = CEDARV_MPEG4_SUB_FORMAT_XVID; + break; + case AV_CODEC_ID_MPEG2VIDEO: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_MPEG2; + break; + case AV_CODEC_ID_RV40: + cedarStreamInfo.format = CEDARV_STREAM_FORMAT_REALVIDEO; + break; + default: + return false; + } + cedarStreamInfo.video_width = d.codec_ctx->width; + cedarStreamInfo.video_height = d.codec_ctx->height; + if (d.codec_ctx->extradata_size) { + cedarStreamInfo.init_data = d.codec_ctx->extradata; + cedarStreamInfo.init_data_len = d.codec_ctx->extradata_size; + } + + int cedarvRet; + cedarvRet = d.cedarv->set_vstream_info(d.cedarv, &cedarStreamInfo); + if (cedarvRet < 0) + return false; + cedarvRet = d.cedarv->open(d.cedarv); + if (cedarvRet < 0) + return false; + + d.cedarv->ioctrl(d.cedarv, CEDARV_COMMAND_PLAY, 0); + + return true; +} + +bool VideoDecoderCedarv::decode(const QByteArray &encoded) +{ + DPTR_D(VideoDecoderCedarv); + + //d.cedarv->ioctrl(d.cedarv, CEDARV_COMMAND_JUMP, 0); + + AVPacket packet; + av_new_packet(&packet, encoded.size()); + memcpy(packet.data, encoded.data(), encoded.size()); + + if (packet.size == 0) { + return true; + } + + u32 bufsize0, bufsize1; + u8 *buf0, *buf1; + + if (d.cedarv->request_write(d.cedarv, packet.size, &buf0, &bufsize0, &buf1, &bufsize1) >= 0) { + memcpy(buf0, packet.data, bufsize0); + if ((u32)packet.size > bufsize0) { + memcpy(buf1, packet.data + bufsize0, bufsize1); + } + cedarv_stream_data_info_t stream_data_info; + stream_data_info.type = 0; + stream_data_info.lengh = packet.size; + stream_data_info.pts = packet.pts; + stream_data_info.flags = CEDARV_FLAG_FIRST_PART | CEDARV_FLAG_LAST_PART | CEDARV_FLAG_PTS_VALID; + d.cedarv->update_data(d.cedarv, &stream_data_info); + if (d.cedarv->decode(d.cedarv) >= 0 && !d.cedarv->display_request(d.cedarv, &d.cedarPicture)) { + } + else { + if (d.cedarPicture.id) { + d.cedarv->display_release(d.cedarv, d.cedarPicture.id); + d.cedarPicture.id = 0; + } + } + } + return true; +} + + +VideoFrame VideoDecoderCedarv::frame() +{ + DPTR_D(VideoDecoderCedarv); + if (!d.cedarPicture.id) { + return VideoFrame(); + } + VideoFrame frame = VideoFrame(d.cedarPicture.width, d.cedarPicture.height, VideoFormat(VideoFormat::Format_YUV420P)); + if ((unsigned int)d.y.size() != d.cedarPicture.size_y) { + d.y.resize(d.cedarPicture.size_y); + } + if ((unsigned int)d.u.size() != d.cedarPicture.size_u / 2) { + d.u.resize(d.cedarPicture.size_u / 2); + } + if ((unsigned int)d.v.size() != d.cedarPicture.size_u / 2) { + d.v.resize(d.cedarPicture.size_u / 2); + } + int bitsPerLine_Y = d.cedarPicture.size_y / d.cedarPicture.height; + int bitsPerRow_Y = d.cedarPicture.size_y / bitsPerLine_Y; + map32x32_to_yuv_Y(d.cedarPicture.y, (uchar *)d.y.data(), bitsPerLine_Y, bitsPerRow_Y); + map32x32_to_yuv_C(d.cedarPicture.u, (uchar *)d.u.data(), (uchar *)d.v.data(), bitsPerLine_Y / 2, bitsPerRow_Y / 2); + frame.setBits((uchar *)d.y.data(), 0); + frame.setBytesPerLine(d.cedarPicture.size_y / d.cedarPicture.height, 0); + frame.setBits((uchar *)d.u.data(), 1); + frame.setBytesPerLine(bitsPerLine_Y / 2, 1); + frame.setBits((uchar *)d.v.data(), 2); + frame.setBytesPerLine(bitsPerLine_Y / 2, 2); + + d.cedarv->display_release(d.cedarv, d.cedarPicture.id); + d.cedarPicture.id = 0; + return frame; +} + + +} // namespace QtAV diff --git a/src/VideoDecoderTypes.cpp b/src/VideoDecoderTypes.cpp index a4a4c693d..bdc7eb196 100644 --- a/src/VideoDecoderTypes.cpp +++ b/src/VideoDecoderTypes.cpp @@ -7,6 +7,7 @@ VideoDecoderId VideoDecoderId_FFmpeg = 1; VideoDecoderId VideoDecoderId_CUDA = 2; VideoDecoderId VideoDecoderId_DXVA = 3; VideoDecoderId VideoDecoderId_VAAPI = 4; +VideoDecoderId VideoDecoderId_Cedarv = 5; QVector GetRegistedVideoDecoderIds() { diff --git a/src/libQtAV.pro b/src/libQtAV.pro index ff191646d..34438e1b3 100644 --- a/src/libQtAV.pro +++ b/src/libQtAV.pro @@ -116,6 +116,11 @@ config_vaapi { SOURCES += VideoDecoderVAAPI.cpp LIBS += -lva -lva-x11 #TODO: dynamic load } +config_libcedarv { + DEFINES *= QTAV_HAVE_CEDARV=1 + SOURCES += VideoDecoderCedarv.cpp + LIBS += -lvecore -lcedarv +} SOURCES += \ QtAV_Compat.cpp \ QtAV_Global.cpp \