[vlc-commits] avcodec: pass AVFrame.opaque to hwaccel release callback

Rémi Denis-Courmont git at videolan.org
Wed Jul 24 22:42:52 CEST 2013


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Jul 24 23:25:10 2013 +0300| [4f96c31975d02c5341d049d3d2b3cbd5ee8881eb] | committer: Rémi Denis-Courmont

avcodec: pass AVFrame.opaque to hwaccel release callback

With the reference counting stuff, the AVFrame structure is gone or
unreachable by the time the release function is called.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4f96c31975d02c5341d049d3d2b3cbd5ee8881eb
---

 modules/codec/avcodec/dxva2.c   |    4 ++--
 modules/codec/avcodec/hwdummy.c |    4 ++--
 modules/codec/avcodec/va.h      |    8 +++++---
 modules/codec/avcodec/vaapi.c   |    4 ++--
 modules/codec/avcodec/vda.c     |    5 ++++-
 modules/codec/avcodec/video.c   |   10 +++++-----
 modules/hw/vdpau/avcodec.c      |    4 ++--
 7 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 184af9e..d33b571 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -471,9 +471,9 @@ static int Get(vlc_va_t *external, AVFrame *ff)
     ff->opaque = surface;
     return VLC_SUCCESS;
 }
-static void Release(AVFrame *ff)
+static void Release(void *opaque)
 {
-    vlc_va_surface_t *surface = ff->opaque;
+    vlc_va_surface_t *surface = opaque;
 
     surface->refcount--;
 }
diff --git a/modules/codec/avcodec/hwdummy.c b/modules/codec/avcodec/hwdummy.c
index 95d95e5..ead7ccd 100644
--- a/modules/codec/avcodec/hwdummy.c
+++ b/modules/codec/avcodec/hwdummy.c
@@ -69,9 +69,9 @@ static int Lock(vlc_va_t *va, AVFrame *ff)
     return VLC_SUCCESS;
 }
 
-static void Unlock(AVFrame *ff)
+static void Unlock(void *opaque)
 {
-    assert((uintptr_t)ff->opaque == SURFACE_MAGIC);
+    assert((uintptr_t)opaque == SURFACE_MAGIC);
 }
 
 static VdpStatus Render(VdpDecoder decoder, VdpVideoSurface target,
diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
index d297114..128942c 100644
--- a/modules/codec/avcodec/va.h
+++ b/modules/codec/avcodec/va.h
@@ -38,7 +38,7 @@ struct vlc_va_t {
     int  (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output,
                   int width, int height);
     int  (*get)(vlc_va_t *, AVFrame *frame);
-    void (*release)(AVFrame *frame);
+    void (*release)(void *opaque);
     int  (*extract)(vlc_va_t *, picture_t *dst, AVFrame *src);
 };
 
@@ -86,15 +86,17 @@ static inline int vlc_va_Get(vlc_va_t *va, AVFrame *frame)
  * Releases a hardware surface from a libavcodec frame.
  * The surface has been previously allocated with vlc_va_Get().
  *
+ * @param opaque opaque data pointer of the AVFrame passed to vlc_va_Get().
+ *
  * @note This function needs not be reentrant. However it may be called
  * concurrently with vlc_va_Get() and/or vlc_va_Extract() from other threads
  * and other frames.
  *
  * @param frame libavcodec frame previously allocated by vlc_va_Get()
  */
-static inline void vlc_va_Release(vlc_va_t *va, AVFrame *frame)
+static inline void vlc_va_Release(vlc_va_t *va, void *opaque)
 {
-    va->release(frame);
+    va->release(opaque);
 }
 
 /**
diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 7068ce4..df3fc4a 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -518,9 +518,9 @@ static int Get( vlc_va_t *va, AVFrame *p_ff )
     return VLC_SUCCESS;
 }
 
-static void Release( AVFrame *p_ff )
+static void Release( void *opaque )
 {
-    vlc_va_surface_t *p_surface = p_ff->opaque;
+    vlc_va_surface_t *p_surface = opaque;
 
     vlc_mutex_lock( p_surface->p_lock );
     p_surface->i_refcount--;
diff --git a/modules/codec/avcodec/vda.c b/modules/codec/avcodec/vda.c
index 396ba87..e0f293b 100644
--- a/modules/codec/avcodec/vda.c
+++ b/modules/codec/avcodec/vda.c
@@ -254,12 +254,15 @@ static int Extract( vlc_va_t *external, picture_t *p_picture, AVFrame *p_ff )
     return VLC_SUCCESS;
 }
 
-static void Release( AVFrame *p_ff )
+static void Release( void *opaque )
 {
+    assert( opaque == NULL );
+#if 0
     CVPixelBufferRef cv_buffer = ( CVPixelBufferRef )p_ff->data[3];
 
     if ( cv_buffer )
         CVPixelBufferRelease( cv_buffer );
+#endif
 }
 
 static void Close( vlc_va_t *external )
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 967cb2e..d6a966f 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -897,14 +897,14 @@ static void ffmpeg_CopyPicture( decoder_t *p_dec,
 typedef struct
 {
     vlc_va_t *va;
-    AVFrame *frame;
+    void *opaque;
 } lavc_hw_ref_t;
 
 static void lavc_va_ReleaseFrame(void *opaque, uint8_t *data)
 {
     lavc_hw_ref_t *ref = opaque;
 
-    vlc_va_Release(ref->va, ref->frame);
+    vlc_va_Release(ref->va, ref->opaque);
     free(ref);
     (void) data;
 }
@@ -931,11 +931,11 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
     lavc_hw_ref_t *ref = malloc(sizeof (*ref));
     if (unlikely(ref == NULL))
     {
-        vlc_va_Release(va, frame);
+        vlc_va_Release(va, frame->opaque);
         return -1;
     }
     ref->va = va;
-    ref->frame = frame;
+    ref->opaque = frame->opaque;
 
     frame->buf[0] = av_buffer_create(frame->data[0], 0, lavc_va_ReleaseFrame,
                                      ref, 0);
@@ -1262,7 +1262,7 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
     decoder_sys_t *p_sys = p_dec->p_sys;
 
     if( p_sys->p_va )
-        vlc_va_Release( p_sys->p_va, p_ff_pic );
+        vlc_va_Release( p_sys->p_va, p_ff_pic->opaque );
     else if( p_ff_pic->opaque )
         decoder_UnlinkPicture( p_dec, (picture_t*)p_ff_pic->opaque);
     else if( p_ff_pic->type == FF_BUFFER_TYPE_INTERNAL )
diff --git a/modules/hw/vdpau/avcodec.c b/modules/hw/vdpau/avcodec.c
index 12af892..8c027d3 100644
--- a/modules/hw/vdpau/avcodec.c
+++ b/modules/hw/vdpau/avcodec.c
@@ -91,9 +91,9 @@ static int Lock(vlc_va_t *va, AVFrame *ff)
     return VLC_SUCCESS;
 }
 
-static void Unlock(AVFrame *ff)
+static void Unlock(void *opaque)
 {
-    vlc_vdp_video_field_t *field = ff->opaque;
+    vlc_vdp_video_field_t *field = opaque;
 
     assert(field != NULL);
     field->destroy(field);



More information about the vlc-commits mailing list