[vlc-devel] [PATCH] codec: avcodec: rework for readframe loop
Francois Cartegnie
fcvlcdev at free.fr
Mon Jun 12 22:09:15 CEST 2017
Changes to support multiple output per block
or delayed multiple output.
Also fixes draining, and some flags applied
to asynchronous output.
Unsure about the post_mt / wait_mt sections
correctness.
---
modules/codec/avcodec/video.c | 466 ++++++++++++++++++++++++------------------
1 file changed, 262 insertions(+), 204 deletions(-)
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 83eac59..a4fba2a 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -48,6 +48,15 @@
#include "../codec/cc.h"
+#define PACKET_HISTORY_DEPTH 64
+
+struct pkt_prop_s
+{
+ int64_t i_reordered_opaque;
+ bool b_preroll;
+ bool b_end_of_sequence;
+};
+
/*****************************************************************************
* decoder_sys_t : decoder descriptor
*****************************************************************************/
@@ -77,8 +86,10 @@ struct decoder_sys_t
atomic_bool b_dr_failure;
/* Hack to force display of still pictures */
- bool b_first_frame;
+ bool b_force_display;
+ /* Attach some data to decoded frames */
+ struct pkt_prop_s packets[PACKET_HISTORY_DEPTH];
/* */
bool palette_sent;
@@ -111,6 +122,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
const enum PixelFormat * );
static int DecodeVideo( decoder_t *, block_t * );
static void Flush( decoder_t * );
+static int ReceiveFrame( decoder_t *p_dec, mtime_t );
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{
@@ -515,6 +527,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
p_context->get_buffer2 = lavc_GetFrame;
p_context->refcounted_frames = true;
p_context->opaque = p_dec;
+ p_context->reordered_opaque = 0;
int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
if( i_thread_count <= 0 )
@@ -557,7 +570,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
/* ***** misc init ***** */
date_Init(&p_sys->pts, 1, 30001);
date_Set(&p_sys->pts, VLC_TS_INVALID);
- p_sys->b_first_frame = true;
+ p_sys->b_force_display = true;
p_sys->i_late_frames = 0;
p_sys->b_from_preroll = false;
@@ -646,19 +659,10 @@ static bool check_block_validity( decoder_sys_t *p_sys, block_t *block )
static bool check_block_being_late( decoder_sys_t *p_sys, block_t *block, mtime_t current_time)
{
- if( !block )
- return false;
- if( block->i_flags & BLOCK_FLAG_PREROLL )
- {
- /* Do not care about late frames when prerolling
- * TODO avoid decoding of non reference frame
- * (ie all B except for H264 where it depends only on nal_ref_idc) */
- p_sys->i_late_frames = 0;
- p_sys->b_from_preroll = true;
- p_sys->i_last_late_delay = INT64_MAX;
- }
-
- if( p_sys->i_late_frames <= 0 )
+ /* Do not care about late frames when prerolling
+ * TODO avoid decoding of non reference frame
+ * (ie all B except for H264 where it depends only on nal_ref_idc) */
+ if( !block || (block->i_flags & BLOCK_FLAG_PREROLL) || p_sys->i_late_frames <= 0 )
return false;
if( current_time - p_sys->i_late_frames_start > (5*CLOCK_FREQ))
@@ -666,7 +670,6 @@ static bool check_block_being_late( decoder_sys_t *p_sys, block_t *block, mtime_
date_Set( &p_sys->pts, VLC_TS_INVALID ); /* To make sure we recover properly */
if( block )
block_Release( block );
- p_sys->i_late_frames--;
return true;
}
return false;
@@ -711,36 +714,55 @@ static void interpolate_next_pts( decoder_t *p_dec, AVFrame *frame )
date_Increment( &p_sys->pts, i_tick + frame->repeat_pict );
}
-static void update_late_frame_count( decoder_t *p_dec, block_t *p_block, mtime_t current_time, mtime_t i_pts )
+static void update_late_frame_count( decoder_t *p_dec, mtime_t current_time, mtime_t i_pts, bool b_prerolling )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- /* Update frame late count (except when doing preroll) */
- mtime_t i_display_date = VLC_TS_INVALID;
- if( !p_block || !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
- i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
-
- if( i_display_date > VLC_TS_INVALID && i_display_date <= current_time )
- {
- /* Out of preroll, consider only late frames on rising delay */
- if( p_sys->b_from_preroll )
- {
- if( p_sys->i_last_late_delay > current_time - i_display_date )
- {
- p_sys->i_last_late_delay = current_time - i_display_date;
- return;
- }
- p_sys->b_from_preroll = false;
- }
-
- p_sys->i_late_frames++;
- if( p_sys->i_late_frames == 1 )
- p_sys->i_late_frames_start = current_time;
-
- }
- else
- {
- p_sys->i_late_frames = 0;
- }
+ /* Update frame late count (except when doing preroll) */
+ if( b_prerolling )
+ {
+ p_sys->b_from_preroll = true;
+ p_sys->i_late_frames = 0;
+ p_sys->i_last_late_delay = 0;
+ p_sys->i_late_frames_start = VLC_TS_INVALID;
+ return;
+ }
+
+ const mtime_t i_display_date = decoder_GetDisplayDate( p_dec, i_pts );
+ if( i_display_date == VLC_TS_INVALID )
+ return;
+ const mtime_t i_diff = current_time - i_display_date;
+
+ if( i_diff > 0 && p_sys->pts.i_divider_num > 0 )
+ {
+ date_t pts = p_sys->pts;
+ date_Increment( &pts, __MAX(1, p_sys->p_context->ticks_per_frame) );
+ /* output can vary have varying delay by few a ms (and reject inter frame delay delta) */
+ const int64_t i_framelength = date_Get( &pts ) - date_Get( &p_sys->pts );
+ /* Out of preroll, consider only late frames on rising delay */
+ if( i_framelength > 0 && !p_sys->b_from_preroll &&
+ p_sys->i_last_late_delay / i_framelength < i_diff / i_framelength )
+ {
+ if( p_sys->i_late_frames < 12 )
+ p_sys->i_late_frames++;
+ if( p_sys->i_late_frames == 1 )
+ p_sys->i_late_frames_start = current_time;
+ p_sys->b_from_preroll = false;
+ }
+ }
+ else
+ {
+ p_sys->b_from_preroll = b_prerolling;
+ if(p_sys->i_late_frames > 0)
+ p_sys->i_late_frames--;
+ }
+
+ p_sys->i_last_late_delay = __MAX(i_diff, 0);
+
+ if(p_sys->i_late_frames == 0)
+ {
+ p_sys->i_last_late_delay = 0;
+ p_sys->i_late_frames_start = VLC_TS_INVALID;
+ }
}
@@ -851,7 +873,7 @@ static void DecodeSidedata( decoder_t *p_dec, const AVFrame *frame, picture_t *p
/*****************************************************************************
* DecodeBlock: Called to decode one or more frames
*****************************************************************************/
-static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error )
+static int DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error )
{
decoder_sys_t *p_sys = p_dec->p_sys;
AVCodecContext *p_context = p_sys->p_context;
@@ -859,8 +881,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
bool b_need_output_picture = true;
/* Boolean for END_OF_SEQUENCE */
- bool eos_spotted = false;
-
+ bool b_end_of_sequence = false;
block_t *p_block;
mtime_t current_time = VLC_TS_INVALID;
@@ -874,24 +895,25 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
p_block = pp_block ? *pp_block : NULL;
if(!p_block && !(p_sys->p_codec->capabilities & AV_CODEC_CAP_DELAY) )
- return NULL;
+ return VLC_EGENERIC;
if( p_sys->b_delayed_open )
{
if( p_block )
block_Release( p_block );
- return NULL;
+ return VLC_EGENERIC;
}
if( !check_block_validity( p_sys, p_block ) )
- return NULL;
+ return VLC_EGENERIC;
current_time = mdate();
if( p_dec->b_frame_drop_allowed && check_block_being_late( p_sys, p_block, current_time) )
{
+ p_sys->i_late_frames--;
msg_Err( p_dec, "more than 5 seconds of late video -> "
"dropping frame (computer too slow ?)" );
- return NULL;
+ return VLC_EGENERIC;
}
@@ -899,7 +921,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
/* Defaults that if we aren't in prerolling, we want output picture
same for if we are flushing (p_block==NULL) */
- if( !p_block || !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
+ if( !p_block || !(p_block->i_flags & (BLOCK_FLAG_PREROLL|BLOCK_FLAG_END_OF_SEQUENCE)) )
b_need_output_picture = true;
else
b_need_output_picture = false;
@@ -917,7 +939,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
if( p_block )
block_Release( p_block );
msg_Warn( p_dec, "More than 11 late frames, dropping frame" );
- return NULL;
+ return VLC_EGENERIC;
}
}
if( !b_need_output_picture )
@@ -933,25 +955,23 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
* that the real frame size */
if( p_block && p_block->i_buffer > 0 )
{
- eos_spotted = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;
+ b_end_of_sequence = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;
p_block = block_Realloc( p_block, 0,
p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
if( !p_block )
- return NULL;
+ return VLC_SUCCESS;
p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
*pp_block = p_block;
memset( p_block->p_buffer + p_block->i_buffer, 0,
FF_INPUT_BUFFER_PADDING_SIZE );
}
- while( !p_block || p_block->i_buffer > 0 || eos_spotted )
+ while( !p_block || p_block->i_buffer > 0 )
{
- int i_used;
+ size_t i_used = 0;
AVPacket pkt;
- post_mt( p_sys );
-
av_init_packet( &pkt );
if( p_block && p_block->i_buffer > 0 )
{
@@ -987,8 +1007,9 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
if( !b_need_output_picture )
pkt.flags |= AV_PKT_FLAG_DISCARD;
#endif
-
+ post_mt( p_sys );
int ret = avcodec_send_packet(p_context, &pkt);
+ wait_mt( p_sys );
if( ret != 0 && ret != AVERROR(EAGAIN) )
{
if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL))
@@ -999,201 +1020,238 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block, bool *error
av_packet_unref( &pkt );
break;
}
+
+ struct pkt_prop_s *p_prop = &p_sys->packets[p_context->reordered_opaque % PACKET_HISTORY_DEPTH];
+ p_prop->b_preroll = (p_block && (p_block->i_flags & BLOCK_FLAG_PREROLL));
+ p_prop->b_end_of_sequence = (p_block && (p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE));
+ p_prop->i_reordered_opaque = p_context->reordered_opaque++;
+ if( p_prop->b_preroll )
+ p_sys->b_from_preroll = true;
+
i_used = ret != AVERROR(EAGAIN) ? pkt.size : 0;
av_packet_unref( &pkt );
- AVFrame *frame = av_frame_alloc();
- if (unlikely(frame == NULL))
+ if( p_block )
{
- *error = true;
- break;
+ /* Consumed bytes */
+ p_block->p_buffer += i_used;
+ if( i_used < p_block->i_buffer )
+ p_block->i_buffer -= i_used;
+ else
+ p_block->i_buffer = 0;
}
- ret = avcodec_receive_frame(p_context, frame);
- if( ret != 0 && ret != AVERROR(EAGAIN) )
+ do
{
- if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL))
- {
- msg_Err(p_dec, "avcodec_receive_frame critical error");
- *error = true;
- }
- av_frame_free(&frame);
- /* After draining, we need to reset decoder with a flush */
- if( ret == AVERROR_EOF )
- avcodec_flush_buffers( p_sys->p_context );
+ post_mt( p_sys );
+ ret = ReceiveFrame( p_dec, current_time );
+ wait_mt( p_sys );
+
+
+ } while ( ret == VLC_SUCCESS );
+
+ if( ret == VLC_EGENERIC )
+ *error = true;
+
+ if( ret != VLC_SUCCESS || !p_block || p_block->i_buffer == 0 )
break;
- }
- bool not_received_frame = ret;
+ }
- wait_mt( p_sys );
+ if( p_block )
+ block_Release( p_block );
- if( eos_spotted )
- p_sys->b_first_frame = true;
+ /* Need to drain after EOS packet */
+ if( b_end_of_sequence && !*error )
+ DecodeBlock( p_dec, NULL, error );
- if( p_block )
- {
- if( p_block->i_buffer <= 0 )
- eos_spotted = false;
+ return VLC_SUCCESS;
+}
- /* Consumed bytes */
- p_block->p_buffer += i_used;
- p_block->i_buffer -= i_used;
- }
+static int ReceiveFrame( decoder_t *p_dec, mtime_t current_time )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ AVCodecContext *p_context = p_sys->p_context;
+
+ AVFrame *frame = av_frame_alloc();
+ if (unlikely(frame == NULL))
+ return VLC_EGENERIC;
- /* Nothing to display */
- if( not_received_frame )
+ int ret = avcodec_receive_frame(p_context, frame);
+ if( ret != 0 && ret != AVERROR(EAGAIN) )
+ {
+ av_frame_free(&frame);
+ /* After draining, we need to reset decoder with a flush */
+ if( ret == AVERROR_EOF )
{
- av_frame_free(&frame);
- if( i_used == 0 ) break;
- continue;
+ avcodec_flush_buffers( p_sys->p_context );
}
+ else
+ {
+ char errbuf[AV_ERROR_MAX_STRING_SIZE];
+ av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
+ msg_Err(p_dec, "avcodec_receive_frame %s", errbuf);
+ if (ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL))
+ return VLC_EGENERIC;
+ }
+ return VLC_ENOITEM;
+ }
+ bool not_received_frame = ret;
- /* Compute the PTS */
+ /* Nothing to display */
+ if( not_received_frame )
+ {
+ av_frame_free(&frame);
+ return VLC_ENOITEM;
+ }
+
+ /* Get stored properties */
+ struct pkt_prop_s *p_prop = &p_sys->packets[frame->reordered_opaque % PACKET_HISTORY_DEPTH];
+ if( p_prop->i_reordered_opaque != frame->reordered_opaque )
+ p_prop = NULL;
+ else if( p_prop->b_end_of_sequence )
+ p_sys->b_force_display = true;
+
+ /* Compute the PTS */
#ifdef FF_API_PKT_PTS
- mtime_t i_pts = frame->pts;
+ mtime_t i_pts = frame->pts;
#else
- mtime_t i_pts = frame->pkt_pts;
+ mtime_t i_pts = frame->pkt_pts;
#endif
- if (i_pts == AV_NOPTS_VALUE )
- i_pts = frame->pkt_dts;
+ if (i_pts == AV_NOPTS_VALUE )
+ i_pts = frame->pkt_dts;
- if( i_pts == AV_NOPTS_VALUE )
- i_pts = date_Get( &p_sys->pts );
+ if( i_pts == AV_NOPTS_VALUE )
+ i_pts = date_Get( &p_sys->pts );
- /* Interpolate the next PTS */
- if( i_pts > VLC_TS_INVALID )
- date_Set( &p_sys->pts, i_pts );
+ /* Interpolate the next PTS */
+ if( i_pts > VLC_TS_INVALID )
+ date_Set( &p_sys->pts, i_pts );
- interpolate_next_pts( p_dec, frame );
+ interpolate_next_pts( p_dec, frame );
+
+ update_late_frame_count( p_dec, current_time, i_pts, (p_prop && p_prop->b_preroll) );
+
+ if( ( !p_sys->p_va && !frame->linesize[0] ) ||
+ ( p_dec->b_frame_drop_allowed && (frame->flags & AV_FRAME_FLAG_CORRUPT) &&
+ !p_sys->b_show_corrupted ) )
+ {
+ av_frame_free(&frame);
+ return VLC_SUCCESS;
+ }
- update_late_frame_count( p_dec, p_block, current_time, i_pts);
+#if !LIBAVCODEC_VERSION_CHECK( 57, 0, 0xFFFFFFFFU, 64, 101 )
+ if( !b_need_output_picture )
+ {
+ av_frame_free(&frame);
+ return VLC_SUCCESS;
+ }
+#endif
- if( ( !p_sys->p_va && !frame->linesize[0] ) ||
- ( p_dec->b_frame_drop_allowed && (frame->flags & AV_FRAME_FLAG_CORRUPT) &&
- !p_sys->b_show_corrupted ) )
+ if( p_context->pix_fmt == AV_PIX_FMT_PAL8
+ && !p_dec->fmt_out.video.p_palette )
+ {
+ /* See AV_PIX_FMT_PAL8 comment in avc_GetVideoFormat(): update the
+ * fmt_out palette and change the fmt_out chroma to request a new
+ * vout */
+ assert( p_dec->fmt_out.video.i_chroma != VLC_CODEC_RGBP );
+
+ video_palette_t *p_palette;
+ p_palette = p_dec->fmt_out.video.p_palette
+ = malloc( sizeof(video_palette_t) );
+ if( !p_palette )
{
av_frame_free(&frame);
- continue;
+ return VLC_EGENERIC;
}
-
-#if !LIBAVCODEC_VERSION_CHECK( 57, 0, 0xFFFFFFFFU, 64, 101 )
- if( !b_need_output_picture )
+ static_assert( sizeof(p_palette->palette) == AVPALETTE_SIZE,
+ "Palette size mismatch between vlc and libavutil" );
+ assert( frame->data[1] != NULL );
+ memcpy( p_palette->palette, frame->data[1], AVPALETTE_SIZE );
+ p_palette->i_entries = AVPALETTE_COUNT;
+ p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBP;
+ if( decoder_UpdateVideoFormat( p_dec ) )
{
av_frame_free(&frame);
- continue;
+ return VLC_SUCCESS;
}
-#endif
+ }
- if( p_context->pix_fmt == AV_PIX_FMT_PAL8
- && !p_dec->fmt_out.video.p_palette )
+ picture_t *p_pic = frame->opaque;
+ if( p_pic == NULL )
+ { /* When direct rendering is not used, get_format() and get_buffer()
+ * might not be called. The output video format must be set here
+ * then picture buffer can be allocated. */
+ if (p_sys->p_va == NULL
+ && lavc_UpdateVideoFormat(p_dec, p_context, p_context->pix_fmt,
+ p_context->pix_fmt) == 0)
+ p_pic = decoder_NewPicture(p_dec);
+
+ if( !p_pic )
{
- /* See AV_PIX_FMT_PAL8 comment in avc_GetVideoFormat(): update the
- * fmt_out palette and change the fmt_out chroma to request a new
- * vout */
- assert( p_dec->fmt_out.video.i_chroma != VLC_CODEC_RGBP );
-
- video_palette_t *p_palette;
- p_palette = p_dec->fmt_out.video.p_palette
- = malloc( sizeof(video_palette_t) );
- if( !p_palette )
- {
- *error = true;
- av_frame_free(&frame);
- break;
- }
- static_assert( sizeof(p_palette->palette) == AVPALETTE_SIZE,
- "Palette size mismatch between vlc and libavutil" );
- assert( frame->data[1] != NULL );
- memcpy( p_palette->palette, frame->data[1], AVPALETTE_SIZE );
- p_palette->i_entries = AVPALETTE_COUNT;
- p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBP;
- if( decoder_UpdateVideoFormat( p_dec ) )
- {
- av_frame_free(&frame);
- continue;
- }
+ av_frame_free(&frame);
+ return VLC_SUCCESS;
}
- picture_t *p_pic = frame->opaque;
- if( p_pic == NULL )
- { /* When direct rendering is not used, get_format() and get_buffer()
- * might not be called. The output video format must be set here
- * then picture buffer can be allocated. */
- if (p_sys->p_va == NULL
- && lavc_UpdateVideoFormat(p_dec, p_context, p_context->pix_fmt,
- p_context->pix_fmt) == 0)
- p_pic = decoder_NewPicture(p_dec);
-
- if( !p_pic )
- {
- av_frame_free(&frame);
- break;
- }
-
- /* Fill picture_t from AVFrame */
- if( lavc_CopyPicture( p_dec, p_pic, frame ) != VLC_SUCCESS )
- {
- *error = true;
- av_frame_free(&frame);
- picture_Release( p_pic );
- break;
- }
- }
- else
+ /* Fill picture_t from AVFrame */
+ if( lavc_CopyPicture( p_dec, p_pic, frame ) != VLC_SUCCESS )
{
- if( p_sys->p_va != NULL )
- vlc_va_Extract( p_sys->p_va, p_pic, frame->data[3] );
- picture_Hold( p_pic );
+ av_frame_free(&frame);
+ picture_Release( p_pic );
+ return VLC_EGENERIC;
}
+ }
+ else
+ {
+ if( p_sys->p_va != NULL )
+ vlc_va_Extract( p_sys->p_va, p_pic, frame->data[3] );
+ picture_Hold( p_pic );
+ }
- 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_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_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_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_sar_num || !p_dec->fmt_out.video.i_sar_den )
- {
- p_dec->fmt_out.video.i_sar_num = 1;
- p_dec->fmt_out.video.i_sar_den = 1;
- }
+ if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den )
+ {
+ p_dec->fmt_out.video.i_sar_num = 1;
+ p_dec->fmt_out.video.i_sar_den = 1;
}
+ }
- p_pic->date = i_pts;
- /* Hack to force display of still pictures */
- p_pic->b_force = p_sys->b_first_frame;
- p_pic->i_nb_fields = 2 + frame->repeat_pict;
- p_pic->b_progressive = !frame->interlaced_frame;
- p_pic->b_top_field_first = frame->top_field_first;
+ p_pic->date = i_pts;
+ /* Hack to force display of still pictures */
+ p_pic->b_force = p_sys->b_force_display;
+ p_pic->i_nb_fields = 2 + frame->repeat_pict;
+ p_pic->b_progressive = !frame->interlaced_frame;
+ p_pic->b_top_field_first = frame->top_field_first;
- DecodeSidedata( p_dec, frame, p_pic );
+ DecodeSidedata( p_dec, frame, p_pic );
- av_frame_free(&frame);
+ av_frame_free(&frame);
- /* Send decoded frame to vout */
- if (i_pts > VLC_TS_INVALID)
- {
- p_sys->b_first_frame = false;
- return p_pic;
- }
- else
- picture_Release( p_pic );
+ /* Send decoded frame to vout */
+ if (i_pts > VLC_TS_INVALID)
+ {
+ p_sys->b_force_display = false;
+ decoder_QueueVideo( p_dec, p_pic );
}
+ else
+ picture_Release( p_pic );
- if( p_block )
- block_Release( p_block );
- return NULL;
+ return VLC_SUCCESS;
}
static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
{
block_t **pp_block = p_block ? &p_block : NULL;
- picture_t *p_pic;
+
bool error = false;
- while( ( p_pic = DecodeBlock( p_dec, pp_block, &error ) ) != NULL )
- decoder_QueueVideo( p_dec, p_pic );
+ DecodeBlock( p_dec, pp_block, &error );
+
return error ? VLCDEC_ECRITICAL : VLCDEC_SUCCESS;
}
--
2.9.4
More information about the vlc-devel
mailing list