/*****************************************************************************
- * video.c: video decoder using the ffmpeg library
+ * video.c: video decoder using the libavcodec library
*****************************************************************************
* Copyright (C) 1999-2001 the VideoLAN team
* $Id$
# include "config.h"
#endif
+#if defined(HAVE_LIBAVCODEC_AVCODEC_H) && defined(HAVE_AVCODEC_DXVA2)
+# if _WIN32_WINNT < 0x600
+/* dxva2 needs Vista support */
+# undef _WIN32_WINNT
+# define _WIN32_WINNT 0x600
+# endif
+#endif
+
#include <vlc_common.h>
#include <vlc_codec.h>
#include <vlc_avcodec.h>
#include <vlc_cpu.h>
#include <assert.h>
-/* ffmpeg header */
-#ifdef HAVE_LIBAVCODEC_AVCODEC_H
-# include <libavcodec/avcodec.h>
-# ifdef HAVE_AVCODEC_VAAPI
-# include <libavcodec/vaapi.h>
-# endif
-# ifdef HAVE_AVCODEC_DXVA2
-# include <libavcodec/dxva2.h>
-# endif
-#elif defined(HAVE_FFMPEG_AVCODEC_H)
-# include <ffmpeg/avcodec.h>
-#else
-# include <avcodec.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/mem.h>
+#ifdef HAVE_AVCODEC_VAAPI
+# include <libavcodec/vaapi.h>
+#endif
+#ifdef HAVE_AVCODEC_DXVA2
+# include <libavcodec/dxva2.h>
+#endif
+#ifdef HAVE_AVCODEC_VDA
+# include <libavcodec/vda.h>
#endif
#include "avcodec.h"
#include "va.h"
-#if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2)
+#if defined(HAVE_AVCODEC_VAAPI) || defined(HAVE_AVCODEC_DXVA2) || defined(HAVE_AVCODEC_VDA)
# define HAVE_AVCODEC_VA
#endif
/* Hack to force display of still pictures */
bool b_first_frame;
+
/* */
+#if LIBAVCODEC_VERSION_MAJOR < 54
AVPaletteControl palette;
+#else
+# warning FIXME
+#endif
/* */
bool b_flush;
# define post_mt(s)
#endif
-/* FIXME (dummy palette for now) */
-static const AVPaletteControl palette_control;
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/* ***** Get configuration of ffmpeg plugin ***** */
p_sys->p_context->workaround_bugs =
- var_InheritInteger( p_dec, "ffmpeg-workaround-bugs" );
+ var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
+#if LIBAVCODEC_VERSION_MAJOR < 54
p_sys->p_context->error_recognition =
- var_InheritInteger( p_dec, "ffmpeg-error-resilience" );
+#else
+ p_sys->p_context->err_recognition =
+#endif
+ var_InheritInteger( p_dec, "avcodec-error-resilience" );
if( var_CreateGetBool( p_dec, "grayscale" ) )
p_sys->p_context->flags |= CODEC_FLAG_GRAY;
- i_val = var_CreateGetInteger( p_dec, "ffmpeg-vismv" );
+ i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
if( i_val ) p_sys->p_context->debug_mv = i_val;
- i_val = var_CreateGetInteger( p_dec, "ffmpeg-lowres" );
+ i_val = var_CreateGetInteger( p_dec, "avcodec-lowres" );
if( i_val > 0 && i_val <= 2 ) p_sys->p_context->lowres = i_val;
- i_val = var_CreateGetInteger( p_dec, "ffmpeg-skiploopfilter" );
+ i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL;
else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY;
else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR;
else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF;
- if( var_CreateGetBool( p_dec, "ffmpeg-fast" ) )
+ if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;
- /* ***** ffmpeg frame skipping ***** */
- p_sys->b_hurry_up = var_CreateGetBool( p_dec, "ffmpeg-hurry-up" );
+ /* ***** libavcodec frame skipping ***** */
+ p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );
- switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-frame" ) )
+ switch( var_CreateGetInteger( p_dec, "avcodec-skip-frame" ) )
{
case -1:
p_sys->p_context->skip_frame = AVDISCARD_NONE;
}
p_sys->i_skip_frame = p_sys->p_context->skip_frame;
- switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-idct" ) )
+ switch( var_CreateGetInteger( p_dec, "avcodec-skip-idct" ) )
{
case -1:
p_sys->p_context->skip_idct = AVDISCARD_NONE;
}
p_sys->i_skip_idct = p_sys->p_context->skip_idct;
- /* ***** ffmpeg direct rendering ***** */
+ /* ***** libavcodec direct rendering ***** */
p_sys->b_direct_rendering = false;
p_sys->i_direct_rendering_used = -1;
- if( var_CreateGetBool( p_dec, "ffmpeg-dr" ) &&
+ if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
(p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
/* No idea why ... but this fixes flickering on some TSCC streams */
- p_sys->i_codec_id != CODEC_ID_TSCC &&
+ p_sys->i_codec_id != CODEC_ID_TSCC && p_sys->i_codec_id != CODEC_ID_CSCD &&
+ p_sys->i_codec_id != CODEC_ID_CINEPAK &&
#if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 68, 2 ) ) && (LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 100, 1 ) )
/* avcodec native vp8 decode doesn't handle EMU_EDGE flag, and I
don't have idea howto implement fallback to libvpx decoder */
p_sys->b_direct_rendering = true;
}
- /* ffmpeg doesn't properly release old pictures when frames are skipped */
+ /* libavcodec doesn't properly release old pictures when frames are skipped */
//if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
if( p_sys->b_direct_rendering )
{
p_sys->p_context->opaque = p_dec;
#ifdef HAVE_AVCODEC_MT
- int i_thread_count = var_InheritInteger( p_dec, "ffmpeg-threads" );
+ int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
if( i_thread_count <= 0 )
+ {
i_thread_count = vlc_GetCPUCount();
+ if( i_thread_count > 1 )
+ i_thread_count++;
+
+ //FIXME: take in count the decoding time
+ i_thread_count = __MIN( i_thread_count, 4 );
+ }
+ i_thread_count = __MIN( i_thread_count, 16 );
msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
p_sys->p_context->thread_count = i_thread_count;
#endif
#ifdef HAVE_AVCODEC_VA
- const bool b_use_hw = var_CreateGetBool( p_dec, "ffmpeg-hw" );
+ const bool b_use_hw = var_CreateGetBool( p_dec, "avcodec-hw" );
if( b_use_hw &&
(i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ||
i_codec_id == CODEC_ID_MPEG4 ||
#ifdef HAVE_AVCODEC_MT
if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
{
- msg_Warn( p_dec, "threaded frame decoding is not compatible with ffmpeg-hw, disabled" );
+ msg_Warn( p_dec, "threaded frame decoding is not compatible with libavcodec-hw, disabled" );
p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
}
+ if( ( p_sys->p_context->thread_type & FF_THREAD_SLICE ) &&
+ ( i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ) )
+ {
+ msg_Warn( p_dec, "threaded slice decoding is not compatible with libavcodec-hw, disabled" );
+ p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
+ }
#endif
p_sys->p_context->get_format = ffmpeg_GetFormat;
}
#endif
+#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;
+#endif
+
/* ***** misc init ***** */
p_sys->i_pts = VLC_TS_INVALID;
}
p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
+#if LIBAVCODEC_VERSION_MAJOR < 54
/* Setup palette */
memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
if( p_dec->fmt_in.video.p_palette )
{
p_sys->p_context->palctrl = &p_sys->palette;
}
+#else
+# warning FIXME
+#endif
/* ***** init this codec with special data ***** */
ffmpeg_InitCodec( p_dec );
/*
* Do the actual decoding now */
- /* Don't forget that ffmpeg requires a little more bytes
+ /* Don't forget that libavcodec requires a little more bytes
* that the real frame size */
if( p_block->i_buffer > 0 )
{
}
/* Sanity check (seems to be needed for some streams) */
- if( p_sys->p_ff_pic->pict_type == FF_B_TYPE )
+ if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
{
p_sys->b_has_b_frames = true;
}
for( i_line = 0; i_line < p_pic->p[i_plane].i_visible_lines;
i_line++ )
{
- vlc_memcpy( p_dst, p_src, i_size );
+ memcpy( p_dst, p_src, i_size );
p_src += i_src_stride;
p_dst += i_dst_stride;
}
/* */
p_ff_pic->type = FF_BUFFER_TYPE_USER;
- /* FIXME what is that, should give good value */
- p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg
+
+#if LIBAVCODEC_VERSION_MAJOR < 54
+ p_ff_pic->age = 256*256*256*64;
+#endif
if( vlc_va_Get( p_sys->p_va, p_ff_pic ) )
{
p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
p_ff_pic->linesize[3] = 0;
- /* FIXME what is that, should give good value */
- p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg
+#if LIBAVCODEC_VERSION_MAJOR < 54
+ p_ff_pic->age = 256*256*256*64;
+#endif
post_mt( p_sys );
return 0;
[PIX_FMT_VAAPI_MOCO] = "PIX_FMT_VAAPI_MOCO",
#ifdef HAVE_AVCODEC_DXVA2
[PIX_FMT_DXVA2_VLD] = "PIX_FMT_DXVA2_VLD",
+#endif
+#ifdef HAVE_AVCODEC_VDA
+ [PIX_FMT_VDA_VLD] = "PIX_FMT_VDA_VLD",
#endif
[PIX_FMT_YUYV422] = "PIX_FMT_YUYV422",
[PIX_FMT_YUV420P] = "PIX_FMT_YUV420P",
}
#endif
+#ifdef HAVE_AVCODEC_VDA
+ if( pi_fmt[i] == PIX_FMT_VDA_VLD )
+ {
+ msg_Dbg( p_dec, "Trying VDA" );
+ p_sys->p_va = vlc_va_NewVDA( VLC_OBJECT(p_dec), p_sys->i_codec_id, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
+ if( !p_sys->p_va )
+ msg_Warn( p_dec, "Failed to open VDA" );
+ }
+#endif
+
if( p_sys->p_va &&
p_context->width > 0 && p_context->height > 0 )
{