[FFmpeg-cvslog] lavc: Add hwaccel private data and init/uninit callbacks

Anton Khirnov git at videolan.org
Mon May 12 00:29:38 CEST 2014


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Thu Mar  6 18:37:42 2014 +0100| [dd2d3b766b20196d0b65a82e3d897ccecbf7adb8] | committer: Luca Barbato

lavc: Add hwaccel private data and init/uninit callbacks

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dd2d3b766b20196d0b65a82e3d897ccecbf7adb8
---

 libavcodec/avcodec.h       |   23 +++++++++++++++++++++++
 libavcodec/internal.h      |    5 +++++
 libavcodec/pthread_frame.c |    1 +
 libavcodec/utils.c         |   34 ++++++++++++++++++++++++++++++----
 4 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 65c7da4..c76ee04 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2999,6 +2999,29 @@ typedef struct AVHWAccel {
      * AVCodecContext.release_buffer().
      */
     int frame_priv_data_size;
+
+    /**
+     * Initialize the hwaccel private data.
+     *
+     * This will be called from ff_get_format(), after hwaccel and
+     * hwaccel_context are set and the hwaccel private data in AVCodecInternal
+     * is allocated.
+     */
+    int (*init)(AVCodecContext *avctx);
+
+    /**
+     * Uninitialize the hwaccel private data.
+     *
+     * This will be called from get_format() or avcodec_close(), after hwaccel
+     * and hwaccel_context are already uninitialized.
+     */
+    int (*uninit)(AVCodecContext *avctx);
+
+    /**
+     * Size of the private data to allocate in
+     * AVCodecInternal.hwaccel_priv_data.
+     */
+    int priv_data_size;
 } AVHWAccel;
 
 /**
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 78af94e..6aaaf4c 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -95,6 +95,11 @@ typedef struct AVCodecInternal {
      * packet into every function.
      */
     AVPacket *pkt;
+
+    /**
+     * hwaccel-specific private data
+     */
+    void *hwaccel_priv_data;
 } AVCodecInternal;
 
 struct AVCodecDefault {
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index ca36be2..34ca9a6 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -206,6 +206,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
 
         dst->hwaccel = src->hwaccel;
         dst->hwaccel_context = src->hwaccel_context;
+        dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
     }
 
     if (for_user) {
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index c002c9c..d5c3070 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -893,16 +893,37 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
     if (!desc)
         return AV_PIX_FMT_NONE;
 
+    if (avctx->hwaccel && avctx->hwaccel->uninit)
+        avctx->hwaccel->uninit(avctx);
+    av_freep(&avctx->internal->hwaccel_priv_data);
+    avctx->hwaccel = NULL;
+
     if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
-        avctx->hwaccel = find_hwaccel(avctx->codec_id, ret);
-        if (!avctx->hwaccel) {
+        AVHWAccel *hwaccel;
+        int err;
+
+        hwaccel = find_hwaccel(avctx->codec_id, ret);
+        if (!hwaccel) {
             av_log(avctx, AV_LOG_ERROR,
                    "Could not find an AVHWAccel for the pixel format: %s",
                    desc->name);
             return AV_PIX_FMT_NONE;
         }
-    } else {
-        avctx->hwaccel = NULL;
+
+        if (hwaccel->priv_data_size) {
+            avctx->internal->hwaccel_priv_data = av_mallocz(hwaccel->priv_data_size);
+            if (!avctx->internal->hwaccel_priv_data)
+                return AV_PIX_FMT_NONE;
+        }
+
+        if (hwaccel->init) {
+            err = hwaccel->init(avctx);
+            if (err < 0) {
+                av_freep(&avctx->internal->hwaccel_priv_data);
+                return AV_PIX_FMT_NONE;
+            }
+        }
+        avctx->hwaccel = hwaccel;
     }
 
     return ret;
@@ -1688,6 +1709,11 @@ av_cold int avcodec_close(AVCodecContext *avctx)
         for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
             av_buffer_pool_uninit(&pool->pools[i]);
         av_freep(&avctx->internal->pool);
+
+        if (avctx->hwaccel && avctx->hwaccel->uninit)
+            avctx->hwaccel->uninit(avctx);
+        av_freep(&avctx->internal->hwaccel_priv_data);
+
         av_freep(&avctx->internal);
     }
 



More information about the ffmpeg-cvslog mailing list