[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