[vlc-devel] [PATCH] vda: Add hwaccel1.2 support
Luca Barbato
lu_zero at gentoo.org
Thu May 8 15:31:40 CEST 2014
The global context setup are proper av_ namespaced functions,
the frames are properly refcounted and the output is fixed to
UYVY.
---
configure.ac | 8 +-
modules/codec/avcodec/vda.c | 179 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 155 insertions(+), 32 deletions(-)
diff --git a/configure.ac b/configure.ac
index 2f28385..fbb2a3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2401,7 +2401,13 @@ AS_IF([test "${enable_vda}" != "no"], [
AC_MSG_ERROR([--enable-vda and --disable-avcodec options are mutually exclusive.])
])
])
- fi
+ AS_IF([test "${have_avcodec_vda}" = "yes"], [
+ SAVE_LIBS=$LIBS
+ LIBS="$LIBS $AVCODEC_LIBS"
+ AC_CHECK_FUNCS([av_vda_alloc_context])
+ LIBS=$SAVE_LIBS
+ ])
+ fi
])
AM_CONDITIONAL([HAVE_AVCODEC_VDA], [test "${have_avcodec_vda}" = "yes"])
diff --git a/modules/codec/avcodec/vda.c b/modules/codec/avcodec/vda.c
index c8e0c5f..958cbef 100644
--- a/modules/codec/avcodec/vda.c
+++ b/modules/codec/avcodec/vda.c
@@ -51,6 +51,35 @@ static int Get( vlc_va_t *, void **, uint8_t ** );
static int Extract( vlc_va_t *, picture_t *, void *, uint8_t * );
static void Release( void *, uint8_t * );
+static void vda_Copy422YpCbCr8( picture_t *p_pic,
+ CVPixelBufferRef buffer )
+{
+ int i_dst_stride, i_src_stride;
+ uint8_t *p_dst, *p_src;
+
+ CVPixelBufferLockBaseAddress( buffer, 0 );
+
+ for( int i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
+ {
+ p_dst = p_pic->p[i_plane].p_pixels;
+ p_src = CVPixelBufferGetBaseAddressOfPlane( buffer, i_plane );
+ i_dst_stride = p_pic->p[i_plane].i_pitch;
+ i_src_stride = CVPixelBufferGetBytesPerRowOfPlane( buffer, i_plane );
+
+ for( int i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines ; i_line++ )
+ {
+ memcpy( p_dst, p_src, i_src_stride );
+
+ p_src += i_src_stride;
+ p_dst += i_dst_stride;
+ }
+ }
+
+ CVPixelBufferUnlockBaseAddress( buffer, 0 );
+}
+
+#ifndef HAVE_AV_VDA_ALLOC_CONTEXT
+
static const int nvda_pix_fmt_list[] = { 0, 1 };
static const char *const nvda_pix_fmt_list_text[] =
{ N_("420YpCbCr8Planar"), N_("422YpCbCr8") };
@@ -196,9 +225,9 @@ ok:
msg_Err( p_va->p_log, "Failed to create decoder: %i", status );
return VLC_EGENERIC;
}
- else
- msg_Dbg( p_va->p_log, "VDA decoder created");
-
+
+ msg_Dbg( p_va->p_log, "VDA decoder created");
+
return VLC_SUCCESS;
}
@@ -230,34 +259,6 @@ static void vda_Copy420YpCbCr8Planar( picture_t *p_pic,
CVPixelBufferUnlockBaseAddress( buffer, 0 );
}
-static void vda_Copy422YpCbCr8( picture_t *p_pic,
- CVPixelBufferRef buffer )
-{
- int i_dst_stride, i_src_stride;
- uint8_t *p_dst, *p_src;
-
- CVPixelBufferLockBaseAddress( buffer, 0 );
-
- for( int i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
- {
- p_dst = p_pic->p[i_plane].p_pixels;
- p_src = CVPixelBufferGetBaseAddressOfPlane( buffer, i_plane );
- i_dst_stride = p_pic->p[i_plane].i_pitch;
- i_src_stride = CVPixelBufferGetBytesPerRowOfPlane( buffer, i_plane );
-
- for( int i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines ; i_line++ )
- {
- memcpy( p_dst, p_src, i_src_stride );
-
- p_src += i_src_stride;
- p_dst += i_dst_stride;
- }
- }
-
- CVPixelBufferUnlockBaseAddress( buffer, 0 );
-}
-
-
static int Get( vlc_va_t *external, void **opaque, uint8_t **data )
{
VLC_UNUSED( external );
@@ -313,3 +314,119 @@ static void Release( void *opaque, uint8_t *data )
#endif
(void) opaque; (void) data;
}
+
+#else
+
+vlc_module_begin ()
+ set_description( N_("Video Decode Acceleration Framework (VDA)") )
+ set_capability( "hw decoder", 0 )
+ set_category( CAT_INPUT )
+ set_subcategory( SUBCAT_INPUT_VCODEC )
+ set_callbacks( Open, Close )
+vlc_module_end ()
+
+struct vlc_va_sys_t
+{
+ // to free the hwaccel
+ AVCodecContext *avctx;
+ vlc_object_t *p_log;
+};
+
+typedef struct vlc_va_sys_t vlc_va_vda_t;
+
+static vlc_va_vda_t *vlc_va_vda_Get( vlc_va_t *p_va )
+{
+ return p_va->sys;
+}
+
+static int Open( vlc_va_t *external, AVCodecContext *avctx,
+ const es_format_t *fmt )
+{
+ msg_Dbg( external, "VDA decoder Open");
+
+ vlc_va_vda_t *p_va = calloc( 1, sizeof(*p_va) );
+ if (!p_va) {
+ av_vda_default_free(avctx);
+ return VLC_EGENERIC;
+ }
+ p_va->p_log = VLC_OBJECT(external);
+ p_va->avctx = avctx;
+
+ external->sys = p_va;
+ external->description = (char *)"VDA";
+ external->pix_fmt = AV_PIX_FMT_VDA;
+ external->setup = Setup;
+ external->get = Get;
+ external->release = Release;
+ external->extract = Extract;
+ msg_Dbg( external, "VDA decoder Open success!");
+
+ (void) fmt;
+
+ return VLC_SUCCESS;
+}
+
+static void Close( vlc_va_t *external )
+{
+ vlc_va_vda_t *p_va = vlc_va_vda_Get( external );
+
+ av_vda_default_free(p_va->avctx);
+}
+
+static int Setup( vlc_va_t *external, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma,
+ int i_width, int i_height )
+{
+ vlc_va_vda_t *p_va = vlc_va_vda_Get( external );
+
+ *pi_chroma = VLC_CODEC_UYVY;
+
+ av_vda_default_free(p_va->avctx);
+
+ if( av_vda_default_init(p_va->avctx) < 0 )
+ return VLC_EGENERIC;
+
+ (void)i_width; (void)i_height;
+
+ return VLC_SUCCESS;
+}
+
+// Never called
+static int Get( vlc_va_t *external, void **opaque, uint8_t **data )
+{
+ VLC_UNUSED( external );
+
+ (void) data;
+ (void) opaque;
+ return VLC_SUCCESS;
+}
+
+static int Extract( vlc_va_t *external, picture_t *p_picture, void *opaque,
+ uint8_t *data )
+{
+ vlc_va_vda_t *p_va = vlc_va_vda_Get( external );
+
+ CVPixelBufferRef cv_buffer = (CVPixelBufferRef)data;
+
+ if( !cv_buffer )
+ {
+ msg_Dbg( p_va->p_log, "Frame buffer is empty.");
+ return VLC_EGENERIC;
+ }
+ if (!CVPixelBufferGetDataSize(cv_buffer) > 0)
+ {
+ msg_Dbg( p_va->p_log, "Empty frame buffer");
+ return VLC_EGENERIC;
+ }
+
+ vda_Copy422YpCbCr8( p_picture, cv_buffer );
+
+ (void) opaque;
+ return VLC_SUCCESS;
+}
+
+static void Release( void *opaque, uint8_t *data )
+{
+ (void) opaque; (void) data;
+}
+
+#endif
--
1.9.0
More information about the vlc-devel
mailing list