From b03abbfdbe31b8b316e237d3307fdf44cbcd33e8 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Sat, 24 Oct 2015 23:28:20 +0800 Subject: [PATCH] coda vpu: decode without read for eof packets. clean up --- src/codec/video/SurfaceInteropGAL.cpp | 3 +- src/codec/video/SurfaceInteropGAL.h | 5 +- src/codec/video/VideoDecoderVPU.cpp | 137 +++++++++----------------- src/codec/video/viv/GALScaler.cpp | 1 - src/codec/video/viv/GALScaler.h | 1 - 5 files changed, 51 insertions(+), 96 deletions(-) diff --git a/src/codec/video/SurfaceInteropGAL.cpp b/src/codec/video/SurfaceInteropGAL.cpp index 9f256a3b..27addc8b 100644 --- a/src/codec/video/SurfaceInteropGAL.cpp +++ b/src/codec/video/SurfaceInteropGAL.cpp @@ -9,7 +9,6 @@ void dma_copy_from_vmem(unsigned char* dst, unsigned int src, int len); } namespace QtAV { namespace vpu { - InteropResource::InteropResource() : scaler(0) {} @@ -48,7 +47,7 @@ bool InteropResource::map(const FBSurfacePtr &surface, VideoFrame *img, int) // qMin(scaler->outHeight(), img->height) dma_copy_from_vmem(img->bits(0), (unsigned int)(quintptr)scaler->outPlanes().at(0), img->bytesPerLine(0)*img->height()); } else { - qWarning("different gpu/host_mem stride"); + qWarning("different stride. vmem: %d, host: %d", img->bytesPerLine(0), scaler->outLineSizes().at(0)); for (int i = 0; i < img->height(); ++i) dma_copy_from_vmem(img->bits(0) + i*img->bytesPerLine(0), (unsigned int)(quintptr)scaler->outPlanes().at(0) + i*scaler->outLineSizes().at(0), img->bytesPerLine(0)); } diff --git a/src/codec/video/SurfaceInteropGAL.h b/src/codec/video/SurfaceInteropGAL.h index 3037a821..d90bd92e 100644 --- a/src/codec/video/SurfaceInteropGAL.h +++ b/src/codec/video/SurfaceInteropGAL.h @@ -32,7 +32,7 @@ public: /*! * \brief map * \param surface vpu decoded surface - * \param info [width, height, linesize] + * \param img contains the target frame information * \param w frame width(visual width) without alignment, <= vpu surface width * \param h frame height(visual height) * \param plane useless now @@ -55,11 +55,10 @@ public: * \param frame_h frame height(visual height) */ void setSurface(const FBSurfacePtr& surface, int frame_w, int frame_h); - /// GLTextureSurface only supports rgb32 void* map(SurfaceType type, const VideoFormat& fmt, void* handle, int plane) Q_DECL_OVERRIDE; void unmap(void *) Q_DECL_OVERRIDE {} protected: - /// copy from gpu (optimized if possible) and convert to target format if necessary + /// copy from gpu (optimized if possible) and convert to target format + scaled to target size if necessary void* mapToHost(const VideoFormat &format, void *handle, int plane); private: InteropResourcePtr m_resource; diff --git a/src/codec/video/VideoDecoderVPU.cpp b/src/codec/video/VideoDecoderVPU.cpp index ed6714d5..d5800d88 100644 --- a/src/codec/video/VideoDecoderVPU.cpp +++ b/src/codec/video/VideoDecoderVPU.cpp @@ -1,23 +1,4 @@ /****************************************************************************** - QtAV: Media play library based on Qt and FFmpeg - Copyright (C) 2013-2015 Wang Bin - Miroslav Bendik - -* 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/VideoDecoder.h" @@ -94,9 +75,10 @@ class VideoDecoderVPUPrivate Q_DECL_FINAL: public VideoDecoderPrivate public: VideoDecoderVPUPrivate() : VideoDecoderPrivate() - , instIdx(0), coreIdx(0) + , coreIdx(0) , tiled2LinearEnable(false) //? , mapType(LINEAR_FRAME_MAP) //? + , instIdx(0) , chunkReuseRequired(false) , seqInited(false), seqFilled(false) , bsfillSize(0) @@ -125,11 +107,12 @@ public: bool initSeq(); bool processHeaders(int* seqHeaderSize, int* picHeaderSize, const Packet& pkt, int fps_num, int fps_den, int nb_index_entries); // user config - int instIdx, coreIdx; //0 + int coreIdx; // MAX_NUM_VPU_CORE = 1 bool useRot, useDering; //false bool tiled2LinearEnable; TiledMapType mapType; // vpu status + int instIdx; bool chunkReuseRequired; //false bool seqInited, seqFilled; //false int bsfillSize; //0 @@ -420,9 +403,6 @@ bool VideoDecoderVPUPrivate::open() bsfillSize = 0; chunkReuseRequired = false; frameIdx = 0; - width = codec_ctx->width; - height = codec_ctx->height; - qDebug("open ok. size: %dx%d", width, height); interop_res = vpu::InteropResourcePtr(new vpu::InteropResource()); return true; } @@ -530,30 +510,14 @@ qDebug("initSeq: %d", seqInited); framebufHeight = FFALIGN(scaledHeight, 32); // framebufheight must be aligned by 31 because of the number of MB height would be odd in each filed picture. else framebufHeight = FFALIGN(scaledHeight, 16); -#ifdef SUPPORT_USE_VPU_ROTATOR - rotbufWidth = (decConfig.rotAngle == 90 || decConfig.rotAngle == 270) ? - FFALIGN(scaledHeight, 16) : FFALIGN(scaledWidth, 16); - rotbufHeight = (decConfig.rotAngle == 90 || decConfig.rotAngle == 270) ? - FFALIGN(scaledWidth, 16) : FFALIGN(scaledHeight, 16); -#endif } else { framebufWidth = FFALIGN(initialInfo.picWidth, 16); - // TODO: vpurun decConfig.maxHeight // TODO: omx fbHeight align 16 if (IsSupportInterlaceMode(decOP.bitstreamFormat, &initialInfo)) framebufHeight = FFALIGN(initialInfo.picHeight, 32); // framebufheight must be aligned by 31 because of the number of MB height would be odd in each filed picture. else framebufHeight = FFALIGN(initialInfo.picHeight, 16); -#ifdef SUPPORT_USE_VPU_ROTATOR - rotbufWidth = (decConfig.rotAngle == 90 || decConfig.rotAngle == 270) ? - FFALIGN(initialInfo.picHeight, 16) : FFALIGN(initialInfo.picWidth, 16); - rotbufHeight = (decConfig.rotAngle == 90 || decConfig.rotAngle == 270) ? - FFALIGN(initialInfo.picWidth, 16) : FFALIGN(initialInfo.picHeight, 16); -#endif } -#ifdef SUPPORT_USE_VPU_ROTATOR - rotStride = rotbufWidth; -#endif framebufStride = framebufWidth; framebufFormat = FORMAT_420; // vpurun: allocate out buffer of size framebufSize for rendering. we do not need it @@ -642,59 +606,57 @@ bool VideoDecoderVPU::decode(const Packet &packet) qWarning("decode finished"); return false; } - if (packet.data.isEmpty()) - return true; - if (packet.isEOF()) { //decode the trailing frames + QByteArray chunkData(packet.data); + DecOpenParam &decOP = d.decOP; + int seqHeaderSize = 0; //also used in FLUSH_BUFFER + int picHeaderSize = 0; + if (packet.isEOF()) { if (!d.flush()) { qDebug("Error decode EOS"); // when? return false; } + chunkData = QByteArray(); //decode the trailing frames qDebug("eof packet"); - //goto FLUSH_BUFFER; //TODO: decode trailing frames - } - QByteArray chunkData(packet.data); - DecOpenParam &decOP = d.decOP; - if (decOP.bitstreamMode == BS_MODE_PIC_END) { //TODO: no check in omx. it's always true here + } else { + if (decOP.bitstreamMode == BS_MODE_PIC_END) { //TODO: no check in omx. it's always true here + if (!d.chunkReuseRequired) { + qDebug("!chunkReuseRequired VPU_DecSetRdPtr"); + VPU_DecSetRdPtr(d.handle, decOP.bitstreamBuffer, 1); + } + } if (!d.chunkReuseRequired) { -qDebug("!chunkReuseRequired VPU_DecSetRdPtr"); - VPU_DecSetRdPtr(d.handle, decOP.bitstreamBuffer, 1); + if (!d.processHeaders(&seqHeaderSize, &picHeaderSize, packet, property("fps_num").toInt(), property("fps_den").toInt(), property("nb_index_entries").toInt())) { + qWarning("procesHeader error"); + return false; + } + } + // Fill VCL data + switch(decOP.bitstreamFormat) { + case STD_VP3: + case STD_THO: + //const int size = WriteBsBufFromBufHelper(coreIdx, handle, &vbStream, picHeader, picHeaderSize, decOP.streamEndian); + break; + default: { + if (decOP.bitstreamFormat == STD_RV) { + const int cSlice = chunkData.at(0) + 1; + chunkData.remove(0, 1+(cSlice*8)); + } + const int size = WriteBsBufFromBufHelper(d.coreIdx, d.handle, &d.vbStream, (BYTE*)chunkData.constData(), chunkData.size(), decOP.streamEndian); + if (size <0) { + qWarning("WriteBsBufFromBufHelper failed Error code is 0x%x", size); + return false; + } + d.bsfillSize += size; } - } - int seqHeaderSize = 0; //also used in FLUSH_BUFFER - int picHeaderSize = 0; - if (!d.chunkReuseRequired) { - if (!d.processHeaders(&seqHeaderSize, &picHeaderSize, packet, property("fps_num").toInt(), property("fps_den").toInt(), property("nb_index_entries").toInt())) { - qWarning("procesHeader error"); - return false; - } - } - // Fill VCL data - switch(decOP.bitstreamFormat) { - case STD_VP3: - case STD_THO: - //const int size = WriteBsBufFromBufHelper(coreIdx, handle, &vbStream, picHeader, picHeaderSize, decOP.streamEndian); break; - default: { - if (decOP.bitstreamFormat == STD_RV) { - const int cSlice = chunkData.at(0) + 1; - chunkData.remove(0, 1+(cSlice*8)); } - const int size = WriteBsBufFromBufHelper(d.coreIdx, d.handle, &d.vbStream, (BYTE*)chunkData.constData(), chunkData.size(), decOP.streamEndian); - if (size <0) { - qWarning("WriteBsBufFromBufHelper failed Error code is 0x%x", size); + + qDebug("bsfillSize: %d", d.bsfillSize); + //chunkIdx++; + if (!d.initSeq()) return false; - } - d.bsfillSize += size; + d.chunkReuseRequired = false; } - break; - } - -qDebug("bsfillSize: %d", d.bsfillSize); - //chunkIdx++; - if (!d.initSeq()) - return false; - d.chunkReuseRequired = false; - //FLUSH_BUFFER: if(!(d.int_reason & (1<(0); } VideoFrame VideoDecoderVPU::frame() { DPTR_D(VideoDecoderVPU); - // 0 on success if (d.display_queue.empty()) { qDebug("VPU has no frame decoded"); return VideoFrame(); } FBSurfacePtr surf(d.display_queue.front()); d.display_queue.pop_front(); - // FIXME: width()/height() 0 // TODO: timestamp is packet pts in OMX! - //qDebug("frame size: %dx%d %dx%d", width(), height(), d.codec_ctx->width, d.codec_ctx->height); VideoFrame frame(d.codec_ctx->width, d.codec_ctx->height, VideoFormat::Format_RGB32); //frame.setTimestamp(); vpu::SurfaceInteropGAL *interop = new vpu::SurfaceInteropGAL(d.interop_res); - interop->setSurface(surf, width(), height()); //width() valid? + interop->setSurface(surf, d.codec_ctx->width, d.codec_ctx->height); frame.setMetaData(QStringLiteral("surface_interop"), QVariant::fromValue(VideoSurfaceInteropPtr(interop))); return frame; } diff --git a/src/codec/video/viv/GALScaler.cpp b/src/codec/video/viv/GALScaler.cpp index bb9e0d1d..10b93817 100644 --- a/src/codec/video/viv/GALScaler.cpp +++ b/src/codec/video/viv/GALScaler.cpp @@ -167,7 +167,6 @@ bool GALScaler::convert(const quint8 * const src[], const int srcStride[]) GC_ENSURE(gco2D_EnableDither(egn2D, gcvFALSE), false) GC_ENSURE(gco2D_Flush(egn2D), false); GC_ENSURE(gcoHAL_Commit(d.test2D.runtime.hal, gcvTRUE), false); - return true; } diff --git a/src/codec/video/viv/GALScaler.h b/src/codec/video/viv/GALScaler.h index 04e6f86d..ec065a82 100644 --- a/src/codec/video/viv/GALScaler.h +++ b/src/codec/video/viv/GALScaler.h @@ -1,7 +1,6 @@ #include namespace QtAV { - class GALScalerPrivate; class GALScaler Q_DECL_FINAL : public ImageConverter {