[FFmpeg-devel] [PATCH 3/3] libutvideo: Make CODEC_CAP_DR1 capable
Derek Buitenhuis
derek.buitenhuis at gmail.com
Mon Nov 7 05:51:49 CET 2011
Convert the libutvideo decoder wrapper to be
CODEC_CAP_DR1 cabpable. The slowdown should
not be too much at all.
Signed-off-by: Derek Buitenhuis <derek.buitenhuis at gmail.com>
---
libavcodec/libutvideo.cpp | 46 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/libavcodec/libutvideo.cpp b/libavcodec/libutvideo.cpp
index f27af7e..c68b6b6 100644
--- a/libavcodec/libutvideo.cpp
+++ b/libavcodec/libutvideo.cpp
@@ -146,6 +146,17 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
pic->pict_type = AV_PICTURE_TYPE_I;
pic->key_frame = 1;
+ /* Release any previous buffer */
+ if(pic->data[0])
+ avctx->release_buffer(avctx, pic);
+
+ /* Allocate buffer for frame */
+ if(avctx->get_buffer(avctx, pic) < 0)
+ {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+ return -1;
+ }
+
/* Decode the frame */
utv->codec->DecodeFrame(utv->output, avpkt->data, true);
@@ -153,21 +164,33 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
switch(avctx->pix_fmt)
{
case PIX_FMT_YUV420P:
+
pic->linesize[0] = w;
pic->linesize[1] = pic->linesize[2] = w / 2;
- pic->data[0] = utv->output;
- pic->data[2] = utv->output + (w * h);
- pic->data[1] = pic->data[2] + (w * h / 4);
+
+ memcpy(pic->data[0], utv->output, w * h);
+ memcpy(pic->data[2], utv->output + w * h, w * h / 4);
+ memcpy(pic->data[1], utv->output + (w * h * 5) / 4, w * h / 4);
+
break;
case PIX_FMT_YUYV422:
+
pic->linesize[0] = w * 2;
- pic->data[0] = utv->output;
+
+ memcpy(pic->data[0], utv->output, w * h * 2);
+
break;
case PIX_FMT_BGR24:
case PIX_FMT_RGB32:
- /* Make the linesize negative, since Ut Video uses bottom-up BGR */
- pic->linesize[0] = -1 * w * (avctx->pix_fmt == PIX_FMT_BGR24 ? 3 : 4);
- pic->data[0] = utv->output + utv->buf_size + pic->linesize[0];
+
+ /* Set the linesize depending on whether we have an alpha channel or not */
+ pic->linesize[0] = w * (avctx->pix_fmt == PIX_FMT_BGR24 ? 3 : 4);
+
+ /* Copy the lines in reverse since Ut Video returns bottom-up BGR/RGB */
+ for(int i = h - 1; i >= 0; i--)
+ memcpy(pic->data[0] + pic->linesize[0] * (h - 1 - i),
+ utv->output + pic->linesize[0] * i, pic->linesize[0]);
+
break;
}
@@ -180,9 +203,14 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
static av_cold int utvideo_decode_close(AVCodecContext *avctx)
{
UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+ AVFrame *pic = avctx->coded_frame;
+
+ /* Release buffer if there is one */
+ if(pic->data[0])
+ avctx->release_buffer(avctx, pic);
/* Free output */
- av_freep(&avctx->coded_frame);
+ av_freep(&pic);
av_freep(&utv->output);
/* Finish decoding and clean up the instance */
@@ -201,7 +229,7 @@ AVCodec ff_libutvideo_decoder = {
NULL,
utvideo_decode_close,
utvideo_decode_frame,
- NULL,
+ CODEC_CAP_DR1,
NULL,
NULL,
NULL,
--
1.7.7.1
More information about the ffmpeg-devel
mailing list