Commit a8b249bc authored by Thomas Guillem's avatar Thomas Guillem

decoder: refactor pf_decode_* callbacks

Use only one callback for every decoder types:

int (*pf_decode)(decoder_t *, block_t *p_block);

There is now only one way to send output frames/blocks from a decoder module:
using decoder_QueueVideo(), decoder_QueueAudio() and decoder_QueueSub()
functions.

This fixes transcoding not receiving any output when a decoder used
decoder_Queue*() function.

The pf_packetize callback is kept unchanged. A packetizer shouldn't be
asynchronous at all (and this simplify the locking for decoder core).

The pf_decode callback returns, for now, only one value: SUCCESS. This will
allow a module to send more status.
parent f4eec050
......@@ -67,11 +67,23 @@ struct decoder_t
/* Tell the decoder if it is allowed to drop frames */
bool b_frame_drop_allowed;
/* All pf_decode_* and pf_packetize functions have the same behavior.
# define VLCDEC_SUCCESS VLC_SUCCESS
/* This function is called to decode one packetized block.
*
* These functions are called in a loop with the same pp_block argument
* until they return NULL. This allows a module implementation to return
* more than one frames/samples for one input block.
* The module implementation will own the input block (p_block) and should
* process and release it. Depending of the decoder type, the module should
* send output frames/blocks via decoder_QueueVideo(), decoder_QueueAudio()
* or decoder_QueueSub().
*
* If p_block is NULL, the decoder asks the module to drain itself. The
* module should return all available output frames/block via the queue
* functions.
*/
int ( * pf_decode ) ( decoder_t *, block_t *p_block );
/* This function is called in a loop with the same pp_block argument until
* it returns NULL. This allows a module implementation to return more than
* one output blocks for one input block.
*
* pp_block or *pp_block can be NULL.
*
......@@ -79,32 +91,31 @@ struct decoder_t
* own the input block (*pp_block) and should process and release it. The
* module can also process a part of the block. In that case, it should
* modify (*pp_block)->p_buffer/i_buffer accordingly and return a valid
* frame/samples. The module can also set *pp_block to NULL when the input
* output block. The module can also set *pp_block to NULL when the input
* block is consumed.
*
* If pp_block is not NULL but *pp_block is NULL, a previous call of the pf
* function has set the *pp_block to NULL. Here, the module can return new
* frames/samples for the same, already processed, input block (the pf
* function will be called as long as the module return a frame/samples).
* output block for the same, already processed, input block (the
* pf_packetize function will be called as long as the module return an
* output block).
*
* When the pf function returns NULL, the next call to this function will
* have a new a valid pp_block (if the decoder is not drained).
* have a new a valid pp_block (if the packetizer is not drained).
*
* If pp_block is NULL, the decoder asks the module to drain itself. In
* that case, the module has to return all frames/samples available (the pf
* function will be called as long as the module return a frame/samples).
* If pp_block is NULL, the packetizer asks the module to drain itself. In
* that case, the module has to return all output frames available (the
* pf_packetize function will be called as long as the module return an
* output block).
*/
picture_t * ( * pf_decode_video )( decoder_t *, block_t **pp_block );
block_t * ( * pf_decode_audio )( decoder_t *, block_t **pp_block );
subpicture_t * ( * pf_decode_sub) ( decoder_t *, block_t **pp_block );
block_t * ( * pf_packetize ) ( decoder_t *, block_t **pp_block );
block_t * ( * pf_packetize )( decoder_t *, block_t **pp_block );
/* */
void ( * pf_flush ) ( decoder_t * );
/* Closed Caption (CEA 608/708) extraction.
* If set, it *may* be called after pf_decode_video/pf_packetize
* If set, it *may* be called after pf_decode/pf_packetize
* returned data. It should return CC for the pictures returned by the
* last pf_packetize/pf_decode_video call only,
* last pf_packetize/pf_decode call only,
* pb_present will be used to known which cc channel are present (but
* globaly, not necessary for the current packet */
block_t * ( * pf_get_cc ) ( decoder_t *, bool pb_present[4] );
......@@ -156,6 +167,7 @@ struct decoder_t
int (*pf_queue_audio)( decoder_t *, block_t * );
/* XXX use decoder_QueueSub */
int (*pf_queue_sub)( decoder_t *, subpicture_t *);
void *p_queue_ctx;
/* Private structure for the owner of the decoder */
decoder_owner_sys_t *p_owner;
......@@ -325,14 +337,14 @@ static inline int decoder_UpdateAudioFormat( decoder_t *dec )
/**
* This function will return a new audio buffer usable by a decoder as an
* output buffer. It must be released with block_Release() or returned it to
* the caller as a pf_decode_audio return value.
* the caller as a decoder_QueueAudio parameter.
*/
VLC_API block_t * decoder_NewAudioBuffer( decoder_t *, int i_size ) VLC_USED;
/**
* This function will return a new subpicture usable by a decoder as an output
* buffer. You have to release it using subpicture_Delete() or by returning
* it to the caller as a pf_decode_sub return value.
* it to the caller as a decoder_QueueSub parameter.
*/
VLC_API subpicture_t * decoder_NewSubpicture( decoder_t *, const subpicture_updater_t * ) VLC_USED;
......
......@@ -25,6 +25,7 @@
#define VLC_IMAGE_H 1
# include <vlc_picture.h>
# include <vlc_picture_fifo.h>
/**
* \file
......@@ -55,6 +56,8 @@ struct image_handler_t
decoder_t *p_dec;
encoder_t *p_enc;
filter_t *p_filter;
picture_fifo_t *outfifo;
};
VLC_API image_handler_t * image_HandlerCreate( vlc_object_t * ) VLC_USED;
......
......@@ -154,13 +154,12 @@ static void Exchange( sample_t *restrict p_out, const sample_t *restrict p_in )
}
}
static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
static int Decode( decoder_t *p_dec, block_t *p_in_buf )
{
decoder_sys_t *p_sys = p_dec->p_sys;
if (pp_block == NULL || *pp_block == NULL)
return NULL;
block_t *p_in_buf = *pp_block;
if (p_in_buf == NULL) /* No drain */
return VLCDEC_SUCCESS;
#ifdef LIBA52_FIXED
sample_t i_sample_level = (1 << 24);
......@@ -175,7 +174,10 @@ static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
* samples for each channel. */
block_t *p_out_buf = block_Alloc( 6 * i_bytes_per_block );
if( unlikely(p_out_buf == NULL) )
goto out;
{
block_Release( p_in_buf );
return VLCDEC_SUCCESS;
}
/* Do the actual decoding now. */
a52_frame( p_sys->p_liba52, p_in_buf->p_buffer,
......@@ -231,10 +233,9 @@ static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
p_out_buf->i_dts = p_in_buf->i_dts;
p_out_buf->i_pts = p_in_buf->i_pts;
p_out_buf->i_length = p_in_buf->i_length;
out:
block_Release( p_in_buf );
*pp_block = NULL;
return p_out_buf;
decoder_QueueAudio( p_dec, p_out_buf );
return VLCDEC_SUCCESS;
}
static int channels_vlc2a52( const audio_format_t *p_audio, int *p_flags )
......@@ -369,8 +370,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
p_dec->pf_decode_audio = Decode;
p_dec->pf_flush = NULL;
p_dec->pf_decode = Decode;
p_dec->pf_flush = NULL;
return VLC_SUCCESS;
}
......
......@@ -41,7 +41,7 @@
static int OpenDecoder( vlc_object_t * );
static void CloseDecoder( vlc_object_t * );
static block_t *DecodeBlock( decoder_t *, block_t ** );
static int DecodeAudio( decoder_t *, block_t * );
static void Flush( decoder_t * );
vlc_module_begin ()
......@@ -290,8 +290,8 @@ static int OpenDecoder( vlc_object_t *p_this )
date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
date_Set( &p_sys->end_date, 0 );
p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_flush = Flush;
p_dec->pf_decode = DecodeAudio;
p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
......@@ -314,7 +314,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
if( !pp_block || !*pp_block ) return NULL;
if( !*pp_block ) return NULL;
p_block = *pp_block;
......@@ -390,6 +390,17 @@ drop:
return NULL;
}
static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
{
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
block_t **pp_block = &p_block, *p_out;
while( ( p_out = DecodeBlock( p_dec, pp_block ) ) != NULL )
decoder_QueueAudio( p_dec, p_out );
return VLCDEC_SUCCESS;
}
/*****************************************************************************
* CloseDecoder:
*****************************************************************************/
......
......@@ -74,7 +74,7 @@ struct decoder_sys_t
static int Open( decoder_t *p_dec, bool b_packetizer );
static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
block_t **pp_block, bool b_packetizer );
block_t *p_block, bool b_packetizer );
/*****************************************************************************
* OpenDecoder:
......@@ -135,16 +135,15 @@ static const uint8_t reverse[256] = {
****************************************************************************
* Beware, this function must be fed with complete frames (PES packet).
*****************************************************************************/
static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
static int Decode( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
block_t *p_aout_buffer;
int i_frame_length, i_bits;
p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, false );
p_block = Parse( p_dec, &i_frame_length, &i_bits, p_block, false );
if( !p_block )
return NULL;
return VLCDEC_SUCCESS;
if( decoder_UpdateAudioFormat( p_dec ) )
{
......@@ -220,7 +219,9 @@ static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
exit:
block_Release( p_block );
return p_aout_buffer;
if( p_aout_buffer != NULL )
decoder_QueueAudio( p_dec, p_aout_buffer );
return VLCDEC_SUCCESS;
}
/*****************************************************************************
......@@ -244,7 +245,12 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
block_t *p_block;
int i_frame_length, i_bits;
p_block = Parse( p_dec, &i_frame_length, &i_bits, pp_block, true );
if( !pp_block ) /* No Drain */
return NULL;
p_block = *pp_block;
*pp_block = NULL; /* So the packet doesn't get re-sent */
p_block = Parse( p_dec, &i_frame_length, &i_bits, p_block, true );
if( !p_block )
return NULL;
......@@ -284,7 +290,7 @@ static int Open( decoder_t *p_dec, bool b_packetizer )
{
p_dec->fmt_out.i_codec = VLC_CODEC_302M;
p_dec->pf_decode_audio = NULL;
p_dec->pf_decode = NULL;
p_dec->pf_packetize = Packetize;
}
else
......@@ -292,8 +298,8 @@ static int Open( decoder_t *p_dec, bool b_packetizer )
p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
p_dec->fmt_out.audio.i_bitspersample = 16;
p_dec->pf_decode_audio = Decode;
p_dec->pf_packetize = NULL;
p_dec->pf_decode = Decode;
p_dec->pf_packetize = NULL;
}
p_dec->pf_flush = Flush;
return VLC_SUCCESS;
......@@ -312,20 +318,17 @@ static const unsigned int pi_original_channels[4] = {
AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
};
static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
block_t **pp_block, bool b_packetizer )
static block_t * Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
block_t *p_block, bool b_packetizer )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
uint32_t h;
unsigned int i_size;
int i_channels;
int i_bits;
if( !pp_block || !*pp_block ) return NULL;
p_block = *pp_block;
*pp_block = NULL; /* So the packet doesn't get re-sent */
if( !p_block ) /* No drain */
return NULL;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
......
......@@ -132,25 +132,23 @@ static vlc_fourcc_t FindVlcChroma( struct aom_image *img )
/****************************************************************************
* Decode: the whole thing
****************************************************************************/
static picture_t *Decode(decoder_t *dec, block_t **pp_block)
static int Decode(decoder_t *dec, block_t *block)
{
aom_codec_ctx_t *ctx = &dec->p_sys->ctx;
if( !pp_block || !*pp_block )
return NULL;
block_t *block = *pp_block;
if (!block) /* No Drain */
return VLCDEC_SUCCESS;
if (block->i_flags & (BLOCK_FLAG_CORRUPTED)) {
block_Release(block);
return NULL;
return VLCDEC_SUCCESS;
}
/* Associate packet PTS with decoded frame */
mtime_t *pkt_pts = malloc(sizeof(*pkt_pts));
if (!pkt_pts) {
block_Release(block);
*pp_block = NULL;
return NULL;
return VLCDEC_SUCCESS;
}
*pkt_pts = block->i_pts;
......@@ -159,19 +157,18 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
err = aom_codec_decode(ctx, block->p_buffer, block->i_buffer, pkt_pts, 0);
block_Release(block);
*pp_block = NULL;
if (err != AOM_CODEC_OK) {
free(pkt_pts);
AOM_ERR(dec, ctx, "Failed to decode frame");
return NULL;
return VLCDEC_SUCCESS;
}
const void *iter = NULL;
struct aom_image *img = aom_codec_get_frame(ctx, &iter);
if (!img) {
free(pkt_pts);
return NULL;
return VLCDEC_SUCCESS;
}
/* fetches back the PTS */
......@@ -182,7 +179,7 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
dec->fmt_out.i_codec = FindVlcChroma(img);
if (dec->fmt_out.i_codec == 0) {
msg_Err(dec, "Unsupported output colorspace %d", img->fmt);
return NULL;
return VLCDEC_SUCCESS;
}
video_format_t *v = &dec->fmt_out.video;
......@@ -219,10 +216,10 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
}
if (decoder_UpdateVideoFormat(dec))
return NULL;
return VLCDEC_SUCCESS;
picture_t *pic = decoder_NewPicture(dec);
if (!pic)
return NULL;
return VLCDEC_SUCCESS;
for (int plane = 0; plane < pic->i_planes; plane++ ) {
uint8_t *src = img->planes[plane];
......@@ -241,7 +238,8 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
pic->b_progressive = true; /* codec does not support interlacing */
pic->date = pts;
return pic;
decoder_QueueVideo(dec, pic);
return VLCDEC_SUCCESS;
}
/*****************************************************************************
......@@ -281,7 +279,7 @@ static int OpenDecoder(vlc_object_t *p_this)
return VLC_EGENERIC;;
}
dec->pf_decode_video = Decode;
dec->pf_decode = Decode;
dec->fmt_out.i_cat = VIDEO_ES;
dec->fmt_out.video.i_width = dec->fmt_in.video.i_width;
......
......@@ -66,7 +66,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static block_t *DecodeBlock( decoder_t *, block_t ** );
static int DecodeBlock( decoder_t *, block_t * );
static void Flush( decoder_t * );
struct decoder_sys_t
......@@ -293,8 +293,8 @@ static int DecoderOpen( vlc_object_t *p_this )
date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
date_Set( &p_sys->end_date, 0 );
p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_flush = Flush;
p_dec->pf_decode = DecodeBlock;
p_dec->pf_flush = Flush;
p_dec->p_sys = p_sys;
return VLC_SUCCESS;
......@@ -315,16 +315,11 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* This function must be fed with whole samples (see nBlockAlign).
****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
if( pp_block == NULL )
return NULL;
block_t *p_block = *pp_block;
if( p_block == NULL )
return NULL;
*pp_block = NULL;
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
goto skip;
......@@ -368,10 +363,11 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_block->i_pts = date_Get( &p_sys->end_date );
p_block->i_length = date_Increment( &p_sys->end_date, samples )
- p_block->i_pts;
return p_block;
decoder_QueueAudio( p_dec, p_block );
return VLCDEC_SUCCESS;
skip:
block_Release( p_block );
return NULL;
return VLCDEC_SUCCESS;
}
static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
......
......@@ -41,7 +41,7 @@
*****************************************************************************/
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static subpicture_t *Decode( decoder_t *, block_t ** );
static int Decode( decoder_t *, block_t * );
#define IGNORE_RUBY_TEXT N_("Ignore ruby(furigana)")
#define IGNORE_RUBY_LONGTEXT N_("Ignore ruby(furigana) in the subtitle.")
......@@ -117,7 +117,7 @@ static int Open( vlc_object_t *p_this )
}
p_dec->p_sys = p_sys;
p_dec->pf_decode_sub = Decode;
p_dec->pf_decode = Decode;
p_dec->fmt_out.i_cat = SPU_ES;
p_dec->fmt_out.i_codec = 0;
......@@ -161,22 +161,17 @@ static void Close( vlc_object_t *p_this )
/*****************************************************************************
* Decode:
*****************************************************************************/
static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
static int Decode( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
subpicture_t *p_spu = NULL;
if( ( pp_block == NULL ) || ( *pp_block == NULL ) )
{
return NULL;
}
p_block = *pp_block;
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
block_Release( p_block );
return NULL;
return VLCDEC_SUCCESS;
}
arib_parser_t *p_parser = arib_get_parser( p_sys->p_arib_instance );
......@@ -184,13 +179,13 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if ( p_parser && p_decoder )
{
arib_parse_pes( p_parser, p_block->p_buffer, p_block->i_buffer );
p_spu = render( p_dec, p_parser, p_decoder, p_block );
subpicture_t *p_spu = render( p_dec, p_parser, p_decoder, p_block );
if( p_spu != NULL )
decoder_QueueSub( p_dec, p_spu );
}
block_Release( p_block );
*pp_block = NULL;
return p_spu;
return VLCDEC_SUCCESS;
}
/* following functions are local */
......
......@@ -74,7 +74,7 @@ struct decoder_sys_t
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame );
static block_t *DecodeAudio( decoder_t *, block_t ** );
static int DecodeAudio( decoder_t *, block_t * );
static void Flush( decoder_t * );
static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
......@@ -270,8 +270,8 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
if( p_dec->fmt_out.audio.i_rate )
date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
p_dec->pf_decode_audio = DecodeAudio;
p_dec->pf_flush = Flush;
p_dec->pf_decode = DecodeAudio;
p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
......@@ -299,9 +299,9 @@ static void Flush( decoder_t *p_dec )
}
/*****************************************************************************
* DecodeAudio: Called to decode one frame
* DecodeBlock: Called to decode one frame
*****************************************************************************/
static block_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
AVCodecContext *ctx = p_sys->p_context;
......@@ -466,6 +466,14 @@ drop:
return NULL;
}
static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
{
block_t **pp_block = p_block ? &p_block : NULL, *p_out;
while( ( p_out = DecodeBlock( p_dec, pp_block ) ) != NULL )
decoder_QueueAudio( p_dec, p_out );
return VLCDEC_SUCCESS;
}
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame )
{
decoder_sys_t *p_sys = p_dec->p_sys;
......
......@@ -45,7 +45,7 @@ struct decoder_sys_t {
static subpicture_t *ConvertSubtitle(decoder_t *, AVSubtitle *, mtime_t pts,
AVCodecContext *avctx);
static subpicture_t *DecodeSubtitle(decoder_t *, block_t **);
static int DecodeSubtitle(decoder_t *, block_t *);
static void Flush(decoder_t *);
/**
......@@ -113,8 +113,8 @@ int InitSubtitleDec(decoder_t *dec, AVCodecContext *context,
/* */
msg_Dbg(dec, "libavcodec codec (%s) started", codec->name);
dec->fmt_out.i_cat = SPU_ES;
dec->pf_decode_sub = DecodeSubtitle;
dec->pf_flush = Flush;
dec->pf_decode = DecodeSubtitle;
dec->pf_flush = Flush;
return VLC_SUCCESS;
}
......@@ -132,7 +132,7 @@ static void Flush(decoder_t *dec)
/**
* Decode one subtitle
*/
static subpicture_t *DecodeSubtitle(decoder_t *dec, block_t **block_ptr)
static subpicture_t *DecodeBlock(decoder_t *dec, block_t **block_ptr)
{
decoder_sys_t *sys = dec->p_sys;
......@@ -203,6 +203,15 @@ static subpicture_t *DecodeSubtitle(decoder_t *dec, block_t **block_ptr)
return spu;
}
static int DecodeSubtitle(decoder_t *dec, block_t *block)
{
block_t **block_ptr = block ? &block : NULL;
subpicture_t *spu;
while ((spu = DecodeBlock(dec, block_ptr)) != NULL)
decoder_QueueSub(dec, spu);
return VLCDEC_SUCCESS;
}
/**
* Convert a RGBA libavcodec region to our format.
*/
......
......@@ -98,7 +98,7 @@ static void ffmpeg_InitCodec ( decoder_t * );
static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int);
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
const enum PixelFormat * );
static picture_t *DecodeVideo( decoder_t *, block_t ** );
static int DecodeVideo( decoder_t *, block_t * );
static void Flush( decoder_t * );
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
......@@ -554,8 +554,8 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
return VLC_EGENERIC;
}
p_dec->pf_decode_video = DecodeVideo;
p_dec->pf_flush = Flush;
p_dec->pf_decode = DecodeVideo;
p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
......@@ -706,9 +706,9 @@ static void update_late_frame_count( decoder_t *p_dec, block_t *p_block, mtime_t
/*****************************************************************************
* DecodeVideo: Called to decode one or more frames
* DecodeBlock: Called to decode one or more frames
*****************************************************************************/
static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
AVCodecContext *p_context = p_sys->p_context;
......@@ -1018,6 +1018,15 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
return NULL;
}
static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
{
block_t **pp_block = p_block ? &p_block : NULL;
picture_t *p_pic;
while( ( p_pic = DecodeBlock( p_dec, pp_block ) ) != NULL )
decoder_QueueVideo( p_dec, p_pic );
return VLCDEC_SUCCESS;
}
/*****************************************************************************
* EndVideo: decoder destruction
*****************************************************************************
......
......@@ -37,7 +37,7 @@ struct decoder_sys_t
static int OpenDecoder(vlc_object_t *);
static void CloseDecoder(vlc_object_t *);
static picture_t *DecodeBlock(decoder_t *, block_t **);
static int DecodeBlock(decoder_t *, block_t *);
/*
* Module descriptor
......@@ -80,7 +80,7 @@ static int OpenDecoder(vlc_object_t *p_this)
p_dec->fmt_out.i_cat = VIDEO_ES;
/* Set callbacks */
p_dec->pf_decode_video = DecodeBlock;
p_dec->pf_decode = DecodeBlock;
return VLC_SUCCESS;
}
......@@ -88,18 +88,14 @@ static int OpenDecoder(vlc_object_t *p_this)
/*
* This function must be fed with a complete compressed frame.
*/
static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
picture_t *p_pic = 0;
BPGImageInfo img_info;
if( !pp_block || !*pp_block )
return NULL;
p_block = *pp_block;
*pp_block = NULL;
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
goto error;
......@@ -158,12 +154,10 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )