[vlc-commits] avcodec: rationalize hwaccel surface allocation callback
Rémi Denis-Courmont
git at videolan.org
Thu Jul 25 18:05:57 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Jul 25 18:57:18 2013 +0300| [eae355f6ca1942def16d4b6b4a36c0b7cecc1e2f] | committer: Rémi Denis-Courmont
avcodec: rationalize hwaccel surface allocation callback
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=eae355f6ca1942def16d4b6b4a36c0b7cecc1e2f
---
modules/codec/avcodec/dxva2.c | 15 ++++-----------
modules/codec/avcodec/hwdummy.c | 14 ++++----------
modules/codec/avcodec/va.h | 9 ++++++---
modules/codec/avcodec/vaapi.c | 15 +++------------
modules/codec/avcodec/vda.c | 17 ++++-------------
modules/codec/avcodec/video.c | 9 ++++++---
modules/hw/vdpau/avcodec.c | 13 +++----------
7 files changed, 30 insertions(+), 62 deletions(-)
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 5d8cd19..82fb5d1 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -425,8 +425,9 @@ static int Extract(vlc_va_t *external, picture_t *picture, AVFrame *ff)
IDirect3DSurface9_UnlockRect(d3d);
return VLC_SUCCESS;
}
+
/* FIXME it is nearly common with VAAPI */
-static int Get(vlc_va_t *external, AVFrame *ff)
+static int Get(vlc_va_t *external, void **opaque, uint8_t **data)
{
vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
@@ -459,16 +460,8 @@ static int Get(vlc_va_t *external, AVFrame *ff)
surface->refcount = 1;
surface->order = va->surface_order++;
-
- /* */
- for (int i = 0; i < 4; i++) {
- ff->data[i] = NULL;
- ff->linesize[i] = 0;
-
- if (i == 0 || i == 3)
- ff->data[i] = (void*)surface->d3d;/* Yummie */
- }
- ff->opaque = surface;
+ *data = (void *)surface->d3d;
+ *opaque = surface;
return VLC_SUCCESS;
}
diff --git a/modules/codec/avcodec/hwdummy.c b/modules/codec/avcodec/hwdummy.c
index 83b56e0..b89ef16 100644
--- a/modules/codec/avcodec/hwdummy.c
+++ b/modules/codec/avcodec/hwdummy.c
@@ -56,17 +56,11 @@ struct vlc_va_sys_t
AVVDPAUContext context;
};
-static int Lock(vlc_va_t *va, AVFrame *ff)
+static int Lock(vlc_va_t *va, void **opaque, uint8_t **data)
{
- for (unsigned i = 0; i < AV_NUM_DATA_POINTERS; i++)
- {
- ff->data[i] = NULL;
- ff->linesize[i] = 0;
- }
-
- ff->data[0] = (void *)(uintptr_t)DATA_MAGIC; /* must be non-NULL */
- ff->data[3] = (void *)(uintptr_t)DATA_MAGIC;
- ff->opaque = (void *)(uintptr_t)OPAQUE_MAGIC;
+ *data = (void *)(uintptr_t)DATA_MAGIC;
+ *opaque = (void *)(uintptr_t)OPAQUE_MAGIC;
+ (void) va;
return VLC_SUCCESS;
}
diff --git a/modules/codec/avcodec/va.h b/modules/codec/avcodec/va.h
index ddbf9ce..71cad95 100644
--- a/modules/codec/avcodec/va.h
+++ b/modules/codec/avcodec/va.h
@@ -37,7 +37,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);
+ int (*get)(vlc_va_t *, void **opaque, uint8_t **data);
void (*release)(void *opaque, uint8_t *surface);
int (*extract)(vlc_va_t *, picture_t *dst, AVFrame *src);
};
@@ -70,6 +70,9 @@ static inline int vlc_va_Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *output,
* The surface will be used as output for the hardware decoder, and possibly
* also as a reference frame to decode other surfaces.
*
+ * @param opaque pointer to storage space for surface internal data [OUT]
+ * @param data pointer to the AVFrame data[0] and data[3] pointers [OUT]
+ *
* @note This function needs not be reentrant. However it may be called
* concurrently with vlc_va_Extract() and/or vlc_va_Release() from other
* threads and other frames.
@@ -77,9 +80,9 @@ static inline int vlc_va_Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *output,
* @param frame libavcodec frame [IN/OUT]
* @return VLC_SUCCESS on success, otherwise an error code.
*/
-static inline int vlc_va_Get(vlc_va_t *va, AVFrame *frame)
+static inline int vlc_va_Get(vlc_va_t *va, void **opaque, uint8_t **data)
{
- return va->get(va, frame);
+ return va->get(va, opaque, data);
}
/**
diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 7b40c3e..2f9fedc 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -477,7 +477,7 @@ static int Extract( vlc_va_t *va, picture_t *p_picture, AVFrame *p_ff )
return VLC_SUCCESS;
}
-static int Get( vlc_va_t *va, AVFrame *p_ff )
+static int Get( vlc_va_t *va, void **opaque, uint8_t **data )
{
vlc_va_sys_t *sys = va->sys;
int i_old;
@@ -504,17 +504,8 @@ static int Get( vlc_va_t *va, AVFrame *p_ff )
p_surface->i_refcount = 1;
p_surface->i_order = sys->i_surface_order++;
-
- /* */
- for( int i = 0; i < 4; i++ )
- {
- p_ff->data[i] = NULL;
- p_ff->linesize[i] = 0;
-
- if( i == 0 || i == 3 )
- p_ff->data[i] = (void*)(uintptr_t)p_surface->i_id;/* Yummie */
- }
- p_ff->opaque = p_surface;
+ *data = (void *)(uintptr_t)p_surface->i_id;
+ *opaque = p_surface;
return VLC_SUCCESS;
}
diff --git a/modules/codec/avcodec/vda.c b/modules/codec/avcodec/vda.c
index 695d08c..fd298eb 100644
--- a/modules/codec/avcodec/vda.c
+++ b/modules/codec/avcodec/vda.c
@@ -203,20 +203,12 @@ ok:
return VLC_SUCCESS;
}
-static int Get( vlc_va_t *external, AVFrame *p_ff )
+static int Get( vlc_va_t *external, void **opaque, uint8_t **data )
{
VLC_UNUSED( external );
- /* */
- for( int i = 0; i < 4; i++ )
- {
- p_ff->data[i] = NULL;
- p_ff->linesize[i] = 0;
-
- if( i == 0 || i == 3 )
- p_ff->data[i] = (uint8_t *)1; // dummy
- }
-
+ *data = (uint8_t *)1; // dummy
+ (void) opaque;
return VLC_SUCCESS;
}
@@ -257,14 +249,13 @@ static int Extract( vlc_va_t *external, picture_t *p_picture, AVFrame *p_ff )
static void Release( void *opaque, uint8_t *data )
{
- assert( opaque == NULL );
#if 0
CVPixelBufferRef cv_buffer = ( CVPixelBufferRef )p_ff->data[3];
if ( cv_buffer )
CVPixelBufferRelease( cv_buffer );
#endif
- (void) data;
+ (void) opaque; (void) data;
}
static void Close( vlc_va_t *external )
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index b25a8d4..9a9e196 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -907,11 +907,14 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
msg_Err(dec, "hardware acceleration setup failed");
return -1;
}
- if (vlc_va_Get(va, frame))
+ if (vlc_va_Get(va, &frame->opaque, &frame->data[0]))
{
msg_Err(dec, "hardware acceleration picture allocation failed");
return -1;
}
+ /* data[0] must be non-NULL for libavcodec internal checks.
+ * data[3] actually contains the format-specific surface handle. */
+ frame->data[3] = frame->data[0];
frame->buf[0] = av_buffer_create(frame->data[0], 0, va->release,
frame->opaque, 0);
@@ -921,7 +924,6 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame,
return -1;
}
assert(frame->data[0] != NULL);
- assert(frame->data[3] != NULL);
(void) flags;
return 0;
}
@@ -1097,12 +1099,13 @@ static int ffmpeg_va_GetFrameBuf( struct AVCodecContext *p_context, AVFrame *p_f
return -1;
}
- if( vlc_va_Get( p_va, p_ff_pic ) )
+ if( vlc_va_Get( p_va, &p_ff_pic->opaque, &p_ff_pic->data[0] ) )
{
msg_Err( p_dec, "vlc_va_Get failed" );
return -1;
}
+ p_ff_pic->data[3] = p_ff_pic->data[0];
p_ff_pic->type = FF_BUFFER_TYPE_USER;
return 0;
}
diff --git a/modules/hw/vdpau/avcodec.c b/modules/hw/vdpau/avcodec.c
index 07028b6..7da4e76 100644
--- a/modules/hw/vdpau/avcodec.c
+++ b/modules/hw/vdpau/avcodec.c
@@ -60,18 +60,12 @@ struct vlc_va_sys_t
uint16_t height;
};
-static int Lock(vlc_va_t *va, AVFrame *ff)
+static int Lock(vlc_va_t *va, void **opaque, uint8_t **data)
{
vlc_va_sys_t *sys = va->sys;
VdpVideoSurface surface;
VdpStatus err;
- for (unsigned i = 0; i < AV_NUM_DATA_POINTERS; i++)
- {
- ff->data[i] = NULL;
- ff->linesize[i] = 0;
- }
-
err = vdp_video_surface_create(sys->vdp, sys->device, VDP_CHROMA_TYPE_420,
sys->width, sys->height, &surface);
if (err != VDP_STATUS_OK)
@@ -85,9 +79,8 @@ static int Lock(vlc_va_t *va, AVFrame *ff)
if (unlikely(field == NULL))
return VLC_ENOMEM;
- ff->data[0] = (void *)sys->vdp; /* must be non-NULL */
- ff->data[3] = (void *)(uintptr_t)surface;
- ff->opaque = field;
+ *data = (void *)(uintptr_t)surface;
+ *opaque = field;
return VLC_SUCCESS;
}
More information about the vlc-commits
mailing list