X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Favcodec%2Fvideo.c;h=f257adb448731c5777218464302afd239e22cdae;hb=ad0b21e09097d2b7c4843dcc4bde66c9e2b766d1;hp=7125a6f92d38e3a69dfff42f53d82c23366870d1;hpb=0786bb1acb0ce2de97da2d9f0042854640fb8e48;p=vlc diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c index 7125a6f92d..f257adb448 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -31,7 +31,6 @@ #include #include -#include /* BITMAPINFOHEADER */ #include #include @@ -81,6 +80,7 @@ struct decoder_sys_t /* for direct rendering */ bool b_direct_rendering; + int i_direct_rendering_used; bool b_has_b_frames; @@ -150,22 +150,20 @@ static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec, p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; /* If an aspect-ratio was specified in the input format then force it */ - if( p_dec->fmt_in.video.i_aspect ) + if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 ) { - p_dec->fmt_out.video.i_aspect = p_dec->fmt_in.video.i_aspect; + p_dec->fmt_out.video.i_sar_num = p_dec->fmt_in.video.i_sar_num; + p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den; } else { - p_dec->fmt_out.video.i_aspect = - VOUT_ASPECT_FACTOR * ( av_q2d(p_context->sample_aspect_ratio) * - p_context->width / p_context->height ); p_dec->fmt_out.video.i_sar_num = p_context->sample_aspect_ratio.num; p_dec->fmt_out.video.i_sar_den = p_context->sample_aspect_ratio.den; - if( p_dec->fmt_out.video.i_aspect == 0 ) + if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den ) { - p_dec->fmt_out.video.i_aspect = - VOUT_ASPECT_FACTOR * p_context->width / p_context->height; + p_dec->fmt_out.video.i_sar_num = 1; + p_dec->fmt_out.video.i_sar_den = 1; } } @@ -218,14 +216,9 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, /* ***** Get configuration of ffmpeg plugin ***** */ p_sys->p_context->workaround_bugs = - config_GetInt( p_dec, "ffmpeg-workaround-bugs" ); -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 0, 0 ) - p_sys->p_context->error_resilience = - config_GetInt( p_dec, "ffmpeg-error-resilience" ); -#else + var_InheritInteger( p_dec, "ffmpeg-workaround-bugs" ); p_sys->p_context->error_recognition = - config_GetInt( p_dec, "ffmpeg-error-resilience" ); -#endif + var_InheritInteger( p_dec, "ffmpeg-error-resilience" ); if( var_CreateGetBool( p_dec, "grayscale" ) ) p_sys->p_context->flags |= CODEC_FLAG_GRAY; @@ -296,12 +289,9 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, /* ***** ffmpeg direct rendering ***** */ p_sys->b_direct_rendering = false; + p_sys->i_direct_rendering_used = -1; if( var_CreateGetBool( p_dec, "ffmpeg-dr" ) && (p_sys->p_codec->capabilities & CODEC_CAP_DR1) && - /* Apparently direct rendering doesn't work with YUV422P */ - p_sys->p_context->pix_fmt != PIX_FMT_YUV422P && - /* H264 uses too many reference frames */ - p_sys->i_codec_id != CODEC_ID_H264 && /* No idea why ... but this fixes flickering on some TSCC streams */ p_sys->i_codec_id != CODEC_ID_TSCC && !p_sys->p_context->debug_mv ) @@ -315,9 +305,13 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false; if( p_sys->b_direct_rendering ) { - msg_Dbg( p_dec, "using direct rendering" ); + msg_Dbg( p_dec, "trying to use direct rendering" ); p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE; } + else + { + msg_Dbg( p_dec, "direct rendering is disabled" ); + } /* Always use our get_buffer wrapper so we can calculate the * PTS correctly */ @@ -644,22 +638,18 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) p_sys->b_has_b_frames = true; } - if( !p_dec->fmt_in.video.i_aspect ) + if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den ) { /* Fetch again the aspect ratio in case it changed */ - p_dec->fmt_out.video.i_aspect = - VOUT_ASPECT_FACTOR - * ( av_q2d(p_sys->p_context->sample_aspect_ratio) - * p_sys->p_context->width / p_sys->p_context->height ); p_dec->fmt_out.video.i_sar_num = p_sys->p_context->sample_aspect_ratio.num; p_dec->fmt_out.video.i_sar_den = p_sys->p_context->sample_aspect_ratio.den; - if( p_dec->fmt_out.video.i_aspect == 0 ) + if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den ) { - p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR - * p_sys->p_context->width / p_sys->p_context->height; + p_dec->fmt_out.video.i_sar_num = 1; + p_dec->fmt_out.video.i_sar_den = 1; } } @@ -815,11 +805,7 @@ static int ffmpeg_OpenCodec( decoder_t *p_dec ) } p_sys->p_context->width = p_dec->fmt_in.video.i_width; p_sys->p_context->height = p_dec->fmt_in.video.i_height; -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 0, 0) - p_sys->p_context->bits_per_sample = p_dec->fmt_in.video.i_bits_per_pixel; -#else p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.video.i_bits_per_pixel; -#endif int ret; vlc_avcodec_lock(); @@ -831,9 +817,6 @@ static int ffmpeg_OpenCodec( decoder_t *p_dec ) p_sys->b_delayed_open = false; - if( p_sys->p_va && p_sys->p_va->description ) - msg_Info( p_dec, "Using %s for hardware decoding.", p_sys->p_va->description ); - return VLC_SUCCESS; } /***************************************************************************** @@ -930,7 +913,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, } else if( !p_sys->b_direct_rendering ) { - /* Not much to do in indirect rendering mode */ + /* Not much to do in indirect rendering mode. */ return avcodec_default_get_buffer( p_context, p_ff_pic ); } @@ -942,18 +925,57 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, avcodec_align_dimensions( p_sys->p_context, &i_width, &i_height ); if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS || - p_sys->p_context->width % 16 || p_sys->p_context->height % 16 || - /* We only pad picture up to 16 */ - PAD(p_sys->p_context->width,16) < i_width || PAD(p_sys->p_context->height,16) < i_height || p_context->pix_fmt == PIX_FMT_PAL8 ) - return avcodec_default_get_buffer( p_context, p_ff_pic ); + goto no_dr; p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; /* Get a new picture */ p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context ); if( !p_pic ) - return avcodec_default_get_buffer( p_context, p_ff_pic ); + goto no_dr; + bool b_compatible = true; + if( p_pic->p[0].i_pitch / p_pic->p[0].i_pixel_pitch < i_width || + p_pic->p[0].i_lines < i_height ) + b_compatible = false; + for( int i = 0; i < p_pic->i_planes && b_compatible; i++ ) + { + unsigned i_align; + switch( p_sys->i_codec_id ) + { + case CODEC_ID_SVQ1: + case CODEC_ID_VP5: + case CODEC_ID_VP6: + case CODEC_ID_VP6F: + case CODEC_ID_VP6A: + i_align = 16; + break; + default: + i_align = i == 0 ? 16 : 8; + break; + } + if( p_pic->p[i].i_pitch % i_align ) + b_compatible = false; + if( (intptr_t)p_pic->p[i].p_pixels % i_align ) + b_compatible = false; + } + if( p_context->pix_fmt == PIX_FMT_YUV422P && b_compatible ) + { + if( 2 * p_pic->p[1].i_pitch != p_pic->p[0].i_pitch || + 2 * p_pic->p[2].i_pitch != p_pic->p[0].i_pitch ) + b_compatible = false; + } + if( !b_compatible ) + { + decoder_DeletePicture( p_dec, p_pic ); + goto no_dr; + } + + if( p_sys->i_direct_rendering_used != 1 ) + { + msg_Dbg( p_dec, "using direct rendering" ); + p_sys->i_direct_rendering_used = 1; + } p_sys->p_context->draw_horiz_band = NULL; @@ -975,6 +997,14 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg return 0; + +no_dr: + if( p_sys->i_direct_rendering_used != 0 ) + { + msg_Warn( p_dec, "disabling direct rendering" ); + p_sys->i_direct_rendering_used = 0; + } + return avcodec_default_get_buffer( p_context, p_ff_pic ); } static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *p_context, AVFrame *p_ff_pic ) { @@ -1161,6 +1191,9 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_codec, if( p_sys->p_va ) { + if( p_sys->p_va->description ) + msg_Info( p_dec, "Using %s for hardware decoding.", p_sys->p_va->description ); + /* FIXME this will disabled direct rendering * even if a new pixel format is renegociated */