Commit e7eb250a authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

avcodec: move hardware decoding into dedicated plugins (fixes #7220)

parent 93fd69f4
......@@ -94,7 +94,6 @@ libavcodec_plugin_la_SOURCES = \
avcodec/deinterlace.c \
avcodec/fourcc.c \
avcodec/chroma.c avcodec/chroma.h \
avcodec/copy.c avcodec/copy.h \
avcodec/va.h \
avcodec/avcodec.c avcodec/avcodec.h
if ENABLE_SOUT
......@@ -104,21 +103,7 @@ endif
libavcodec_plugin_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS_avcodec)
libavcodec_plugin_la_LIBADD = $(AM_LIBADD) $(LIBS_avcodec)
libavcodec_plugin_la_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_avcodec)
if HAVE_AVCODEC_VAAPI
libavcodec_plugin_la_SOURCES += avcodec/vaapi.c
libavcodec_plugin_la_CFLAGS += $(LIBVA_CFLAGS) $(X_CFLAGS) -DHAVE_AVCODEC_VAAPI
libavcodec_plugin_la_LIBADD += $(LIBVA_LIBS) $(X_LIBS) $(X_PRE_LIBS) -lX11
endif
if HAVE_AVCODEC_DXVA2
libavcodec_plugin_la_SOURCES += avcodec/dxva2.c
libavcodec_plugin_la_CFLAGS += -DHAVE_AVCODEC_DXVA2
libavcodec_plugin_la_LIBADD += -lole32 -lshlwapi -luuid
endif
if HAVE_AVCODEC_VDA
libavcodec_plugin_la_SOURCES += avcodec/vda.c
libavcodec_plugin_la_CFLAGS += -DHAVE_AVCODEC_VDA
libavcodec_plugin_la_LDFLAGS += -Wl,-framework,CoreFoundation,-framework,VideoDecodeAcceleration,-framework,QuartzCore
endif
if MERGE_FFMPEG
libavcodec_plugin_la_SOURCES += \
../demux/avformat/demux.c \
......@@ -135,6 +120,34 @@ libvlc_LTLIBRARIES += \
EXTRA_LTLIBRARIES += \
libavcodec_plugin.la
### avcodec hardware acceleration ###
libvaapi_plugin_la_SOURCES = \
avcodec/copy.c avcodec/copy.h \
avcodec/vaapi.c
libvaapi_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) $(X_CFLAGS)
libvaapi_plugin_la_LIBADD = $(AM_LIBADD) $(LIBVA_LIBS) \
$(X_LIBS) $(X_PRE_LIBS) -lX11
if HAVE_AVCODEC_VAAPI
libvlc_LTLIBRARIES += libvaapi_plugin.la
endif
libdxva2_plugin_la_SOURCES = \
avcodec/copy.c avcodec/copy.h \
avcodec/dxva2.c
libdxva2_plugin_la_LIBADD = $(AM_LIBADD) -lole32 -lshlwapi -luuid
if HAVE_AVCODEC_DXVA2
libvlc_LTLIBRARIES += libdxva2_plugin.la
endif
libvda_plugin_la_SOURCES = \
avcodec/copy.c avcodec/copy.h \
avcodec/vda.c
libvda_plugin_la_LDFLAGS = -Wl,-framework,CoreFoundation,-framework,VideoDecodeAcceleration,-framework,QuartzCore
if HAVE_AVCODEC_VDA
libvlc_LTLIBRARIES += libvda_plugin.la
endif
### OpenMAX ###
noinst_HEADERS += \
omxil/OMX_Component.h \
......
......@@ -65,12 +65,6 @@ static const int nloopf_list[] = { 0, 1, 2, 3, 4 };
static const char *const nloopf_list_text[] =
{ N_("None"), N_("Non-ref"), N_("Bidir"), N_("Non-key"), N_("All") };
#if defined(HAVE_AVCODEC_VDA)
static const int nvda_pix_fmt_list[] = { 0, 1 };
static const char *const nvda_pix_fmt_list_text[] =
{ N_("420YpCbCr8Planar"), N_("422YpCbCr8") };
#endif
#ifdef ENABLE_SOUT
static const char *const enc_hq_list[] = { "rd", "bits", "simple" };
static const char *const enc_hq_list_text[] = {
......@@ -141,22 +135,8 @@ vlc_module_begin ()
true )
add_obsolete_string( "ffmpeg-codec" ) /* removed since 2.1.0 */
add_string( "avcodec-codec", NULL, CODEC_TEXT, CODEC_LONGTEXT, true )
#if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2) || defined(HAVE_AVCODEC_VDA)
add_obsolete_bool( "ffmpeg-hw" ) /* removed since 2.1.0 */
add_bool( "avcodec-hw",
#if !defined(HAVE_AVCODEC_VDA)
false
#else
true
#endif
, HW_TEXT, HW_LONGTEXT, false )
#if defined(HAVE_AVCODEC_VDA)
add_integer ( "avcodec-vda-pix-fmt", 0, VDA_PIX_FMT_TEXT,
VDA_PIX_FMT_LONGTEXT, false)
change_safe ()
change_integer_list( nvda_pix_fmt_list, nvda_pix_fmt_list_text )
#endif
#endif
add_module( "avcodec-hw", "hw decoder", "none", HW_TEXT, HW_LONGTEXT, false )
#if defined(FF_THREAD_FRAME)
add_obsolete_integer( "ffmpeg-threads" ) /* removed since 2.1.0 */
add_integer( "avcodec-threads", 1, THREADS_TEXT, THREADS_LONGTEXT, true );
......
......@@ -34,11 +34,13 @@
# define _WIN32_WINNT 0x600
# endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_picture.h>
#include <vlc_fourcc.h>
#include <vlc_cpu.h>
#include <assert.h>
#include <vlc_plugin.h>
#include <libavcodec/avcodec.h>
# define DXVA2API_USE_BITFIELDS
......@@ -49,6 +51,17 @@
#include "va.h"
#include "copy.h"
static int Open(vlc_va_t *, int, int, const es_format_t *);
static void Close(vlc_va_t *);
vlc_module_begin()
set_description(N_("DirectX Video Acceleration (DXVA) 2.0"))
set_capability("hw decoder", 50)
set_category(CAT_INPUT)
set_subcategory(SUBCAT_INPUT_VCODEC)
set_callbacks(Open, Close)
vlc_module_end()
#include <windows.h>
#include <windowsx.h>
#include <ole2.h>
......@@ -488,8 +501,8 @@ static void Close(vlc_va_t *external)
free(va);
}
int vlc_va_New(vlc_va_t *log, int pixfmt, int codec_id,
const es_format_t *fmt)
static int Open(vlc_va_t *log, int pixfmt, int codec_id,
const es_format_t *fmt)
{
if( pixfmt != PIX_FMT_DXVA2_VLD )
return NULL;
......
......@@ -31,6 +31,7 @@ struct vlc_va_t {
VLC_COMMON_MEMBERS
vlc_va_sys_t *sys;
module_t *module;
char *description;
int (*setup)(vlc_va_t *, void **hw, vlc_fourcc_t *output,
......@@ -38,7 +39,6 @@ struct vlc_va_t {
int (*get)(vlc_va_t *, AVFrame *frame);
void (*release)(vlc_va_t *, AVFrame *frame);
int (*extract)(vlc_va_t *, picture_t *dst, AVFrame *src);
void (*close)(vlc_va_t *);
};
static inline int vlc_va_Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *output,
......@@ -58,12 +58,8 @@ static inline int vlc_va_Extract(vlc_va_t *va, picture_t *dst, AVFrame *src)
{
return va->extract(va, dst, src);
}
static inline void vlc_va_Delete(vlc_va_t *va)
{
va->close(va);
vlc_object_release(va);
}
int vlc_va_New(vlc_va_t *, int pix, int codec, const es_format_t *);
static vlc_va_t *vlc_va_New(vlc_object_t *, int, int, const es_format_t *);
static void vlc_va_Delete(vlc_va_t *va);
#endif
......@@ -25,22 +25,32 @@
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_fourcc.h>
#include <assert.h>
#include <vlc_xlib.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/vaapi.h>
#include <X11/Xlib.h>
#include <va/va_x11.h>
#include "avcodec.h"
#include "va.h"
#include "copy.h"
#include <vlc_xlib.h>
static int Create( vlc_va_t *, int, int, const es_format_t * );
static void Delete( vlc_va_t * );
#include <libavcodec/vaapi.h>
#include <X11/Xlib.h>
#include <va/va_x11.h>
vlc_module_begin ()
set_description( N_("Video Acceleration (VA) API") )
set_capability( "hw decoder", 50 )
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_VCODEC )
set_callbacks( Create, Delete )
vlc_module_end ()
typedef struct
{
......@@ -490,6 +500,7 @@ static void Close( vlc_va_sys_t *p_va )
if( p_va->p_display_x11 )
XCloseDisplay( p_va->p_display_x11 );
}
static void Delete( vlc_va_t *p_external )
{
vlc_va_sys_t *p_va = p_external->sys;
......@@ -498,8 +509,7 @@ static void Delete( vlc_va_t *p_external )
free( p_va );
}
/* */
int vlc_va_New( vlc_va_t *p_va, int pixfmt, int i_codec_id,
static int Create( vlc_va_t *p_va, int pixfmt, int i_codec_id,
const es_format_t *fmt )
{
/* Only VLD supported */
......@@ -523,6 +533,5 @@ int vlc_va_New( vlc_va_t *p_va, int pixfmt, int i_codec_id,
p_va->get = Get;
p_va->release = Release;
p_va->extract = Extract;
p_va->close = Delete;
return VLC_SUCCESS;
}
......@@ -24,9 +24,11 @@
# include "config.h"
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_vout.h>
#include <assert.h>
#include <vlc_plugin.h>
#include <libavcodec/avcodec.h>
......@@ -37,6 +39,24 @@
#include <libavcodec/vda.h>
#include <VideoDecodeAcceleration/VDADecoder.h>
static int Open( vlc_va_t *, int, int, const es_format_t * );
static void Close( vlc_va_t * );
static const int nvda_pix_fmt_list[] = { 0, 1 };
static const char *const nvda_pix_fmt_list_text[] =
{ N_("420YpCbCr8Planar"), N_("422YpCbCr8") };
vlc_module_begin ()
set_description( N_("Video Decode Acceleration Framework (VDA)") )
set_capability( "hw decoder", 50 )
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_VCODEC )
set_callbacks( Open, Close )
add_integer ( "avcodec-vda-pix-fmt", 0, VDA_PIX_FMT_TEXT,
VDA_PIX_FMT_LONGTEXT, false)
change_integer_list( nvda_pix_fmt_list, nvda_pix_fmt_list_text )
vlc_module_end ()
struct vlc_va_sys_t
{
struct vda_context hw_ctx;
......@@ -241,15 +261,15 @@ static void Close( vlc_va_t *p_external )
free( p_va );
}
int vlc_va_New( vlc_va_t *external, int pixfmt, int i_codec_id,
const es_format_t *fmt )
static int Open( vlc_va_t *external, int pixfmt, int i_codec_id,
const es_format_t *fmt )
{
if( pixfmt != PIX_FMT_VDA_VLD || i_codec_id != CODEC_ID_H264 )
return NULL;
if( fmt->p_extra == NULL || fmt->i_extra < 7 )
{
msg_Warn( p_log, "VDA requires extradata." );
msg_Warn( external, "VDA requires extradata." );
return NULL;
}
......@@ -267,7 +287,6 @@ int vlc_va_New( vlc_va_t *external, int pixfmt, int i_codec_id,
external->get = Get;
external->release = Release;
external->extract = Extract;
external->close = Close;
return VLC_SUCCESS;
}
......@@ -33,17 +33,15 @@
#include <vlc_codec.h>
#include <vlc_avcodec.h>
#include <vlc_cpu.h>
#include <vlc_modules.h>
#include <assert.h>
#include <libavcodec/avcodec.h>
#include <libavutil/mem.h>
#include <libavutil/pixdesc.h>
#include "avcodec.h"
#include "va.h"
#if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2) || defined(HAVE_AVCODEC_VDA)
# define HAVE_AVCODEC_VA
# include <libavutil/pixdesc.h>
#endif
/*****************************************************************************
* decoder_sys_t : decoder descriptor
......@@ -108,11 +106,8 @@ static void ffmpeg_CopyPicture ( decoder_t *, picture_t *, AVFrame * );
static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * );
static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *, AVFrame * );
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
#ifdef HAVE_AVCODEC_VA
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
const enum PixelFormat * );
#endif
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{
......@@ -345,9 +340,8 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
p_sys->p_context->thread_count = i_thread_count;
#endif
#ifdef HAVE_AVCODEC_VA
const bool b_use_hw = var_CreateGetBool( p_dec, "avcodec-hw" );
if( b_use_hw &&
char *hw = var_CreateGetString( p_dec, "avcodec-hw" ); /* FIXME */
if( (hw == NULL || strcasecmp( hw, "none" )) &&
(i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ||
i_codec_id == CODEC_ID_MPEG4 ||
i_codec_id == CODEC_ID_H264 ||
......@@ -368,7 +362,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
#endif
p_sys->p_context->get_format = ffmpeg_GetFormat;
}
#endif
free( hw );
#ifdef HAVE_AVCODEC_MT
if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count;
......@@ -963,7 +957,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
if( p_sys->p_va )
{
#ifdef HAVE_AVCODEC_VA
#if 1 // LIBAVCODEC_VERSION_MAJOR >= ? FIXME
/* hwaccel_context is not present in old ffmpeg version */
if( vlc_va_Setup( p_sys->p_va,
&p_context->hwaccel_context, &p_dec->fmt_out.video.i_chroma,
......@@ -1124,7 +1118,49 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
p_ff_pic->data[i] = NULL;
}
#ifdef HAVE_AVCODEC_VA
static int ffmpeg_va_Start( void *func, va_list ap )
{
vlc_va_t *va = va_arg( ap, vlc_va_t * );
int pix = va_arg( ap, int );
int codec = va_arg( ap, int );
const es_format_t *fmt = va_arg( ap, const es_format_t * );
int (*open)( vlc_va_t *, int, int, const es_format_t * ) = func;
return open( va, pix, codec, fmt );
}
static vlc_va_t *vlc_va_New( vlc_object_t *parent, int pixfmt, int codec_id,
const es_format_t *fmt )
{
vlc_va_t *p_va = vlc_object_create( parent, sizeof( *p_va ) );
if( unlikely(p_va == NULL) )
return NULL;
p_va->module = vlc_module_load( p_va, "hw decoder", "$avcodec-hw",
true, ffmpeg_va_Start, p_va, pixfmt,
codec_id, fmt );
if( p_va->module == NULL )
{
vlc_object_release( p_va );
p_va = NULL;
}
return p_va;
}
static void ffmpeg_va_Stop( void *func, va_list ap )
{
vlc_va_t *va = va_arg( ap, vlc_va_t * );
void (*close)( vlc_va_t * ) = func;
close( va );
}
static void vlc_va_Delete( vlc_va_t *va )
{
vlc_module_unload( va->module, ffmpeg_va_Stop, va );
vlc_object_release( va );
}
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
const enum PixelFormat *pi_fmt )
{
......@@ -1144,12 +1180,10 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
msg_Dbg( p_dec, "Available decoder output format %d (%s)", pi_fmt[i],
name ? name : "unknown" );
vlc_va_t *p_va = vlc_object_create( p_dec, sizeof( *p_va ) );
if( unlikely(p_va == NULL) )
continue;
if( vlc_va_New( p_va, pi_fmt[i], p_sys->i_codec_id, &p_dec->fmt_in ) )
vlc_va_t *p_va = vlc_va_New( VLC_OBJECT(p_dec), pi_fmt[i],
p_sys->i_codec_id, &p_dec->fmt_in );
if( p_va == NULL )
{
vlc_object_release( p_va );
msg_Dbg( p_dec, "acceleration not available" );
continue;
}
......@@ -1183,5 +1217,3 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
/* Fallback to default behaviour */
return avcodec_default_get_format( p_context, pi_fmt );
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment