[vlc-devel] [PATCH 4/8] decoder: refactor pf_decode_* callbacks
Thomas Guillem
thomas at gllm.fr
Wed Feb 8 19:53:51 CET 2017
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.
TODO: fix some spu decoders that send a queue of spu (they should call
decoder_QueueSub() for each spu).
---
include/vlc_codec.h | 50 ++++---
include/vlc_image.h | 3 +
modules/codec/a52.c | 21 +--
modules/codec/adpcm.c | 19 ++-
modules/codec/aes3.c | 37 ++---
modules/codec/aom.c | 28 ++--
modules/codec/araw.c | 22 ++-
modules/codec/arib/aribsub.c | 22 ++-
modules/codec/avcodec/audio.c | 18 ++-
modules/codec/avcodec/subtitle.c | 17 ++-
modules/codec/avcodec/video.c | 19 ++-
modules/codec/bpg.c | 20 +--
modules/codec/cc.c | 19 ++-
modules/codec/cdg.c | 19 ++-
modules/codec/crystalhd.c | 27 ++--
modules/codec/cvdsub.c | 24 ++--
modules/codec/daala.c | 46 ++++---
modules/codec/dca.c | 16 +--
modules/codec/ddummy.c | 18 +--
modules/codec/dmo/dmo.c | 94 +++++--------
modules/codec/dvbsub.c | 33 ++---
modules/codec/faad.c | 34 +++--
modules/codec/flac.c | 28 ++--
modules/codec/fluidsynth.c | 23 ++--
modules/codec/g711.c | 29 ++--
modules/codec/gstreamer/gstdecode.c | 24 ++--
modules/codec/jpeg.c | 23 ++--
modules/codec/kate.c | 65 +++++----
modules/codec/libass.c | 29 ++--
modules/codec/libmpeg2.c | 18 ++-
modules/codec/lpcm.c | 19 ++-
modules/codec/mad.c | 14 +-
modules/codec/mft.c | 71 +++-------
modules/codec/mpg123.c | 17 ++-
modules/codec/oggspots.c | 50 ++++---
modules/codec/omxil/mediacodec.c | 75 ++++------
modules/codec/omxil/omxil.c | 94 ++++++-------
modules/codec/opus.c | 54 +++++---
modules/codec/png.c | 36 ++---
modules/codec/rawvideo.c | 36 +++--
modules/codec/schroedinger.c | 33 ++---
modules/codec/scte18.c | 15 +-
modules/codec/scte27.c | 13 +-
modules/codec/sdl_image.c | 23 ++--
modules/codec/spdif.c | 20 +--
modules/codec/speex.c | 63 +++++----
modules/codec/spudec/spudec.c | 35 +++--
modules/codec/stl.c | 17 ++-
modules/codec/subsdec.c | 20 ++-
modules/codec/substx3g.c | 30 ++--
modules/codec/subsusf.c | 19 ++-
modules/codec/svcdsub.c | 24 ++--
modules/codec/svg.c | 19 ++-
modules/codec/telx.c | 19 ++-
modules/codec/textst.c | 49 +++----
modules/codec/theora.c | 51 ++++---
modules/codec/ttml/substtml.c | 14 +-
modules/codec/uleaddvaudio.c | 19 ++-
modules/codec/videotoolbox.m | 38 +++---
modules/codec/vorbis.c | 35 +++--
modules/codec/vpx.c | 28 ++--
modules/codec/wmafixed/wma.c | 58 +++-----
modules/codec/xwd.c | 18 +--
modules/codec/zvbi.c | 20 ++-
modules/hw/mmal/codec.c | 28 ++--
modules/misc/stats.c | 15 +-
modules/packetizer/flac.c | 6 +-
modules/stream_out/mosaic_bridge.c | 180 ++++++++++++------------
modules/stream_out/transcode/audio.c | 82 ++++++++---
modules/stream_out/transcode/spu.c | 90 ++++++++----
modules/stream_out/transcode/transcode.c | 3 +
modules/stream_out/transcode/transcode.h | 22 +++
modules/stream_out/transcode/video.c | 55 +++++++-
src/input/decoder.c | 226 ++++++++-----------------------
src/input/demux.c | 4 +-
src/misc/image.c | 44 +++++-
76 files changed, 1407 insertions(+), 1339 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index eb4a5c3f41..2f8facc18f 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -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;
diff --git a/include/vlc_image.h b/include/vlc_image.h
index 0b9ab9e8ce..41aab308f6 100644
--- a/include/vlc_image.h
+++ b/include/vlc_image.h
@@ -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;
diff --git a/modules/codec/a52.c b/modules/codec/a52.c
index 967ad20d79..f9f48cfb31 100644
--- a/modules/codec/a52.c
+++ b/modules/codec/a52.c
@@ -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;
}
diff --git a/modules/codec/adpcm.c b/modules/codec/adpcm.c
index 1128f5a7a9..457f2fc0c1 100644
--- a/modules/codec/adpcm.c
+++ b/modules/codec/adpcm.c
@@ -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:
*****************************************************************************/
diff --git a/modules/codec/aes3.c b/modules/codec/aes3.c
index ce7f20d3ad..019e242601 100644
--- a/modules/codec/aes3.c
+++ b/modules/codec/aes3.c
@@ -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 )
{
diff --git a/modules/codec/aom.c b/modules/codec/aom.c
index fb818f1243..2770b6deb0 100644
--- a/modules/codec/aom.c
+++ b/modules/codec/aom.c
@@ -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;
diff --git a/modules/codec/araw.c b/modules/codec/araw.c
index 5e323f69e4..28add6fe39 100644
--- a/modules/codec/araw.c
+++ b/modules/codec/araw.c
@@ -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 )
diff --git a/modules/codec/arib/aribsub.c b/modules/codec/arib/aribsub.c
index 84f54d3ffa..cf1ea3e3b3 100644
--- a/modules/codec/arib/aribsub.c
+++ b/modules/codec/arib/aribsub.c
@@ -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,18 @@ 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 );
@@ -185,12 +181,12 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
arib_parse_pes( p_parser, p_block->p_buffer, p_block->i_buffer );
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 */
diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c
index 35cd258289..0700963745 100644
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -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;
diff --git a/modules/codec/avcodec/subtitle.c b/modules/codec/avcodec/subtitle.c
index 26d87547f6..b48dea381b 100644
--- a/modules/codec/avcodec/subtitle.c
+++ b/modules/codec/avcodec/subtitle.c
@@ -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.
*/
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index dc477f823e..b2ab47878a 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -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
*****************************************************************************
diff --git a/modules/codec/bpg.c b/modules/codec/bpg.c
index 8c41fa75ff..757c0c696f 100644
--- a/modules/codec/bpg.c
+++ b/modules/codec/bpg.c
@@ -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 )
p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;
- block_Release( p_block );
- return p_pic;
-
+ decoder_QueueVideo( p_dec, p_pic );
error:
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
static void CloseDecoder( vlc_object_t *p_this )
diff --git a/modules/codec/cc.c b/modules/codec/cc.c
index eacc3d29b3..b62adda31f 100644
--- a/modules/codec/cc.c
+++ b/modules/codec/cc.c
@@ -225,7 +225,7 @@ struct decoder_sys_t
bool b_opaque;
};
-static subpicture_t *Decode( decoder_t *, block_t ** );
+static int Decode( decoder_t *, block_t * );
static void Flush( decoder_t * );
/*****************************************************************************
@@ -260,8 +260,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
- p_dec->pf_decode_sub = Decode;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = Decode;
+ p_dec->pf_flush = Flush;
/* Allocate the memory needed to store the decoder's structure */
p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
@@ -301,15 +301,12 @@ static void Push( decoder_t *, block_t * );
static block_t *Pop( decoder_t * );
static subpicture_t *Convert( decoder_t *, block_t ** );
-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;
- if( pp_block && *pp_block )
- {
- Push( p_dec, *pp_block );
- *pp_block = NULL;
- }
+ if( p_block )
+ Push( p_dec, p_block );
for( ;; )
{
@@ -331,9 +328,9 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
subpicture_t *p_spu = Convert( p_dec, &p_sys->p_block );
if( p_spu )
- return p_spu;
+ decoder_QueueSub( p_dec, p_spu );
}
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/cdg.c b/modules/codec/cdg.c
index b0e8ad65c2..3bb0c3141d 100644
--- a/modules/codec/cdg.c
+++ b/modules/codec/cdg.c
@@ -73,7 +73,7 @@ struct decoder_sys_t
static int Open ( vlc_object_t * );
static void Close( vlc_object_t * );
-static picture_t *Decode( decoder_t *, block_t ** );
+static int Decode( decoder_t *, block_t * );
static int DecodePacket( decoder_sys_t *p_cdg, uint8_t *p_buffer, int i_buffer );
static void Flush( decoder_t * );
@@ -124,8 +124,8 @@ static int Open( vlc_object_t *p_this )
p_dec->fmt_out.video.i_bmask = 0xff << CDG_COLOR_B_SHIFT;
/* Set callbacks */
- p_dec->pf_decode_video = Decode;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = Decode;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -145,15 +145,13 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* This function must be fed with a complete compressed frame.
****************************************************************************/
-static picture_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;
picture_t *p_pic = NULL;
- if( !pp_block || !*pp_block )
- return NULL;
- p_block = *pp_block;
+ if( !p_block ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
@@ -185,8 +183,9 @@ static picture_t *Decode( decoder_t *p_dec, block_t **pp_block )
exit:
block_Release( p_block );
- *pp_block = NULL;
- return p_pic;
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/crystalhd.c b/modules/codec/crystalhd.c
index f0c15877c6..9a8d2e7acc 100644
--- a/modules/codec/crystalhd.c
+++ b/modules/codec/crystalhd.c
@@ -96,7 +96,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static picture_t *DecodeBlock ( decoder_t *p_dec, block_t **pp_block );
+static int DecodeBlock ( decoder_t *p_dec, block_t *p_block );
// static void crystal_CopyPicture ( picture_t *, BC_DTS_PROC_OUT* );
static int crystal_insert_sps_pps(decoder_t *, uint8_t *, uint32_t);
@@ -350,7 +350,7 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.video.i_height = p_dec->fmt_in.video.i_height;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
msg_Info( p_dec, "Opened CrystalHD hardware with success" );
return VLC_SUCCESS;
@@ -431,20 +431,19 @@ static BC_STATUS ourCallback(void *shnd, uint32_t width, uint32_t height, uint32
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
-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 = NULL;
BC_DTS_PROC_OUT proc_out;
BC_DTS_STATUS driver_stat;
/* First check the status of the decode to produce pictures */
if( BC_FUNC_PSYS(DtsGetDriverStatus)( p_sys->bcm_handle, &driver_stat ) != BC_STS_SUCCESS )
- return NULL;
-
- if( pp_block )
- p_block = *pp_block;
+ {
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
+ }
if( p_block )
{
@@ -457,10 +456,9 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_block->i_pts >= VLC_TS_INVALID ? TO_BC_PTS(p_block->i_pts) : 0, false );
block_Release( p_block );
- *pp_block = NULL;
if( status != BC_STS_SUCCESS )
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
#ifdef DEBUG_CRYSTALHD
@@ -472,7 +470,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
#endif
if( driver_stat.ReadyListCount == 0 )
- return NULL;
+ return VLCDEC_SUCCESS;
/* Prepare the Output structure */
/* We always expect and use YUY2 */
@@ -508,7 +506,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/* In interlaced mode, do not push the first field in the pipeline */
if( (proc_out.PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
!(proc_out.PicInfo.flags & VDEC_FLAG_FIELDPAIR) )
- return NULL;
+ return VLCDEC_SUCCESS;
// crystal_CopyPicture( p_pic, &proc_out );
p_pic->date = proc_out.PicInfo.timeStamp > 0 ?
@@ -517,7 +515,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
#ifdef DEBUG_CRYSTALHD
msg_Dbg( p_dec, "TS Output is %"PRIu64, p_pic->date);
#endif
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
case BC_STS_DEC_NOT_OPEN:
case BC_STS_DEC_NOT_STARTED:
@@ -585,7 +584,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
if( p_pic )
picture_Release( p_pic );
- return NULL;
+ return VLCDEC_SUCCESS;
}
#if 0
diff --git a/modules/codec/cvdsub.c b/modules/codec/cvdsub.c
index 44269e3b45..29fdae2507 100644
--- a/modules/codec/cvdsub.c
+++ b/modules/codec/cvdsub.c
@@ -60,7 +60,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static subpicture_t *Decode( decoder_t *, block_t ** );
+static int Decode( decoder_t *, block_t * );
static block_t *Packetize ( decoder_t *, block_t ** );
static block_t *Reassemble ( decoder_t *, block_t * );
static void ParseMetaInfo ( decoder_t *, block_t * );
@@ -122,7 +122,7 @@ static int DecoderOpen( vlc_object_t *p_this )
p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
p_sys->p_spu = NULL;
- p_dec->pf_decode_sub = Decode;
+ p_dec->pf_decode = Decode;
p_dec->pf_packetize = Packetize;
p_dec->fmt_out.i_cat = SPU_ES;
@@ -160,25 +160,27 @@ void DecoderClose( 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 )
{
- block_t *p_block, *p_spu;
+ block_t *p_data;
- if( pp_block == NULL || *pp_block == NULL ) 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 )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
- if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
+ if( !(p_data = Reassemble( p_dec, p_block )) )
+ return VLCDEC_SUCCESS;
/* Parse and decode */
- return DecodePacket( p_dec, p_spu );
+ subpicture_t *p_spu = DecodePacket( p_dec, p_data );
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/daala.c b/modules/codec/daala.c
index 7bcf7c7f5f..ca94b67107 100644
--- a/modules/codec/daala.c
+++ b/modules/codec/daala.c
@@ -80,9 +80,10 @@ static int OpenDecoder ( vlc_object_t * );
static int OpenPacketizer( vlc_object_t * );
static void CloseDecoder ( vlc_object_t * );
-static void *DecodeBlock ( decoder_t *, block_t ** );
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block );
+static block_t *Packetize ( decoder_t *, block_t ** );
static int ProcessHeaders( decoder_t * );
-static void *ProcessPacket ( decoder_t *, daala_packet *, block_t ** );
+static void *ProcessPacket ( decoder_t *, daala_packet *, block_t * );
static picture_t *DecodePacket( decoder_t *, daala_packet * );
@@ -183,10 +184,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_I420;
/* Set callbacks */
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
+ p_dec->pf_decode = DecodeVideo;
+ p_dec->pf_packetize = Packetize;
/* Init supporting Daala structures needed in header parsing */
daala_comment_init( &p_sys->dc );
@@ -215,16 +214,11 @@ static int OpenPacketizer( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with Daala packets.
****************************************************************************/
-static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block;
daala_packet dpacket;
- if( !pp_block || !*pp_block ) return NULL;
-
- p_block = *pp_block;
-
/* Block to Daala packet */
dpacket.packet = p_block->p_buffer;
dpacket.bytes = p_block->i_buffer;
@@ -252,7 +246,28 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( !p_sys->b_decoded_first_keyframe )
p_block->i_flags |= BLOCK_FLAG_PREROLL; /* Wait until we've decoded the first keyframe */
- return ProcessPacket( p_dec, &dpacket, pp_block );
+ return ProcessPacket( p_dec, &dpacket, p_block );
+}
+
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ picture_t *p_pic = DecodeBlock( p_dec, p_block );
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+ return DecodeBlock( p_dec, p_block );
}
/*****************************************************************************
@@ -402,10 +417,9 @@ cleanup:
* ProcessPacket: processes a daala packet.
*****************************************************************************/
static void *ProcessPacket( decoder_t *p_dec, daala_packet *p_dpacket,
- block_t **pp_block )
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block = *pp_block;
void *p_buf;
if( ( p_block->i_flags&(BLOCK_FLAG_CORRUPTED) ) != 0 )
@@ -423,8 +437,6 @@ static void *ProcessPacket( decoder_t *p_dec, daala_packet *p_dpacket,
p_sys->i_pts = p_block->i_pts;
}
- *pp_block = NULL; /* To avoid being fed the same packet again */
-
if( p_sys->b_packetizer )
{
/* Date management */
diff --git a/modules/codec/dca.c b/modules/codec/dca.c
index d2f7e00e0f..78e55f23c9 100644
--- a/modules/codec/dca.c
+++ b/modules/codec/dca.c
@@ -122,14 +122,13 @@ static void Exchange( float * p_out, const float * 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;
+ if (p_in_buf == NULL) /* No Drain */
+ return VLCDEC_SUCCESS;
- block_t *p_in_buf = *pp_block;
sample_t i_sample_level = 1;
int i_flags = p_sys->i_flags;
size_t i_bytes_per_block = 256 * p_sys->i_nb_channels * sizeof(float);
@@ -212,9 +211,10 @@ static block_t *Decode( decoder_t *p_dec, block_t **pp_block )
p_out_buf->i_pts = p_in_buf->i_pts;
p_out_buf->i_length = p_in_buf->i_length;
out:
+ if (p_out_buf != NULL)
+ decoder_QueueAudio(p_dec, p_out_buf);
block_Release( p_in_buf );
- *pp_block = NULL;
- return p_out_buf;
+ return VLCDEC_SUCCESS;
}
static int channels_vlc2dca( const audio_format_t *p_audio, int *p_flags )
@@ -341,8 +341,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;
}
diff --git a/modules/codec/ddummy.c b/modules/codec/ddummy.c
index 2e88bbcdff..28f18c84c0 100644
--- a/modules/codec/ddummy.c
+++ b/modules/codec/ddummy.c
@@ -64,7 +64,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block );
/*****************************************************************************
* OpenDecoder: Open the decoder
@@ -93,12 +93,7 @@ static int OpenDecoderCommon( vlc_object_t *p_this, bool b_force_dump )
p_dec->p_sys = NULL;
/* Set callbacks */
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_decode_audio = (block_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_decode_sub = (subpicture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
@@ -120,14 +115,11 @@ static int OpenDecoderDump( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
FILE *stream = (void *)p_dec->p_sys;
- block_t *p_block;
- if( !pp_block || !*pp_block ) return NULL;
- p_block = *pp_block;
- *pp_block = NULL;
+ if( !p_block ) return VLCDEC_SUCCESS;
if( stream != NULL
&& p_block->i_buffer > 0
@@ -138,7 +130,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/dmo/dmo.c b/modules/codec/dmo/dmo.c
index 4559380a39..f76fa6ccc6 100644
--- a/modules/codec/dmo/dmo.c
+++ b/modules/codec/dmo/dmo.c
@@ -75,7 +75,7 @@ static const int pi_channels_maps[7] =
*****************************************************************************/
static int DecoderOpen ( vlc_object_t * );
static void DecoderClose ( vlc_object_t * );
-static void *DecodeBlock ( decoder_t *, block_t ** );
+static int DecodeBlock ( decoder_t *, block_t * );
static void *DecoderThread( void * );
static int EncoderOpen ( vlc_object_t * );
static void EncoderClose ( vlc_object_t * );
@@ -125,10 +125,7 @@ struct decoder_sys_t
vlc_mutex_t lock;
vlc_cond_t wait_input, wait_output;
bool b_ready, b_works;
- block_t **pp_input;
-
- int i_output;
- void **pp_output;
+ block_t *p_input;
};
const GUID IID_IWMCodecPrivateData = {0x73f0be8e, 0x57f7, 0x4f01, {0xaa, 0x66, 0x9f, 0x57, 0x34, 0xc, 0xfe, 0xe}};
@@ -271,18 +268,14 @@ found:
return VLC_ENOMEM;
/* Set callbacks */
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_decode_audio = (block_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
vlc_mutex_init( &p_sys->lock );
vlc_cond_init( &p_sys->wait_input );
vlc_cond_init( &p_sys->wait_output );
p_sys->b_works =
p_sys->b_ready = false;
- p_sys->pp_input = NULL;
- TAB_INIT( p_sys->i_output, p_sys->pp_output );
+ p_sys->p_input = NULL;
if( vlc_clone( &p_sys->thread, DecoderThread, p_dec,
VLC_THREAD_PRIORITY_INPUT ) )
@@ -319,38 +312,27 @@ static void DecoderClose( vlc_object_t *p_this )
vlc_mutex_unlock( &p_sys->lock );
vlc_join( p_sys->thread, NULL );
- TAB_CLEAN( p_sys->i_output, p_sys->pp_output );
vlc_cond_destroy( &p_sys->wait_input );
vlc_cond_destroy( &p_sys->wait_output );
vlc_mutex_destroy( &p_sys->lock );
free( p_sys );
}
-static void *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;
- void *p_ret;
-
- vlc_mutex_lock( &p_sys->lock );
- if( p_sys->i_output <= 0 )
- {
- p_sys->pp_input = pp_block;
- vlc_cond_signal( &p_sys->wait_input );
-
- while( p_sys->pp_input )
- vlc_cond_wait( &p_sys->wait_output, &p_sys->lock );
- }
- p_ret = NULL;
- if( p_sys->i_output > 0 )
- {
- p_ret = p_sys->pp_output[0];
- TAB_REMOVE( p_sys->i_output, p_sys->pp_output, p_ret );
- }
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+ vlc_mutex_lock( &p_sys->lock );
+ while( p_sys->p_input )
+ vlc_cond_wait( &p_sys->wait_output, &p_sys->lock );
+ p_sys->p_input = p_block;
+ vlc_cond_signal( &p_sys->wait_input );
vlc_mutex_unlock( &p_sys->lock );
- return p_ret;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
@@ -836,7 +818,7 @@ static void DecClose( decoder_t *p_dec )
****************************************************************************
* This function must be fed with packets.
****************************************************************************/
-static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecBlock( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
@@ -847,8 +829,6 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
block_t block_out;
uint32_t i_status;
- if( !pp_block ) return NULL;
-
p_block = *pp_block;
/* Won't work with streams with B-frames, but do we have any ? */
@@ -867,7 +847,7 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
{
/* We've just started the stream, wait for the first PTS. */
if( p_block ) block_Release( p_block );
- return NULL;
+ return -1;
}
#endif
@@ -890,7 +870,7 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
#ifdef DMO_DEBUG
msg_Dbg( p_dec, "ProcessInput(): no output generated" );
#endif
- return NULL;
+ return -1;
}
else if( i_result == (int)DMO_E_NOTACCEPTING )
{
@@ -900,21 +880,17 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
else if( i_result != S_OK )
{
msg_Dbg( p_dec, "ProcessInput(): failed" );
- return NULL;
+ return -1;
}
else
{
#ifdef DMO_DEBUG
msg_Dbg( p_dec, "ProcessInput(): successful" );
#endif
+ block_Release( p_block );
*pp_block = NULL;
}
}
- else if( p_block && !p_block->i_buffer )
- {
- block_Release( p_block );
- *pp_block = NULL;
- }
/* Get output from the DMO */
block_out.p_buffer = p_sys->p_buffer;
@@ -938,7 +914,7 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
#endif
p_out->vt->Release( (IUnknown *)p_out );
- return NULL;
+ return -1;
}
#ifdef DMO_DEBUG
@@ -951,16 +927,16 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
msg_Dbg( p_dec, "ProcessOutput(): no output (i_buffer_out == 0)" );
#endif
p_out->vt->Release( (IUnknown *)p_out );
- return NULL;
+ return -1;
}
if( p_dec->fmt_out.i_cat == VIDEO_ES )
{
/* Get a new picture */
if( decoder_UpdateVideoFormat( p_dec ) )
- return NULL;
+ return -1;
picture_t *p_pic = decoder_NewPicture( p_dec );
- if( !p_pic ) return NULL;
+ if( !p_pic ) return -1;
CopyPicture( p_pic, block_out.p_buffer );
@@ -970,14 +946,15 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
p_out->vt->Release( (IUnknown *)p_out );
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return 0;
}
else
{
if( decoder_UpdateAudioFormat( p_dec ) )
{
p_out->vt->Release( (IUnknown *)p_out );
- return NULL;
+ return -1;
}
block_t *p_aout_buffer;
@@ -998,10 +975,9 @@ static void *DecBlock( decoder_t *p_dec, block_t **pp_block )
}
p_out->vt->Release( (IUnknown *)p_out );
- return p_aout_buffer;
+ decoder_QueueAudio( p_dec, p_aout_buffer );
+ return 0;
}
-
- return NULL;
}
static void CopyPicture( picture_t *p_pic, uint8_t *p_in )
@@ -1043,19 +1019,17 @@ static void *DecoderThread( void *data )
vlc_mutex_lock( &p_sys->lock );
for( ;; )
{
- while( p_sys->b_ready && !p_sys->pp_input )
+ while( p_sys->b_ready && !p_sys->p_input )
vlc_cond_wait( &p_sys->wait_input, &p_sys->lock );
if( !p_sys->b_ready )
break;
- for( ;; )
- {
- void *p_output = DecBlock( p_dec, p_sys->pp_input );
- if( !p_output )
- break;
- TAB_APPEND( p_sys->i_output, p_sys->pp_output, p_output );
- }
- p_sys->pp_input = NULL;
+ while( DecBlock( p_dec, &p_sys->p_input ) == 0 );
+
+ if( p_sys->p_input != NULL )
+ block_Release( p_sys->p_input );
+ p_sys->p_input = NULL;
+
vlc_cond_signal( &p_sys->wait_output );
}
vlc_mutex_unlock( &p_sys->lock );
diff --git a/modules/codec/dvbsub.c b/modules/codec/dvbsub.c
index 85b8a6d520..00a31edb04 100644
--- a/modules/codec/dvbsub.c
+++ b/modules/codec/dvbsub.c
@@ -107,7 +107,7 @@ static const char *const ppsz_pos_descriptions[] =
*****************************************************************************/
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 * );
static void Flush( decoder_t * );
#ifdef ENABLE_SOUT
@@ -334,8 +334,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
- p_dec->pf_decode_sub = Decode;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = Decode;
+ p_dec->pf_flush = Flush;
p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) );
if( !p_sys )
return VLC_ENOMEM;
@@ -404,15 +404,12 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* 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;
- *pp_block = NULL;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{
@@ -420,7 +417,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
@@ -438,7 +435,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
msg_Warn( p_dec, "non dated subtitle" );
#endif
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
@@ -447,14 +444,14 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
msg_Dbg( p_dec, "invalid data identifier" );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */
{
msg_Dbg( p_dec, "invalid subtitle stream id" );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
#ifdef DEBUG_DVBSUB
@@ -471,16 +468,20 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Check if the page is to be displayed */
if( p_sys->p_page && p_sys->b_page )
- p_spu = render( p_dec );
+ {
+ subpicture_t *p_spu = render( p_dec );
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ }
block_Release( p_block );
- return p_spu;
+ return VLCDEC_SUCCESS;
}
/* following functions are local */
diff --git a/modules/codec/faad.c b/modules/codec/faad.c
index 137188c854..3443543470 100644
--- a/modules/codec/faad.c
+++ b/modules/codec/faad.c
@@ -59,7 +59,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 * );
static void DoReordering( uint32_t *, uint32_t *, int, int, uint32_t * );
@@ -195,8 +195,8 @@ static int Open( vlc_object_t *p_this )
p_sys->b_sbr = p_sys->b_ps = false;
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -213,15 +213,12 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* DecodeBlock:
*****************************************************************************/
-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;
- block_t *p_block;
- if( !pp_block || !*pp_block ) return NULL;
-
- p_block = *pp_block;
- *pp_block = NULL;
+ if( !p_block ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{
@@ -229,7 +226,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
@@ -305,7 +302,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
&i_rate, &i_channels ) < 0 )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_dec->fmt_out.audio.i_rate = i_rate;
@@ -325,7 +322,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
p_sys->i_buffer = 0;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Decode all data */
@@ -387,7 +384,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/* Flush the buffer */
p_sys->i_buffer = 0;
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )
@@ -402,7 +399,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->i_buffer );
}
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( frame.samples <= 0 )
@@ -422,7 +419,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->i_buffer = 0;
}
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* We decoded a valid frame */
@@ -500,7 +497,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
p_sys->i_buffer = 0;
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_out->i_pts = date_Get( &p_sys->date );
@@ -520,7 +517,8 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
block_Release( p_block );
- return p_out;
+ decoder_QueueAudio( p_dec, p_out );
+ return VLCDEC_SUCCESS;
}
else
{
@@ -529,7 +527,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/flac.c b/modules/codec/flac.c
index 504b0fac6d..92b7aa6146 100644
--- a/modules/codec/flac.c
+++ b/modules/codec/flac.c
@@ -102,7 +102,7 @@ static int OpenEncoder ( vlc_object_t * );
static void CloseEncoder ( vlc_object_t * );
#endif
-static block_t *DecodeBlock( decoder_t *, block_t ** );
+static int DecodeBlock( decoder_t *, block_t * );
static void Flush( decoder_t * );
/*****************************************************************************
@@ -361,8 +361,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_S32N;
/* Set callbacks */
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -509,28 +509,26 @@ static void Flush( decoder_t *p_dec )
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
-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 || !*pp_block )
- return NULL;
- if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+ if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{
Flush( p_dec );
- if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
+ if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
- block_Release( *pp_block );
- *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
}
if( !p_sys->b_stream_info )
ProcessHeader( p_dec );
- p_sys->p_block = *pp_block;
- *pp_block = NULL;
+ p_sys->p_block = p_block;
if( p_sys->p_block->i_pts > VLC_TS_INVALID &&
p_sys->p_block->i_pts != date_Get( &p_sys->end_date ) )
@@ -562,7 +560,9 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
block_Release( p_sys->p_block );
p_sys->p_block = NULL;
- return p_sys->p_aout_buffer;
+ if( p_sys->p_aout_buffer != NULL )
+ decoder_QueueAudio( p_dec, p_sys->p_aout_buffer );
+ return VLCDEC_SUCCESS;
}
#ifdef ENABLE_SOUT
diff --git a/modules/codec/fluidsynth.c b/modules/codec/fluidsynth.c
index b7e43b348f..93c803a4b7 100644
--- a/modules/codec/fluidsynth.c
+++ b/modules/codec/fluidsynth.c
@@ -97,7 +97,7 @@ struct decoder_sys_t
};
-static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block);
+static int DecodeBlock (decoder_t *p_dec, block_t *p_block);
static void Flush (decoder_t *);
static int Open (vlc_object_t *p_this)
@@ -181,8 +181,8 @@ static int Open (vlc_object_t *p_this)
date_Set (&p_sys->end_date, 0);
p_dec->p_sys = p_sys;
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -209,18 +209,13 @@ static void Flush (decoder_t *p_dec)
fluid_synth_noteoff (p_sys->synth, channel, note);
}
-static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
+static int DecodeBlock (decoder_t *p_dec, block_t *p_block)
{
- block_t *p_block;
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_out = NULL;
- if (pp_block == NULL)
- return NULL;
- 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_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
{
@@ -228,7 +223,7 @@ static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
{
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
@@ -310,5 +305,7 @@ static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
p_out->p_buffer, 1, 2);
drop:
block_Release (p_block);
- return p_out;
+ if (p_out != NULL)
+ decoder_QueueAudio (p_dec, p_out);
+ return VLCDEC_SUCCESS;
}
diff --git a/modules/codec/g711.c b/modules/codec/g711.c
index ec7292d481..6154e453e7 100644
--- a/modules/codec/g711.c
+++ b/modules/codec/g711.c
@@ -34,7 +34,7 @@
static int DecoderOpen ( vlc_object_t * );
static void DecoderClose( vlc_object_t * );
-static block_t *DecodeBlock( decoder_t *, block_t ** );
+static int DecodeBlock( decoder_t *, block_t * );
static void Flush( decoder_t * );
#ifdef ENABLE_SOUT
@@ -184,8 +184,8 @@ static int DecoderOpen( vlc_object_t *p_this )
return VLC_ENOMEM;
/* Set output properties */
- 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;
p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -221,21 +221,17 @@ static void Flush( decoder_t *p_dec )
date_Set( &p_sys->end_date, 0 );
}
-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;
- *pp_block = NULL;
- if( p_block == NULL )
- return NULL;
+ 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;
}
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
@@ -250,7 +246,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Don't re-use the same pts twice */
@@ -260,19 +256,19 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( samples == 0 )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( decoder_UpdateAudioFormat( p_dec ) )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
if( p_out == NULL )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
assert( p_out->i_nb_samples == samples );
@@ -291,7 +287,8 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
*(dst++) = p_sys->table[*(src++)];
block_Release( p_block );
- return p_out;
+ decoder_QueueAudio( p_dec, p_out );
+ return VLCDEC_SUCCESS;
}
static void DecoderClose( vlc_object_t *p_this )
diff --git a/modules/codec/gstreamer/gstdecode.c b/modules/codec/gstreamer/gstdecode.c
index 3b069df4ae..89cc39bb73 100644
--- a/modules/codec/gstreamer/gstdecode.c
+++ b/modules/codec/gstreamer/gstdecode.c
@@ -70,7 +70,7 @@ typedef struct
*****************************************************************************/
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* );
static void Flush( decoder_t * );
#define MODULE_DESCRIPTION N_( "Uses GStreamer framework's plugins " \
@@ -609,8 +609,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_sys->b_running = true;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
@@ -648,21 +648,15 @@ static void Flush( decoder_t *p_dec )
}
/* Decode */
-static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
- block_t *p_block;
picture_t *p_pic = NULL;
decoder_sys_t *p_sys = p_dec->p_sys;
GstMessage *p_msg;
GstBuffer *p_buf;
- if( !pp_block )
- return NULL;
-
- p_block = *pp_block;
-
- if( !p_block )
- goto check_messages;
+ if( !p_block ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( unlikely( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY |
BLOCK_FLAG_CORRUPTED ) ) )
@@ -736,7 +730,6 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
else
block_Release( p_block );
-check_messages:
/* Poll for any messages, errors */
p_msg = gst_bus_pop_filtered( p_sys->p_bus,
GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR |
@@ -813,8 +806,9 @@ check_messages:
}
done:
- *pp_block = NULL;
- return p_pic;
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
/* Close the decoder instance */
diff --git a/modules/codec/jpeg.c b/modules/codec/jpeg.c
index 60f60c343b..5c26d1fc69 100644
--- a/modules/codec/jpeg.c
+++ b/modules/codec/jpeg.c
@@ -76,7 +76,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 *);
/*
* jpeg encoder descriptor
@@ -178,7 +178,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;
}
@@ -493,26 +493,20 @@ jpeg_GetOrientation( j_decompress_ptr cinfo )
/*
* 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;
JSAMPARRAY p_row_pointers = NULL;
- if (!pp_block || !*pp_block)
- {
- return NULL;
- }
-
- p_block = *pp_block;
- *pp_block = NULL;
+ if (!p_block) /* No Drain */
+ return VLCDEC_SUCCESS;
if (p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* libjpeg longjmp's there in case of error */
@@ -581,7 +575,8 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;
block_Release(p_block);
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
error:
@@ -589,7 +584,7 @@ error:
free(p_row_pointers);
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*
diff --git a/modules/codec/kate.c b/modules/codec/kate.c
index 55678d67e7..d6bca7e650 100644
--- a/modules/codec/kate.c
+++ b/modules/codec/kate.c
@@ -156,11 +156,12 @@ static void CloseDecoder ( vlc_object_t * );
static int OpenPacketizer( vlc_object_t *p_this );
#endif
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
+static int DecodeSub( decoder_t *p_dec, block_t *p_block );
+static block_t * Packetize( decoder_t *p_dec, block_t **pp_block );
static void Flush( decoder_t * );
static int ProcessHeaders( decoder_t *p_dec );
-static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
- block_t **pp_block );
+static void *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
+ block_t *p_block );
static subpicture_t *DecodePacket( decoder_t *p_dec, kate_packet *p_kp,
block_t *p_block );
static void ParseKateComments( decoder_t * );
@@ -351,11 +352,9 @@ static int OpenDecoder( vlc_object_t *p_this )
msg_Dbg( p_dec, "kate: OpenDecoder");
/* Set callbacks */
- p_dec->pf_decode_sub = (subpicture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeSub;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
/* Allocate the memory needed to store the decoder's structure */
if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
@@ -476,18 +475,11 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* This function must be fed with kate packets.
****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block;
kate_packet kp;
- if( !pp_block || !*pp_block )
- return NULL;
-
- p_block = *pp_block;
- *pp_block = NULL;
-
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
{
#ifdef HAVE_TIGER
@@ -514,13 +506,34 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
if( ProcessHeaders( p_dec ) )
{
- block_Release( *pp_block );
+ block_Release( p_block );
return NULL;
}
p_sys->b_has_headers = true;
}
- return ProcessPacket( p_dec, &kp, pp_block );
+ return ProcessPacket( p_dec, &kp, p_block );
+}
+
+static int DecodeSub( decoder_t *p_dec, block_t *p_block )
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ subpicture_t *p_spu = DecodeBlock( p_dec, p_block );
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+ return DecodeBlock( p_dec, p_block );
}
/*****************************************************************************
@@ -611,12 +624,10 @@ static int ProcessHeaders( decoder_t *p_dec )
/*****************************************************************************
* ProcessPacket: processes a kate packet.
*****************************************************************************/
-static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
- block_t **pp_block )
+static void *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block = *pp_block;
- subpicture_t *p_buf = NULL;
/* Date management */
if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != p_sys->i_pts )
@@ -624,8 +635,6 @@ static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
p_sys->i_pts = p_block->i_pts;
}
- *pp_block = NULL; /* To avoid being fed the same packet again */
-
#ifdef ENABLE_PACKETIZER
if( p_sys->b_packetizer )
{
@@ -636,19 +645,17 @@ static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
p_block->i_length = p_sys->i_pts - p_block->i_pts;
else
p_block->i_length = 0;
-
- p_buf = p_block;
+ return p_block;
}
else
#endif
{
- p_buf = DecodePacket( p_dec, p_kp, p_block );
+ subpicture_t *p_buf = DecodePacket( p_dec, p_kp, p_block );
if( p_block )
block_Release( p_block );
+ return p_buf;
}
-
- return p_buf;
}
/* nicked off blend.c */
diff --git a/modules/codec/libass.c b/modules/codec/libass.c
index cf4dfe6505..7d7f265f58 100644
--- a/modules/codec/libass.c
+++ b/modules/codec/libass.c
@@ -64,7 +64,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *, block_t ** );
+static int DecodeBlock( decoder_t *, block_t * );
static void Flush( decoder_t * );
/* */
@@ -132,8 +132,8 @@ static int Create( vlc_object_t *p_this )
if( p_dec->fmt_in.i_codec != VLC_CODEC_SSA )
return VLC_EGENERIC;
- p_dec->pf_decode_sub = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
if( !p_sys )
@@ -310,37 +310,33 @@ static void Flush( decoder_t *p_dec )
/****************************************************************************
* DecodeBlock:
****************************************************************************/
-static subpicture_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;
subpicture_t *p_spu = NULL;
- block_t *p_block;
- if( !pp_block || *pp_block == NULL )
- 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 )
{
Flush( p_dec );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
subpicture_updater_sys_t *p_spu_sys = malloc( sizeof(*p_spu_sys) );
if( !p_spu_sys )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
subpicture_updater_t updater = {
@@ -355,7 +351,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
msg_Warn( p_dec, "can't get spu buffer" );
free( p_spu_sys );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_spu_sys->p_img = NULL;
@@ -367,7 +363,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
subpicture_Delete( p_spu );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
memcpy( p_spu_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
@@ -391,7 +387,8 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
block_Release( p_block );
- return p_spu;
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/****************************************************************************
diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c
index ef994d40c7..120844d804 100644
--- a/modules/codec/libmpeg2.c
+++ b/modules/codec/libmpeg2.c
@@ -110,7 +110,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 DecodeVideo( decoder_t *, block_t *);
#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
#endif
@@ -240,8 +240,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->pf_flush = Reset;
+ p_dec->pf_decode = DecodeVideo;
+ p_dec->pf_flush = Reset;
p_dec->fmt_out.i_cat = VIDEO_ES;
p_dec->fmt_out.i_codec = 0;
@@ -596,6 +596,18 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return NULL;
}
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block)
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ block_t **pp_block = &p_block;
+ picture_t *p_pic;
+ while( ( p_pic = DecodeBlock( p_dec, pp_block ) ) != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
+}
+
/*****************************************************************************
* CloseDecoder: libmpeg2 decoder destruction
*****************************************************************************/
diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c
index 97b9a485b5..c48d10d1dd 100644
--- a/modules/codec/lpcm.c
+++ b/modules/codec/lpcm.c
@@ -178,7 +178,8 @@ typedef struct
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static block_t *DecodeFrame ( decoder_t *, block_t ** );
+static int DecodeFrame ( decoder_t *, block_t * );
+static block_t *Packetize ( decoder_t *, block_t ** );
static void Flush( decoder_t * );
/* */
@@ -297,9 +298,9 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
}
/* Set callback */
- p_dec->pf_decode_audio = DecodeFrame;
- p_dec->pf_packetize = DecodeFrame;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeFrame;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -327,7 +328,7 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* Beware, this function must be fed with complete frames (PES packet).
*****************************************************************************/
-static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
@@ -511,6 +512,14 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
}
}
+static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
+{
+ block_t *p_out = Packetize( p_dec, &p_block );
+ if( p_out != NULL )
+ decoder_QueueAudio( p_dec, p_out );
+ return VLCDEC_SUCCESS;
+}
+
/*****************************************************************************
* CloseCommon : lpcm decoder destruction
*****************************************************************************/
diff --git a/modules/codec/mad.c b/modules/codec/mad.c
index 9a9772c7aa..635b2eadcd 100644
--- a/modules/codec/mad.c
+++ b/modules/codec/mad.c
@@ -81,7 +81,7 @@ vlc_module_begin ()
vlc_module_end ()
/*****************************************************************************
- * DecodeBLock: decode an MPEG audio frame.
+ * DecodeBlock: decode an MPEG audio frame.
*****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
@@ -216,6 +216,14 @@ reject:
goto end;
}
+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 void DecodeFlush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -270,8 +278,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = DecodeFlush;
+ p_dec->pf_decode = DecodeAudio;
+ p_dec->pf_flush = DecodeFlush;
return VLC_SUCCESS;
}
diff --git a/modules/codec/mft.c b/modules/codec/mft.c
index 25e9cfd193..fbd85d4bdc 100644
--- a/modules/codec/mft.c
+++ b/modules/codec/mft.c
@@ -640,15 +640,13 @@ static void CopyPackedBufferToPicture(picture_t *p_pic, const uint8_t *p_src)
}
}
-static int ProcessOutputStream(decoder_t *p_dec, DWORD stream_id, void **result)
+static int ProcessOutputStream(decoder_t *p_dec, DWORD stream_id)
{
decoder_sys_t *p_sys = p_dec->p_sys;
HRESULT hr;
picture_t *picture = NULL;
block_t *aout_buffer = NULL;
- *result = NULL;
-
DWORD output_status = 0;
MFT_OUTPUT_DATA_BUFFER output_buffer = { stream_id, p_sys->output_sample, 0, NULL };
hr = IMFTransform_ProcessOutput(p_sys->mft, 0, 1, &output_buffer, &output_status);
@@ -762,9 +760,9 @@ static int ProcessOutputStream(decoder_t *p_dec, DWORD stream_id, void **result)
}
if (p_dec->fmt_in.i_cat == VIDEO_ES)
- *result = picture;
+ decoder_QueueVideo(p_dec, picture);
else
- *result = aout_buffer;
+ decoder_QueueAudio(p_dec, aout_buffer);
return VLC_SUCCESS;
@@ -777,42 +775,32 @@ error:
return VLC_EGENERIC;
}
-static void *DecodeSync(decoder_t *p_dec, block_t **pp_block)
+static int DecodeSync(decoder_t *p_dec, block_t *p_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
- if (!pp_block || !*pp_block)
- return NULL;
+ if (!p_block) /* No Drain */
+ return VLCDEC_SUCCESS;
- block_t *p_block = *pp_block;
if (p_block->i_flags & (BLOCK_FLAG_CORRUPTED))
{
block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Drain the output stream before sending the input packet. */
- void *result = NULL;
- if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
+ if (ProcessOutputStream(p_dec, p_sys->output_stream_id))
goto error;
- if (result)
- return result;
-
if (ProcessInputStream(p_dec, p_sys->input_stream_id, p_block))
goto error;
-
block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
error:
msg_Err(p_dec, "Error in DecodeSync()");
- if (p_block)
- block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ block_Release(p_block);
+ return VLCDEC_SUCCESS;
}
static HRESULT DequeueMediaEvent(decoder_t *p_dec)
@@ -840,20 +828,18 @@ static HRESULT DequeueMediaEvent(decoder_t *p_dec)
return S_OK;
}
-static void *DecodeAsync(decoder_t *p_dec, block_t **pp_block)
+static int DecodeAsync(decoder_t *p_dec, block_t *p_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
HRESULT hr;
- if (!pp_block || !*pp_block)
- return NULL;
+ if (!p_block) /* No Drain */
+ return VLCDEC_SUCCESS;
- block_t *p_block = *pp_block;
if (p_block->i_flags & (BLOCK_FLAG_CORRUPTED))
{
block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Dequeue all pending media events. */
@@ -866,10 +852,8 @@ static void *DecodeAsync(decoder_t *p_dec, block_t **pp_block)
if (p_sys->pending_output_events > 0)
{
p_sys->pending_output_events -= 1;
- void *result = NULL;
- if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
+ if (ProcessOutputStream(p_dec, p_sys->output_stream_id))
goto error;
- return result;
}
/* Poll the MFT and return decoded frames until the input stream is ready. */
@@ -888,10 +872,9 @@ static void *DecodeAsync(decoder_t *p_dec, block_t **pp_block)
if (p_sys->pending_output_events > 0)
{
p_sys->pending_output_events -= 1;
- void *result = NULL;
- if (ProcessOutputStream(p_dec, p_sys->output_stream_id, &result))
+ if (ProcessOutputStream(p_dec, p_sys->output_stream_id))
goto error;
- return result;
+ break;
}
}
@@ -900,15 +883,13 @@ static void *DecodeAsync(decoder_t *p_dec, block_t **pp_block)
goto error;
block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
error:
msg_Err(p_dec, "Error in DecodeAsync()");
block_Release(p_block);
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
static void DestroyMFT(decoder_t *p_dec);
@@ -1157,17 +1138,7 @@ int Open(vlc_object_t *p_this)
if (AllocateOutputSample(p_dec, 0, &p_sys->output_sample))
goto error;
- if (p_sys->is_async)
- {
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))DecodeAsync;
- p_dec->pf_decode_audio = (block_t *(*)(decoder_t *, block_t **))DecodeAsync;
- }
- else
- {
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))DecodeSync;
- p_dec->pf_decode_audio = (block_t *(*)(decoder_t *, block_t **))DecodeSync;
- }
-
+ p_dec->pf_decode = p_sys->is_async ? DecodeAsync : DecodeSync;
p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;
return VLC_SUCCESS;
diff --git a/modules/codec/mpg123.c b/modules/codec/mpg123.c
index 559bf57266..90880f21bd 100644
--- a/modules/codec/mpg123.c
+++ b/modules/codec/mpg123.c
@@ -190,18 +190,15 @@ static int UpdateAudioFormat( decoder_t *p_dec )
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
-static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
int i_err;
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_out = NULL;
- block_t *p_block = pp_block ? *pp_block : NULL;
-
/* Feed input block */
if( p_block != NULL )
{
- *pp_block = NULL; /* avoid being fed the same packet again */
if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID )
{
/* We've just started the stream, wait for the first PTS. */
@@ -240,7 +237,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->p_out = block_Alloc( mpg123_outblock( p_sys->p_handle ) );
if( unlikely( !p_sys->p_out ) )
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Do the actual decoding now */
@@ -256,7 +253,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
mpg123_plain_strerror( i_err ) );
block_Release( p_sys->p_out );
p_sys->p_out = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
i_err = mpg123_decode_frame( p_sys->p_handle, NULL, NULL, &i_bytes );
@@ -307,7 +304,9 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
end:
if( p_block )
block_Release( p_block );
- return p_out;
+ if( p_out != NULL )
+ decoder_QueueAudio( p_dec, p_out );
+ return VLCDEC_SUCCESS;
}
@@ -378,8 +377,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i",
(char *)&p_dec->fmt_in.i_codec,
diff --git a/modules/codec/oggspots.c b/modules/codec/oggspots.c
index 4fbd6e4b04..9db89c40e3 100644
--- a/modules/codec/oggspots.c
+++ b/modules/codec/oggspots.c
@@ -67,9 +67,10 @@ static int OpenDecoder (vlc_object_t*);
static int OpenPacketizer(vlc_object_t*);
static void CloseDecoder (vlc_object_t*);
-static void* DecodeBlock (decoder_t*, block_t**);
+static int DecodeVideo (decoder_t*, block_t*);
+static block_t* Packetize (decoder_t*, block_t**);
static int ProcessHeader(decoder_t*);
-static void* ProcessPacket(decoder_t*, block_t**);
+static void* ProcessPacket(decoder_t*, block_t*);
static void Flush (decoder_t*);
static picture_t* DecodePacket (decoder_t*, block_t*);
@@ -128,11 +129,9 @@ static int OpenDecoder(vlc_object_t* p_this)
}
/* Set callbacks */
- p_dec->pf_decode_video = (picture_t*(*)(decoder_t*, block_t**))
- DecodeBlock;
- p_dec->pf_packetize = (block_t*(*)(decoder_t*, block_t**))
- DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeVideo;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -156,22 +155,41 @@ static int OpenPacketizer(vlc_object_t* p_this)
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static void* DecodeBlock(decoder_t* p_dec, block_t** pp_block)
+static void* DecodeBlock(decoder_t* p_dec, block_t* p_block)
{
decoder_sys_t* p_sys = p_dec->p_sys;
- if (!pp_block || !*pp_block) return NULL;
-
/* Check for headers */
if (!p_sys->b_has_headers) {
if (ProcessHeader(p_dec)) {
- block_Release(*pp_block);
+ block_Release(p_block);
return NULL;
}
p_sys->b_has_headers = true;
}
- return ProcessPacket(p_dec, pp_block);
+ return ProcessPacket(p_dec, p_block);
+}
+
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ picture_t *p_pic = DecodeBlock( p_dec, p_block );
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+ return DecodeBlock( p_dec, p_block );
}
/*****************************************************************************
@@ -277,17 +295,11 @@ static void Flush(decoder_t* p_dec)
/*****************************************************************************
* ProcessPacket: processes an OggSpots packet.
*****************************************************************************/
-static void* ProcessPacket(decoder_t* p_dec, block_t** pp_block)
+static void* ProcessPacket(decoder_t* p_dec, block_t* p_block)
{
decoder_sys_t* p_sys = p_dec->p_sys;
- block_t* p_block = *pp_block;
void* p_buf;
- *pp_block = NULL; /* To avoid being fed the same packet again */
-
- if (!p_block)
- return NULL;
-
if ( (p_block->i_flags & BLOCK_FLAG_DISCONTINUITY) != 0 ) {
p_sys->i_pts = p_block->i_pts;
}
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index a0879d771e..c42f9a1acb 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -61,7 +61,7 @@ struct csd
#define DECODE_FLAG_RESTART (0x01)
#define DECODE_FLASH_FLUSH (0x02)
/**
- * Callback called when a new block is processed from DecodeCommon.
+ * Callback called when a new block is processed from DecodeBlock.
* It returns -1 in case of error, 0 if block should be dropped, 1 otherwise.
*/
typedef int (*dec_on_new_block_cb)(decoder_t *, block_t **);
@@ -72,7 +72,7 @@ typedef int (*dec_on_new_block_cb)(decoder_t *, block_t **);
typedef void (*dec_on_flush_cb)(decoder_t *);
/**
- * Callback called when DecodeCommon try to get an output buffer (pic or block).
+ * Callback called when DecodeBlock try to get an output buffer (pic or block).
* It returns -1 in case of error, or the number of output buffer returned.
*/
typedef int (*dec_process_output_cb)(decoder_t *, mc_api_out *, picture_t **,
@@ -82,7 +82,7 @@ struct decoder_sys_t
{
mc_api api;
- /* Codec Specific Data buffer: sent in DecodeCommon after a start or a flush
+ /* Codec Specific Data buffer: sent in DecodeBlock after a start or a flush
* with the BUFFER_FLAG_CODEC_CONFIG flag.*/
block_t **pp_csd;
size_t i_csd_count;
@@ -154,13 +154,12 @@ static int VideoVC1_OnNewBlock(decoder_t *, block_t **);
static void Video_OnFlush(decoder_t *);
static int Video_ProcessOutput(decoder_t *, mc_api_out *, picture_t **,
block_t **);
-static picture_t *DecodeVideo(decoder_t *, block_t **);
+static int DecodeBlock(decoder_t *, block_t *);
static int Audio_OnNewBlock(decoder_t *, block_t **);
static void Audio_OnFlush(decoder_t *);
static int Audio_ProcessOutput(decoder_t *, mc_api_out *, picture_t **,
block_t **);
-static block_t *DecodeAudio(decoder_t *, block_t **);
static void DecodeFlushLocked(decoder_t *);
static void DecodeFlush(decoder_t *);
@@ -219,7 +218,7 @@ static void CSDFree(decoder_t *p_dec)
p_sys->i_csd_count = 0;
}
-/* Create the p_sys->p_csd that will be sent from DecodeCommon */
+/* Create the p_sys->p_csd that will be sent from DecodeBlock */
static int CSDDup(decoder_t *p_dec, const struct csd *p_csd, size_t i_count)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -844,9 +843,8 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
goto bailout;
}
- p_dec->pf_decode_video = DecodeVideo;
- p_dec->pf_decode_audio = DecodeAudio;
- p_dec->pf_flush = DecodeFlush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = DecodeFlush;
return VLC_SUCCESS;
@@ -1354,39 +1352,31 @@ static block_t *GetNextBlock(decoder_sys_t *p_sys, block_t *p_block)
return p_block;
}
-/**
- * DecodeCommon called from DecodeVideo or DecodeAudio.
- * It returns -1 in case of error, 0 otherwise.
- */
-static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
+static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
int i_ret;
bool b_dequeue_timeout = false;
bool b_draining;
- if (pp_block != NULL && *pp_block == NULL)
- return 0;
-
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_aborted)
goto end;
- if (pp_block != NULL)
+ if (p_in_block != NULL)
{
- block_t *p_block = *pp_block;
b_draining = false;
- if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
+ if (p_in_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
{
DecodeFlushLocked(p_dec);
if (p_sys->b_aborted)
goto end;
- if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
+ if (p_in_block->i_flags & BLOCK_FLAG_CORRUPTED)
goto end;
}
- if (p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
+ if (p_in_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
&& !(p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED))
{
/* Before Android 21 and depending on the vendor, MediaCodec can
@@ -1398,7 +1388,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
}
/* Parse input block */
- if ((i_ret = p_sys->pf_on_new_block(p_dec, pp_block)) != 1)
+ if ((i_ret = p_sys->pf_on_new_block(p_dec, &p_in_block)) != 1)
{
if (i_ret != 0)
{
@@ -1423,7 +1413,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
if (p_sys->i_decode_flags & (DECODE_FLASH_FLUSH|DECODE_FLAG_RESTART))
{
- msg_Warn(p_dec, "Flushing from DecodeCommon");
+ msg_Warn(p_dec, "Flushing from DecodeBlock");
const bool b_restart = p_sys->i_decode_flags & DECODE_FLAG_RESTART;
p_sys->i_decode_flags = 0;
@@ -1448,7 +1438,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
switch (i_ret)
{
case VLC_SUCCESS:
- msg_Warn(p_dec, "Restarted from DecodeCommon");
+ msg_Warn(p_dec, "Restarted from DecodeBlock");
break;
case VLC_ENOOBJ:
break;
@@ -1466,7 +1456,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
/* Queue CSD blocks and input blocks */
block_t *p_block = NULL;
- while (b_draining || (p_block = GetNextBlock(p_sys, *pp_block)))
+ while (b_draining || (p_block = GetNextBlock(p_sys, p_in_block)))
{
int i_index;
@@ -1516,9 +1506,9 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
p_sys->b_output_ready = true;
vlc_cond_broadcast(&p_sys->cond);
- assert(p_block == *pp_block),
- block_Release(p_block);
- *pp_block = NULL;
+ assert(p_block == p_in_block),
+ block_Release(p_in_block);
+ p_in_block = NULL;
}
b_dequeue_timeout = false;
if (b_draining)
@@ -1537,7 +1527,7 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
* Vout is paused and when the Decoder is flushing. In that case,
* the Vout won't release any output buffers, therefore MediaCodec
* won't dequeue any input buffers. To work around this issue,
- * release all output buffers if DecodeCommon is waiting more than
+ * release all output buffers if DecodeBlock is waiting more than
* 1sec for a new input buffer. */
if (!b_dequeue_timeout)
{
@@ -1576,15 +1566,12 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block)
msg_Err(p_dec, "OutThread timed out");
vlc_mutex_unlock(&p_sys->lock);
- return 0;
+ return VLCDEC_SUCCESS;
}
end:
- if (pp_block && *pp_block)
- {
- block_Release(*pp_block);
- *pp_block = NULL;
- }
+ if (p_in_block)
+ block_Release(p_in_block);
if (p_sys->b_aborted)
{
if (!p_sys->b_has_format)
@@ -1598,12 +1585,12 @@ end:
else
p_dec->b_error = true;
vlc_mutex_unlock(&p_sys->lock);
- return -1;
+ return VLCDEC_SUCCESS;
}
else
{
vlc_mutex_unlock(&p_sys->lock);
- return 0;
+ return VLCDEC_SUCCESS;
}
}
@@ -1693,12 +1680,6 @@ static void Video_OnFlush(decoder_t *p_dec)
InvalidateAllPictures(p_dec);
}
-static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
-{
- DecodeCommon(p_dec, pp_block);
- return NULL;
-}
-
static int Audio_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -1721,9 +1702,3 @@ static void Audio_OnFlush(decoder_t *p_dec)
date_Set(&p_sys->audio.i_end_date, VLC_TS_INVALID);
}
-
-static block_t *DecodeAudio(decoder_t *p_dec, block_t **pp_block)
-{
- DecodeCommon(p_dec, pp_block);
- return NULL;
-}
diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index 8cc18d3005..2ae9bb1874 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -77,8 +77,8 @@ static int OpenEncoder( vlc_object_t * );
static int OpenGeneric( vlc_object_t *, bool b_encode );
static void CloseGeneric( vlc_object_t * );
-static picture_t *DecodeVideo( decoder_t *, block_t ** );
-static block_t *DecodeAudio ( decoder_t *, block_t ** );
+static int DecodeVideo( decoder_t *, block_t * );
+static int DecodeAudio ( decoder_t *, block_t * );
static block_t *EncodeVideo( encoder_t *, picture_t * );
static void Flush( decoder_t * );
@@ -1019,8 +1019,12 @@ static int OpenDecoder( vlc_object_t *p_this )
status = OpenGeneric( p_this, false );
if(status != VLC_SUCCESS) return status;
- p_dec->pf_decode_video = DecodeVideo;
- p_dec->pf_decode_audio = DecodeAudio;
+ switch( p_dec->fmt_in.i_cat )
+ {
+ case AUDIO_ES: p_dec->pf_decode = DecodeAudio; break;
+ case VIDEO_ES: p_dec->pf_decode = DecodeVideo; break;
+ default: vlc_assert_unreachable();
+ }
p_dec->pf_flush = Flush;
return VLC_SUCCESS;
@@ -1538,32 +1542,28 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* DecodeVideo: Called to decode one frame
*****************************************************************************/
-static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- picture_t *p_pic = NULL;
OMX_ERRORTYPE omx_error;
unsigned int i;
- block_t *p_block;
-
- if( !pp_block || !*pp_block )
- return NULL;
- p_block = *pp_block;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
/* Check for errors from codec */
if(p_sys->b_error)
{
msg_Dbg(p_dec, "error during decoding");
block_Release( p_block );
- return 0;
+ return VLCDEC_SUCCESS;
}
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
block_Release( p_block );
Flush( p_dec );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Use the aspect ratio provided by the input (ie read from packetizer).
@@ -1579,22 +1579,19 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den;
}
- /* Take care of decoded frames first */
- if( DecodeVideoOutput( p_dec, &p_sys->out, &p_pic ) != 0 )
- goto error;
-
/* Loop as long as we haven't either got an input buffer (and cleared
* *pp_block) or got an output picture */
int max_polling_attempts = 100;
int attempts = 0;
- while( *pp_block && !p_pic ) {
+ while( p_block ) {
bool b_reconfig = false;
- if( DecodeVideoInput( p_dec, &p_sys->in, pp_block, 0, &b_reconfig ) != 0 )
+ if( DecodeVideoInput( p_dec, &p_sys->in, &p_block, 0, &b_reconfig ) != 0 )
goto error;
+ picture_t *p_pic = NULL;
/* If we don't have a p_pic from the first try. Try again */
- if( !b_reconfig && !p_pic &&
+ if( !b_reconfig &&
DecodeVideoOutput( p_dec, &p_sys->out, &p_pic ) != 0 )
goto error;
@@ -1616,6 +1613,11 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
}
}
+ if( p_pic != NULL )
+ {
+ decoder_QueueVideo( p_dec, p_pic );
+ continue;
+ }
attempts++;
/* With opaque DR the output buffers are released by the
vout therefore we implement a timeout for polling in
@@ -1631,46 +1633,44 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
picture_sys_t *p_picsys = invalid_picture->p_sys;
p_picsys->hw.p_dec = NULL;
p_picsys->hw.i_index = -1;
+ return VLCDEC_SUCCESS;
} else {
/* If we cannot return a picture we must free the
block since the decoder will proceed with the
next block. */
block_Release(p_block);
- *pp_block = NULL;
+ p_block = NULL;
+ return VLCDEC_SUCCESS;
}
- return invalid_picture;
#endif
}
}
- return p_pic;
+ return VLCDEC_SUCCESS;
error:
p_sys->b_error = true;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
* DecodeAudio: Called to decode one frame
*****************************************************************************/
-block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
+int DecodeAudio ( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_buffer = NULL;
OMX_BUFFERHEADERTYPE *p_header;
OMX_ERRORTYPE omx_error;
- block_t *p_block;
unsigned int i;
- if( !pp_block || !*pp_block ) return NULL;
-
- p_block = *pp_block;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
/* Check for errors from codec */
if(p_sys->b_error)
{
msg_Dbg(p_dec, "error during decoding");
block_Release( p_block );
- return 0;
+ return VLCDEC_SUCCESS;
}
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
@@ -1684,7 +1684,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
p_sys->in.definition.nPortIndex, 0 );
}
p_sys->in.b_flushed = true;
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( !date_Get( &p_sys->end_date ) )
@@ -1693,13 +1693,13 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
date_Set( &p_sys->end_date, p_block->i_pts );
}
/* Take care of decoded frames first */
- while(!p_buffer)
+ while (p_block != NULL)
{
unsigned int i_samples = 0;
@@ -1712,7 +1712,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
{
if( decoder_UpdateAudioFormat( p_dec ) )
break;
- p_buffer = decoder_NewAudioBuffer( p_dec, i_samples );
+ block_t *p_buffer = decoder_NewAudioBuffer( p_dec, i_samples );
if( !p_buffer ) break; /* No audio buffer available */
memcpy( p_buffer->p_buffer, p_header->pBuffer, p_buffer->i_buffer );
@@ -1726,25 +1726,25 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
p_buffer->i_pts = date_Get( &p_sys->end_date );
p_buffer->i_length = date_Increment( &p_sys->end_date, i_samples ) -
p_buffer->i_pts;
+ decoder_QueueAudio( p_dec, p_buffer );
}
OMX_DBG( "FillThisBuffer %p, %p", (void *)p_header,
(void *)p_header->pBuffer );
OMX_FIFO_GET(&p_sys->out.fifo, p_header);
OMX_FillThisBuffer(p_sys->omx_handle, p_header);
- }
+ /* Send the input buffer to the component */
+ OMX_FIFO_GET_TIMEOUT(&p_sys->in.fifo, p_header, 200000);
- /* Send the input buffer to the component */
- OMX_FIFO_GET_TIMEOUT(&p_sys->in.fifo, p_header, 200000);
+ if (p_header && p_header->nFlags & SENTINEL_FLAG) {
+ free(p_header);
+ goto reconfig;
+ }
- if (p_header && p_header->nFlags & SENTINEL_FLAG) {
- free(p_header);
- goto reconfig;
- }
+ if (!p_header)
+ continue;
- if(p_header)
- {
p_header->nFilledLen = p_block->i_buffer;
p_header->nOffset = 0;
p_header->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
@@ -1775,7 +1775,7 @@ block_t *DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
(void *)p_header->pBuffer, (unsigned)p_header->nFilledLen );
OMX_EmptyThisBuffer(p_sys->omx_handle, p_header);
p_sys->in.b_flushed = false;
- *pp_block = NULL; /* Avoid being fed the same packet again */
+ p_block = NULL;
}
reconfig:
@@ -1789,10 +1789,10 @@ reconfig:
CHECK_ERROR(omx_error, "PortReconfigure failed");
}
- return p_buffer;
+ return VLCDEC_SUCCESS;
error:
p_sys->b_error = true;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/opus.c b/modules/codec/opus.c
index e7e238427f..68c479ca07 100644
--- a/modules/codec/opus.c
+++ b/modules/codec/opus.c
@@ -154,11 +154,12 @@ static const uint32_t pi_3channels_in[] =
* Local prototypes
****************************************************************************/
-static block_t *DecodeBlock ( decoder_t *, block_t ** );
+static block_t *Packetize ( decoder_t *, block_t ** );
+static int DecodeAudio ( decoder_t *, block_t * );
static void Flush( decoder_t * );
static int ProcessHeaders( decoder_t * );
static int ProcessInitialHeader ( decoder_t *, ogg_packet * );
-static void *ProcessPacket( decoder_t *, ogg_packet *, block_t ** );
+static block_t *ProcessPacket( decoder_t *, ogg_packet *, block_t * );
static block_t *DecodePacket( decoder_t *, ogg_packet *, int, int );
@@ -184,9 +185,9 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_cat = AUDIO_ES;
p_dec->fmt_out.i_codec = VLC_CODEC_FL32;
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_packetize = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeAudio;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
p_sys->p_st = NULL;
@@ -198,17 +199,14 @@ static int OpenDecoder( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static block_t *DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
- if( !pp_block || !*pp_block)
- return NULL;
-
/* Block to Ogg packet */
- oggpacket.packet = (*pp_block)->p_buffer;
- oggpacket.bytes = (*pp_block)->i_buffer;
+ oggpacket.packet = p_block->p_buffer;
+ oggpacket.bytes = p_block->i_buffer;
oggpacket.granulepos = -1;
oggpacket.b_o_s = 0;
@@ -220,13 +218,34 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
if( ProcessHeaders( p_dec ) )
{
- block_Release( *pp_block );
+ block_Release( p_block );
return NULL;
}
p_sys->b_has_headers = true;
}
- return ProcessPacket( p_dec, &oggpacket, pp_block );
+ return ProcessPacket( p_dec, &oggpacket, p_block );
+}
+
+static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ p_block = DecodeBlock( p_dec, p_block );
+ if( p_block != NULL )
+ decoder_QueueAudio( p_dec, p_block );
+ return VLCDEC_SUCCESS;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+ return DecodeBlock( p_dec, p_block );
}
/*****************************************************************************
@@ -374,15 +393,10 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* ProcessPacket: processes a Opus packet.
*****************************************************************************/
-static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- block_t **pp_block )
+static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block = *pp_block;
- *pp_block = NULL; /* To avoid being fed the same packet again */
-
- if( !p_block )
- return NULL;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
diff --git a/modules/codec/png.c b/modules/codec/png.c
index 39f8b79435..dc91b775b5 100644
--- a/modules/codec/png.c
+++ b/modules/codec/png.c
@@ -66,7 +66,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 * );
/*
* png encoder descriptor
@@ -127,7 +127,7 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_RGBA;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
return VLC_SUCCESS;
}
@@ -186,10 +186,9 @@ static void user_warning( png_structp p_png, png_const_charp warning_msg )
****************************************************************************
* 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;
png_uint_32 i_width, i_height;
@@ -200,38 +199,38 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
png_infop p_info, p_end_info;
png_bytep *volatile p_row_pointers = NULL;
- if( !pp_block || !*pp_block ) return NULL;
+ if( !p_block ) /* No Drain */
+ return VLCDEC_SUCCESS;
- p_block = *pp_block;
p_sys->b_error = false;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
p_png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
if( p_png == NULL )
{
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
p_info = png_create_info_struct( p_png );
if( p_info == NULL )
{
png_destroy_read_struct( &p_png, NULL, NULL );
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
p_end_info = png_create_info_struct( p_png );
if( p_end_info == NULL )
{
png_destroy_read_struct( &p_png, &p_info, NULL );
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
/* libpng longjmp's there in case of error */
@@ -298,15 +297,16 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_pic->date = p_block->i_pts > VLC_TS_INVALID ? p_block->i_pts : p_block->i_dts;
- block_Release( p_block ); *pp_block = NULL;
- return p_pic;
+ block_Release( p_block );
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
error:
free( p_row_pointers );
png_destroy_read_struct( &p_png, &p_info, &p_end_info );
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/rawvideo.c b/modules/codec/rawvideo.c
index fabc4820c8..09ef1ba40c 100644
--- a/modules/codec/rawvideo.c
+++ b/modules/codec/rawvideo.c
@@ -144,15 +144,10 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* This function must be fed with complete frames.
****************************************************************************/
-static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static block_t *DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- if( pp_block == NULL || *pp_block == NULL )
- return NULL;
-
- block_t *p_block = *pp_block;
-
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
date_Set( &p_sys->pts, p_block->i_dts );
@@ -187,7 +182,6 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return NULL;
}
- *pp_block = NULL;
return p_block;
}
@@ -218,11 +212,14 @@ static void FillPicture( decoder_t *p_dec, block_t *p_block, picture_t *p_pic )
/*****************************************************************************
* DecodeFrame: decodes a video frame.
*****************************************************************************/
-static picture_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
+static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
{
- block_t *p_block = DecodeBlock( p_dec, pp_block );
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ p_block = DecodeBlock( p_dec, p_block );
if( p_block == NULL )
- return NULL;
+ return VLCDEC_SUCCESS;
decoder_sys_t *p_sys = p_dec->p_sys;
@@ -233,7 +230,7 @@ static picture_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
if( p_pic == NULL )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
FillPicture( p_dec, p_block, p_pic );
@@ -255,7 +252,8 @@ static picture_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
p_pic->b_progressive = true;
block_Release( p_block );
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
static int OpenDecoder( vlc_object_t *p_this )
@@ -265,8 +263,8 @@ static int OpenDecoder( vlc_object_t *p_this )
int ret = OpenCommon( p_dec );
if( ret == VLC_SUCCESS )
{
- p_dec->pf_decode_video = DecodeFrame;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeFrame;
+ p_dec->pf_flush = Flush;
}
return ret;
}
@@ -276,7 +274,15 @@ static int OpenDecoder( vlc_object_t *p_this )
*****************************************************************************/
static block_t *SendFrame( decoder_t *p_dec, block_t **pp_block )
{
- block_t *p_block = DecodeBlock( p_dec, pp_block );
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+
+ block_t *p_block = *pp_block;
+ if( p_block == NULL )
+ return NULL;
+ *pp_block = NULL;
+
+ p_block = DecodeBlock( p_dec, p_block );
if( p_block == NULL )
return NULL;
diff --git a/modules/codec/schroedinger.c b/modules/codec/schroedinger.c
index 9febc22c11..77d8ae509e 100644
--- a/modules/codec/schroedinger.c
+++ b/modules/codec/schroedinger.c
@@ -524,7 +524,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static picture_t *DecodeBlock ( decoder_t *p_dec, block_t **pp_block );
+static int DecodeBlock ( decoder_t *p_dec, block_t *p_block );
static void Flush( decoder_t * );
struct picture_free_t
@@ -588,8 +588,8 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_I420;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -758,20 +758,14 @@ static void Flush( decoder_t *p_dec )
****************************************************************************
* Blocks need not be Dirac dataunit aligned.
* If a block has a PTS signaled, it applies to the first picture at or after p_block
- *
- * If this function returns a picture (!NULL), it is called again and the
- * same block is resubmitted. To avoid this, set *pp_block to NULL;
- * If this function returns NULL, the *pp_block is lost (and leaked).
- * This function must free all blocks when finished with them.
****************************************************************************/
-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;
- if( !pp_block ) return NULL;
-
- if ( *pp_block ) {
- block_t *p_block = *pp_block;
+ if( !p_block ) /* No Drain */
+ return VLCDEC_SUCCESS;
+ else {
/* reset the decoder when seeking as the decode in progress is invalid */
/* discard the block as it is just a null magic block */
@@ -779,8 +773,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
Flush( p_dec );
block_Release( p_block );
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
SchroBuffer *p_schrobuffer;
@@ -798,7 +791,6 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/* this stops the same block being fed back into this function if
* we were on the next iteration of this loop to output a picture */
- *pp_block = NULL;
schro_decoder_autoparse_push( p_sys->p_schro, p_schrobuffer );
/* DO NOT refer to p_block after this point, it may have been freed */
}
@@ -816,7 +808,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
break;
case SCHRO_DECODER_NEED_BITS:
- return NULL;
+ return VLCDEC_SUCCESS;
case SCHRO_DECODER_NEED_FRAME:
p_schroframe = CreateSchroFrameFromPic( p_dec );
@@ -824,7 +816,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( !p_schroframe )
{
msg_Err( p_dec, "Could not allocate picture for decoder");
- return NULL;
+ return VLCDEC_SUCCESS;
}
schro_decoder_add_output_picture( p_sys->p_schro, p_schroframe);
@@ -862,7 +854,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->i_lastpts = p_pic->date;
schro_frame_unref( p_schroframe );
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
case SCHRO_DECODER_EOS:
/* NB, the new api will not emit _EOS, it handles the reset internally */
@@ -870,7 +863,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
case SCHRO_DECODER_ERROR:
msg_Err( p_dec, "SCHRO_DECODER_ERROR");
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
}
diff --git a/modules/codec/scte18.c b/modules/codec/scte18.c
index 79954a8a92..2be6c9996e 100644
--- a/modules/codec/scte18.c
+++ b/modules/codec/scte18.c
@@ -169,12 +169,11 @@ error:
return NULL;
}
-static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
+static int Decode( decoder_t *p_dec, block_t *p_block )
{
- if ( pp_block == NULL || *pp_block == NULL )
- return NULL;
- block_t *p_block = *pp_block; *pp_block = NULL;
- subpicture_t *p_spu = NULL;
+ if ( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+ subpicture_t *p_spu = NULL;
if (p_block->i_flags & (BLOCK_FLAG_CORRUPTED))
goto exit;
@@ -213,7 +212,9 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
exit:
block_Release( p_block );
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
static int Open( vlc_object_t *object )
@@ -235,7 +236,7 @@ static int Open( vlc_object_t *object )
}
dec->p_sys = p_sys;
- dec->pf_decode_sub = Decode;
+ dec->pf_decode = Decode;
es_format_Init( &dec->fmt_out, SPU_ES, 0 );
return VLC_SUCCESS;
diff --git a/modules/codec/scte27.c b/modules/codec/scte27.c
index 03b7b2def7..bd959793c1 100644
--- a/modules/codec/scte27.c
+++ b/modules/codec/scte27.c
@@ -405,13 +405,12 @@ error:
return NULL;
}
-static subpicture_t *Decode(decoder_t *dec, block_t **block)
+static int Decode(decoder_t *dec, block_t *b)
{
decoder_sys_t *sys = dec->p_sys;
- if (block == NULL || *block == NULL)
- return NULL;
- block_t *b = *block; *block = NULL;
+ if (b == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
subpicture_t *sub_first = NULL;
subpicture_t **sub_last = &sub_first;
@@ -490,7 +489,9 @@ static subpicture_t *Decode(decoder_t *dec, block_t **block)
exit:
block_Release(b);
- return sub_first;
+ if (sub_first != NULL)
+ decoder_QueueSub(dec, sub_first );
+ return VLCDEC_SUCCESS;
}
static int Open(vlc_object_t *object)
@@ -507,7 +508,7 @@ static int Open(vlc_object_t *object)
sys->segment_size = 0;
sys->segment_buffer = NULL;
- dec->pf_decode_sub = Decode;
+ dec->pf_decode = Decode;
es_format_Init(&dec->fmt_out, SPU_ES, VLC_CODEC_SPU);
dec->fmt_out.video.i_chroma = VLC_CODEC_YUVP;
diff --git a/modules/codec/sdl_image.c b/modules/codec/sdl_image.c
index 40cce2c434..de7999ccec 100644
--- a/modules/codec/sdl_image.c
+++ b/modules/codec/sdl_image.c
@@ -49,7 +49,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
@@ -116,7 +116,7 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_RGB32;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
return VLC_SUCCESS;
}
@@ -126,21 +126,20 @@ 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 = NULL;
SDL_Surface *p_surface;
SDL_RWops *p_rw;
- 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 ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
p_rw = SDL_RWFromConstMem( p_block->p_buffer, p_block->i_buffer );
@@ -261,14 +260,12 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_pic->date = (p_block->i_pts > VLC_TS_INVALID) ?
p_block->i_pts : p_block->i_dts;
- SDL_FreeSurface( p_surface );
- block_Release( p_block ); *pp_block = NULL;
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
error:
if ( p_surface != NULL ) SDL_FreeSurface( p_surface );
- block_Release( p_block ); *pp_block = NULL;
- return NULL;
+ block_Release( p_block );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/spdif.c b/modules/codec/spdif.c
index 4fff770fc8..25e7c5616b 100644
--- a/modules/codec/spdif.c
+++ b/modules/codec/spdif.c
@@ -38,18 +38,12 @@ vlc_module_begin()
set_callbacks(OpenDecoder, NULL)
vlc_module_end()
-static block_t *
-DecodeBlock(decoder_t *p_dec, block_t **pp_block)
+static int
+DecodeBlock(decoder_t *p_dec, block_t *p_block)
{
- (void) p_dec;
- if (pp_block != NULL)
- {
- block_t *p_block = *pp_block;
- *pp_block = NULL;
- return p_block;
- }
- else
- return NULL;
+ if (p_block != NULL)
+ decoder_QueueAudio( p_dec, p_block );
+ return VLCDEC_SUCCESS;
}
static int
@@ -91,8 +85,8 @@ OpenDecoder(vlc_object_t *p_this)
return VLC_EGENERIC;
}
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_flush = NULL;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = NULL;
return VLC_SUCCESS;
}
diff --git a/modules/codec/speex.c b/modules/codec/speex.c
index a3acad750d..dcea9a8de0 100644
--- a/modules/codec/speex.c
+++ b/modules/codec/speex.c
@@ -189,11 +189,12 @@ static const int pi_channels_maps[6] =
* Local prototypes
****************************************************************************/
-static block_t *DecodeBlock ( decoder_t *, block_t ** );
-static block_t *DecodeRtpSpeexPacket( decoder_t *, block_t **);
-static int ProcessHeaders( decoder_t * );
-static int ProcessInitialHeader ( decoder_t *, ogg_packet * );
-static void *ProcessPacket( decoder_t *, ogg_packet *, block_t ** );
+static block_t *Packetize ( decoder_t *, block_t ** );
+static int DecodeAudio ( decoder_t *, block_t * );
+static int DecodeRtpSpeexPacket( decoder_t *, block_t *);
+static int ProcessHeaders( decoder_t * );
+static int ProcessInitialHeader ( decoder_t *, ogg_packet * );
+static block_t *ProcessPacket( decoder_t *, ogg_packet *, block_t ** );
static void Flush( decoder_t * );
static block_t *DecodePacket( decoder_t *, ogg_packet * );
@@ -236,13 +237,13 @@ static int OpenDecoder( vlc_object_t *p_this )
{
msg_Dbg( p_dec, "Using RTP version of Speex decoder @ rate %d.",
p_dec->fmt_in.audio.i_rate );
- p_dec->pf_decode_audio = DecodeRtpSpeexPacket;
+ p_dec->pf_decode = DecodeRtpSpeexPacket;
}
else
{
- p_dec->pf_decode_audio = DecodeBlock;
+ p_dec->pf_decode = DecodeAudio;
}
- p_dec->pf_packetize = DecodeBlock;
+ p_dec->pf_packetize = Packetize;
p_dec->pf_flush = Flush;
p_sys->p_state = NULL;
@@ -335,8 +336,6 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
- if( !pp_block ) return NULL;
-
block_t *block = *pp_block;
if( block != NULL )
@@ -385,6 +384,24 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return ProcessPacket( p_dec, &oggpacket, pp_block );
}
+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;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ return DecodeBlock( p_dec, pp_block );
+}
+
/*****************************************************************************
* ProcessHeaders: process Speex headers.
*****************************************************************************/
@@ -545,8 +562,8 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* ProcessPacket: processes a Speex packet.
*****************************************************************************/
-static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- block_t **pp_block )
+static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block = *pp_block;
@@ -651,16 +668,15 @@ static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
}
}
-static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
+static int DecodeRtpSpeexPacket( decoder_t *p_dec, block_t *p_speex_bit_block )
{
- block_t *p_speex_bit_block = *pp_block;
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_aout_buffer;
int i_decode_ret;
unsigned int i_speex_frame_size;
if ( !p_speex_bit_block || p_speex_bit_block->i_pts <= VLC_TS_INVALID )
- return NULL;
+ return VLCDEC_SUCCESS;
/*
If the SpeexBits buffer size is 0 (a default value),
@@ -672,7 +688,7 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
if ( !p_sys->p_header )
{
msg_Err( p_dec, "Could not allocate a Speex header.");
- return NULL;
+ return VLCDEC_SUCCESS;
}
const SpeexMode *mode = speex_lib_get_mode((p_sys->rtp_rate / 8000) >> 1);
@@ -684,7 +700,7 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
{
msg_Err( p_dec, "Could not allocate a Speex decoder." );
free( p_sys->p_header );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*
@@ -707,7 +723,7 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
msg_Err( p_dec, "Could not determine the frame size." );
speex_decoder_destroy( p_sys->p_state );
free( p_sys->p_header );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_dec->fmt_out.audio.i_bytes_per_frame = i_speex_frame_size;
@@ -721,9 +737,8 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
if ( !p_sys->p_header )
{
msg_Err( p_dec, "There is no valid Speex header found." );
- return NULL;
+ return VLCDEC_SUCCESS;
}
- *pp_block = NULL;
if ( !date_Get( &p_sys->end_date ) )
date_Set( &p_sys->end_date, p_speex_bit_block->i_dts );
@@ -740,7 +755,7 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
if ( !p_aout_buffer || p_aout_buffer->i_buffer == 0 )
{
msg_Err(p_dec, "Oops: No new buffer was returned!");
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*
@@ -759,7 +774,7 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
if ( i_decode_ret < 0 )
{
msg_Err( p_dec, "Decoding failed. Perhaps we have a bad stream?" );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/*
@@ -772,8 +787,8 @@ static block_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block )
p_sys->i_frame_in_packet++;
block_Release( p_speex_bit_block );
-
- return p_aout_buffer;
+ decoder_QueueAudio( p_dec, p_aout_buffer );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/spudec/spudec.c b/modules/codec/spudec/spudec.c
index 4179e95c45..ae2a739f17 100644
--- a/modules/codec/spudec/spudec.c
+++ b/modules/codec/spudec/spudec.c
@@ -65,8 +65,8 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static block_t * Reassemble( decoder_t *, block_t ** );
-static subpicture_t * Decode ( decoder_t *, block_t ** );
+static block_t * Reassemble( decoder_t *, block_t * );
+static int Decode ( decoder_t *, block_t * );
static block_t * Packetize ( decoder_t *, block_t ** );
/*****************************************************************************
@@ -93,8 +93,8 @@ static int DecoderOpen( vlc_object_t *p_this )
es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_CODEC_SPU );
- p_dec->pf_decode_sub = Decode;
- p_dec->pf_packetize = NULL;
+ p_dec->pf_decode = Decode;
+ p_dec->pf_packetize = NULL;
return VLC_SUCCESS;
}
@@ -140,17 +140,19 @@ 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_spu_block;
subpicture_t *p_spu;
- p_spu_block = Reassemble( p_dec, pp_block );
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+ p_spu_block = Reassemble( p_dec, p_block );
if( ! p_spu_block )
{
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* FIXME: what the, we shouldn’t need to allocate 64k of buffer --sam. */
@@ -167,7 +169,9 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
p_sys->i_spu = 0;
p_sys->p_block = NULL;
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
@@ -176,7 +180,13 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_spu = Reassemble( p_dec, pp_block );
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+
+ block_t *p_spu = Reassemble( p_dec, p_block );
if( ! p_spu )
{
@@ -198,14 +208,9 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
/*****************************************************************************
* Reassemble:
*****************************************************************************/
-static block_t *Reassemble( decoder_t *p_dec, block_t **pp_block )
+static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block;
-
- if( pp_block == NULL || *pp_block == NULL ) return NULL;
- p_block = *pp_block;
- *pp_block = NULL;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
diff --git a/modules/codec/stl.c b/modules/codec/stl.c
index d51a52032e..71d89c059e 100644
--- a/modules/codec/stl.c
+++ b/modules/codec/stl.c
@@ -363,17 +363,14 @@ static void ResetGroups(decoder_sys_t *p_sys)
memset(p_sys->groups, 0, sizeof(stl_sg_t) * (STL_GROUPS_MAX + 1));
}
-static subpicture_t *Decode(decoder_t *p_dec, block_t **pp_block)
+static int Decode(decoder_t *p_dec, block_t *p_block)
{
- if (pp_block == NULL || *pp_block == NULL)
- return NULL;
+ if (p_block == NULL) /* No Drain */
+ return VLCDEC_SUCCESS;
subpicture_t *p_sub_first = NULL;
subpicture_t **pp_sub_last = &p_sub_first;
- block_t *p_block = *pp_block;
- *pp_block = NULL;
-
if(p_block->i_buffer < STL_TTI_SIZE)
p_block->i_flags |= BLOCK_FLAG_CORRUPTED;
@@ -384,7 +381,7 @@ static subpicture_t *Decode(decoder_t *p_dec, block_t **pp_block)
if(p_block->i_flags & BLOCK_FLAG_CORRUPTED)
{
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
}
}
@@ -422,7 +419,9 @@ static subpicture_t *Decode(decoder_t *p_dec, block_t **pp_block)
}
block_Release(p_block);
- return p_sub_first;
+ if (p_sub_first != NULL)
+ decoder_QueueSub(p_dec, p_sub_first);
+ return VLCDEC_SUCCESS;
}
static int ExtractCCT(const decoder_t *dec, cct_number_value_t *cct_number)
@@ -472,7 +471,7 @@ static int Open(vlc_object_t *object)
sys->groups[i].pp_segment_last = &sys->groups[i].p_segment;
dec->p_sys = sys;
- dec->pf_decode_sub = Decode;
+ dec->pf_decode = Decode;
dec->fmt_out.i_cat = SPU_ES;
dec->fmt_out.i_codec = 0;
return VLC_SUCCESS;
diff --git a/modules/codec/subsdec.c b/modules/codec/subsdec.c
index f75a152372..e407c9adbf 100644
--- a/modules/codec/subsdec.c
+++ b/modules/codec/subsdec.c
@@ -209,7 +209,7 @@ struct decoder_sys_t
};
-static subpicture_t *DecodeBlock ( decoder_t *, block_t ** );
+static int DecodeBlock ( decoder_t *, block_t * );
static subpicture_t *ParseText ( decoder_t *, block_t * );
static text_segment_t *ParseSubtitles(int *pi_align, const char * );
@@ -233,7 +233,7 @@ static int OpenDecoder( vlc_object_t *p_this )
return VLC_EGENERIC;
}
- p_dec->pf_decode_sub = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
p_dec->fmt_out.i_cat = SPU_ES;
p_dec->fmt_out.i_codec = 0;
@@ -320,27 +320,25 @@ static int OpenDecoder( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with complete subtitles units.
****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
subpicture_t *p_spu;
- block_t *p_block;
- if( !pp_block || *pp_block == NULL )
- 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 )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_spu = ParseText( p_dec, p_block );
block_Release( p_block );
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/substx3g.c b/modules/codec/substx3g.c
index cb7243aacb..79fa1030d8 100644
--- a/modules/codec/substx3g.c
+++ b/modules/codec/substx3g.c
@@ -33,8 +33,8 @@
/*****************************************************************************
* Module descriptor.
*****************************************************************************/
-static int Open ( vlc_object_t * );
-static subpicture_t *Decode( decoder_t *, block_t ** );
+static int Open ( vlc_object_t * );
+static int Decode( decoder_t *, block_t * );
vlc_module_begin ()
set_description( N_("tx3g subtitles decoder") )
@@ -59,7 +59,7 @@ static int Open( vlc_object_t *p_this )
if( p_dec->fmt_in.i_codec != VLC_CODEC_TX3G )
return VLC_EGENERIC;
- 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;
@@ -300,20 +300,18 @@ static void FontSizeConvert( const text_style_t *p_default_style, text_style_t *
/*****************************************************************************
* Decode:
*****************************************************************************/
-static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
+static int Decode( decoder_t *p_dec, block_t *p_block )
{
- block_t *p_block;
subpicture_t *p_spu = NULL;
- if( ( pp_block == NULL ) || ( *pp_block == NULL ) ) 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) ) ||
p_block->i_buffer < sizeof(uint16_t) )
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
uint8_t *p_buf = p_block->p_buffer;
@@ -327,12 +325,14 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
)
{
psz_subtitle = FromCharset( "UTF-16", p_pszstart, i_psz_bytelength );
- if ( !psz_subtitle ) return NULL;
+ if ( !psz_subtitle )
+ return VLCDEC_SUCCESS;
}
else
{
psz_subtitle = malloc( i_psz_bytelength + 1 );
- if ( !psz_subtitle ) return NULL;
+ if ( !psz_subtitle )
+ return VLCDEC_SUCCESS;
memcpy( psz_subtitle, p_pszstart, i_psz_bytelength );
psz_subtitle[ i_psz_bytelength ] = '\0';
}
@@ -352,7 +352,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
text_segment_Delete( p_segment3g->s );
free( p_segment3g );
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* Create the subpicture unit */
@@ -361,7 +361,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
text_segment_Delete( p_segment3g->s );
free( p_segment3g );
- return NULL;
+ return VLCDEC_SUCCESS;
}
subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys;
@@ -458,5 +458,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
block_Release( p_block );
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
diff --git a/modules/codec/subsusf.c b/modules/codec/subsusf.c
index 361cae3e08..8360db61b8 100644
--- a/modules/codec/subsusf.c
+++ b/modules/codec/subsusf.c
@@ -99,7 +99,7 @@ struct decoder_sys_t
int i_images;
};
-static subpicture_t *DecodeBlock ( decoder_t *, block_t ** );
+static int DecodeBlock ( decoder_t *, block_t * );
static char *CreatePlainText( char * );
static int ParseImageAttachments( decoder_t *p_dec );
@@ -126,7 +126,7 @@ static int OpenDecoder( vlc_object_t *p_this )
if( ( p_dec->p_sys = p_sys = calloc(1, sizeof(decoder_sys_t)) ) == NULL )
return VLC_ENOMEM;
- p_dec->pf_decode_sub = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
p_dec->fmt_out.i_cat = SPU_ES;
p_dec->fmt_out.i_codec = 0;
@@ -154,22 +154,19 @@ static int OpenDecoder( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with complete subtitles units.
****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
subpicture_t *p_spu;
- block_t *p_block;
- if( !pp_block || *pp_block == NULL )
- return NULL;
-
- p_block = *pp_block;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
p_spu = ParseText( p_dec, p_block );
block_Release( p_block );
- *pp_block = NULL;
-
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/svcdsub.c b/modules/codec/svcdsub.c
index 5cefa23a19..7961d94923 100644
--- a/modules/codec/svcdsub.c
+++ b/modules/codec/svcdsub.c
@@ -62,7 +62,7 @@ vlc_module_end ()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static subpicture_t *Decode( decoder_t *, block_t ** );
+static int Decode( decoder_t *, block_t * );
static block_t *Packetize ( decoder_t *, block_t ** );
static block_t *Reassemble ( decoder_t *, block_t * );
static void ParseHeader( decoder_t *, block_t * );
@@ -132,8 +132,8 @@ static int DecoderOpen( vlc_object_t *p_this )
es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_CODEC_OGT );
- p_dec->pf_decode_sub = Decode;
- p_dec->pf_packetize = Packetize;
+ p_dec->pf_decode = Decode;
+ p_dec->pf_packetize = Packetize;
return VLC_SUCCESS;
}
@@ -163,23 +163,23 @@ void DecoderClose( 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 )
{
- block_t *p_block, *p_spu;
-
#ifndef NDEBUG
msg_Dbg( p_dec, "Decode" );
#endif
- if( pp_block == NULL || *pp_block == NULL ) return NULL;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
- p_block = *pp_block;
- *pp_block = NULL;
-
- if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
+ if( !(p_block = Reassemble( p_dec, p_block )) )
+ return VLCDEC_SUCCESS;
/* Parse and decode */
- return DecodePacket( p_dec, p_spu );
+ subpicture_t *p_spu = DecodePacket( p_dec, p_block );
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/svg.c b/modules/codec/svg.c
index b2ea456df7..3da62ad9ae 100644
--- a/modules/codec/svg.c
+++ b/modules/codec/svg.c
@@ -45,7 +45,7 @@
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 * );
#define TEXT_WIDTH N_("Image width")
#define LONG_TEXT_WIDTH N_("Specify the width to decode the image too")
@@ -112,7 +112,7 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_BGRA;
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
return VLC_SUCCESS;
}
@@ -122,10 +122,9 @@ static int OpenDecoder( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with a complete image.
****************************************************************************/
-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 = (decoder_sys_t *) p_dec->p_sys;
- block_t *p_block;
picture_t *p_pic = NULL;
int32_t i_width, i_height;
@@ -133,15 +132,13 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
cairo_surface_t *surface = NULL;
cairo_t *cr = NULL;
- 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)
{
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
rsvg = rsvg_handle_new_from_data( p_block->p_buffer, p_block->i_buffer, NULL );
@@ -259,7 +256,9 @@ done:
cairo_surface_destroy( surface );
block_Release( p_block );
- return p_pic;
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/telx.c b/modules/codec/telx.c
index b0980c1b9f..07a2d7c68c 100644
--- a/modules/codec/telx.c
+++ b/modules/codec/telx.c
@@ -49,7 +49,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 OVERRIDE_PAGE_TEXT N_("Override page")
#define OVERRIDE_PAGE_LONGTEXT N_("Override the indicated page, try this if " \
@@ -179,7 +179,7 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC;
}
- p_dec->pf_decode_sub = Decode;
+ p_dec->pf_decode = Decode;
p_sys = p_dec->p_sys = calloc( 1, sizeof(*p_sys) );
if( p_sys == NULL )
return VLC_ENOMEM;
@@ -428,10 +428,9 @@ static void decode_string( char * res, int res_len,
/*****************************************************************************
* 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;
video_format_t fmt;
/* int erase = 0; */
@@ -446,10 +445,8 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
char psz_line[256];
int i, total;
- if( pp_block == NULL || *pp_block == NULL )
- return NULL;
- p_block = *pp_block;
- *pp_block = NULL;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
dbg((p_dec, "start of telx packet with header %2x\n",
* (uint8_t *) p_block->p_buffer));
@@ -712,7 +709,9 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
dbg((p_dec, "%ld --> %ld\n", (long int) p_block->i_pts/100000, (long int)p_block->i_length/100000));
block_Release( p_block );
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
error:
if ( p_spu != NULL )
@@ -722,5 +721,5 @@ error:
}
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
diff --git a/modules/codec/textst.c b/modules/codec/textst.c
index a948d1c57f..e233de7da2 100644
--- a/modules/codec/textst.c
+++ b/modules/codec/textst.c
@@ -222,41 +222,36 @@ static void textst_FillRegions(decoder_t *p_dec, const uint8_t *p_data, size_t i
}
}
-static subpicture_t *Decode(decoder_t *p_dec, block_t **pp_block)
+static int Decode(decoder_t *p_dec, block_t *p_block)
{
subpicture_t *p_sub = NULL;
- if (pp_block == NULL || *pp_block == NULL)
- return NULL;
+ if (p_block == NULL) /* No Drain */
+ return VLCDEC_SUCCESS;
- block_t *p_block = *pp_block;
- *pp_block = NULL;
-
- if(p_block)
+ if (p_block->i_buffer > 18 &&
+ (p_block->i_flags & BLOCK_FLAG_CORRUPTED) == 0 &&
+ (p_sub = decoder_NewSubpictureText(p_dec)))
{
- if(p_block->i_buffer > 18 &&
- (p_block->i_flags & BLOCK_FLAG_CORRUPTED) == 0 &&
- (p_sub = decoder_NewSubpictureText(p_dec)))
+ p_sub->i_start = ((int64_t) (p_block->p_buffer[3] & 0x01) << 32) | GetDWBE(&p_block->p_buffer[4]);
+ p_sub->i_stop = ((int64_t) (p_block->p_buffer[8] & 0x01) << 32) | GetDWBE(&p_block->p_buffer[9]);
+ p_sub->i_start = VLC_TS_0 + p_sub->i_start * 100 / 9;
+ p_sub->i_stop = VLC_TS_0 + p_sub->i_stop * 100 / 9;
+ if (p_sub->i_start < p_block->i_dts)
{
- p_sub->i_start = ((int64_t) (p_block->p_buffer[3] & 0x01) << 32) | GetDWBE(&p_block->p_buffer[4]);
- p_sub->i_stop = ((int64_t) (p_block->p_buffer[8] & 0x01) << 32) | GetDWBE(&p_block->p_buffer[9]);
- p_sub->i_start = VLC_TS_0 + p_sub->i_start * 100 / 9;
- p_sub->i_stop = VLC_TS_0 + p_sub->i_stop * 100 / 9;
- if(p_sub->i_start < p_block->i_dts)
- {
- p_sub->i_stop += p_block->i_dts - p_sub->i_start;
- p_sub->i_start = p_block->i_dts;
- }
-
- textst_FillRegions(p_dec, &p_block->p_buffer[13], p_block->i_buffer - 13,
- &p_sub->updater.p_sys->region);
-
- p_sub->b_absolute = false;
+ p_sub->i_stop += p_block->i_dts - p_sub->i_start;
+ p_sub->i_start = p_block->i_dts;
}
- block_Release(p_block);
+ textst_FillRegions(p_dec, &p_block->p_buffer[13], p_block->i_buffer - 13,
+ &p_sub->updater.p_sys->region);
+
+ p_sub->b_absolute = false;
}
- return p_sub;
+ block_Release(p_block);
+ if (p_sub != NULL)
+ decoder_QueueSub(p_dec, p_sub);
+ return VLCDEC_SUCCESS;
}
static void Close(vlc_object_t *object)
@@ -278,7 +273,7 @@ static int Open(vlc_object_t *object)
memset(p_sys->palette, 0xFF, 256 * sizeof(uint32_t));
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;
diff --git a/modules/codec/theora.c b/modules/codec/theora.c
index d50a63c2cc..8f364fe61e 100644
--- a/modules/codec/theora.c
+++ b/modules/codec/theora.c
@@ -82,9 +82,10 @@ static int OpenDecoder ( vlc_object_t * );
static int OpenPacketizer( vlc_object_t * );
static void CloseDecoder ( vlc_object_t * );
-static void *DecodeBlock ( decoder_t *, block_t ** );
+static int DecodeVideo ( decoder_t *, block_t * );
+static block_t *Packetize ( decoder_t *, block_t ** );
static int ProcessHeaders( decoder_t * );
-static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
+static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t * );
static void Flush( decoder_t * );
static picture_t *DecodePacket( decoder_t *, ogg_packet * );
@@ -169,11 +170,9 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->fmt_out.i_codec = VLC_CODEC_I420;
/* Set callbacks */
- p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
- DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeVideo;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
/* Init supporting Theora structures needed in header parsing */
th_comment_init( &p_sys->tc );
@@ -202,16 +201,11 @@ static int OpenPacketizer( vlc_object_t *p_this )
****************************************************************************
* This function must be fed with ogg packets.
****************************************************************************/
-static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static void *DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block;
ogg_packet oggpacket;
- if( !pp_block || !*pp_block ) return NULL;
-
- p_block = *pp_block;
-
/* Block to Ogg packet */
oggpacket.packet = p_block->p_buffer;
oggpacket.bytes = p_block->i_buffer;
@@ -231,7 +225,28 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->b_has_headers = true;
}
- return ProcessPacket( p_dec, &oggpacket, pp_block );
+ return ProcessPacket( p_dec, &oggpacket, p_block );
+}
+
+static int DecodeVideo( decoder_t *p_dec, block_t *p_block )
+{
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ picture_t *p_pic = DecodeBlock( p_dec, p_block );
+ if( p_pic != NULL )
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ block_t *p_block = *pp_block; *pp_block = NULL;
+ if( p_block == NULL )
+ return NULL;
+ return DecodeBlock( p_dec, p_block );
}
/*****************************************************************************
@@ -437,17 +452,11 @@ static void Flush( decoder_t *p_dec )
* ProcessPacket: processes a theora packet.
*****************************************************************************/
static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- block_t **pp_block )
+ block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
- block_t *p_block = *pp_block;
void *p_buf;
- *pp_block = NULL; /* To avoid being fed the same packet again */
-
- if( !p_block )
- return NULL;
-
if( ( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) != 0 )
p_sys->i_pts = p_block->i_pts;
diff --git a/modules/codec/ttml/substtml.c b/modules/codec/ttml/substtml.c
index b01cf0d3b6..f0e4925c64 100644
--- a/modules/codec/ttml/substtml.c
+++ b/modules/codec/ttml/substtml.c
@@ -822,18 +822,18 @@ static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block )
/****************************************************************************
* DecodeBlock: the whole thing
****************************************************************************/
-static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
- if( !pp_block || *pp_block == NULL )
- return NULL;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
- block_t* p_block = *pp_block;
subpicture_t *p_spu = ParseBlock( p_dec, p_block );
block_Release( p_block );
- *pp_block = NULL;
- return p_spu;
+ if( p_spu != NULL )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
@@ -852,7 +852,7 @@ int OpenDecoder( vlc_object_t *p_this )
if( unlikely( p_sys == NULL ) )
return VLC_ENOMEM;
- p_dec->pf_decode_sub = DecodeBlock;
+ p_dec->pf_decode = DecodeBlock;
p_dec->fmt_out.i_cat = SPU_ES;
p_sys->i_align = var_InheritInteger( p_dec, "ttml-align" );
diff --git a/modules/codec/uleaddvaudio.c b/modules/codec/uleaddvaudio.c
index c578682e3d..cc1dcb9c2a 100644
--- a/modules/codec/uleaddvaudio.c
+++ b/modules/codec/uleaddvaudio.c
@@ -61,11 +61,11 @@ static void Flush(decoder_t *dec)
date_Set(&sys->end_date, 0);
}
-static block_t *Decode(decoder_t *dec, block_t **block_ptr)
+static block_t *DecodeBlock(decoder_t *dec, block_t **block_ptr)
{
decoder_sys_t *sys = dec->p_sys;
- if (!block_ptr || !*block_ptr)
+ if (!*block_ptr)
return NULL;
block_t *block = *block_ptr;
@@ -122,6 +122,17 @@ static block_t *Decode(decoder_t *dec, block_t **block_ptr)
return NULL;
}
+static int DecodeAudio(decoder_t *dec, block_t *block)
+{
+ if (block == NULL) /* No Drain */
+ return VLCDEC_SUCCESS;
+
+ block_t **block_ptr = &block, *out;
+ while ((out = DecodeBlock(dec, block_ptr)) != NULL)
+ decoder_QueueAudio(dec,out);
+ return VLCDEC_SUCCESS;
+}
+
static int Open(vlc_object_t *object)
{
decoder_t *dec = (decoder_t*)object;
@@ -159,8 +170,8 @@ static int Open(vlc_object_t *object)
dec->fmt_out.audio.i_physical_channels =
dec->fmt_out.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
- dec->pf_decode_audio = Decode;
- dec->pf_flush = Flush;
+ dec->pf_decode = DecodeAudio;
+ dec->pf_flush = Flush;
return VLC_SUCCESS;
}
diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index 8c92d6d5bb..8c90f318c5 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -86,7 +86,7 @@ vlc_module_end()
#pragma mark - local prototypes
static CFDataRef ESDSCreate(decoder_t *, uint8_t *, uint32_t);
-static picture_t *DecodeBlock(decoder_t *, block_t **);
+static int DecodeBlock(decoder_t *, block_t *);
static void PicReorder_pushSorted(decoder_t *, picture_t *);
static picture_t *PicReorder_pop(decoder_t *, bool);
static void PicReorder_flush(decoder_t *);
@@ -752,8 +752,8 @@ static int OpenDecoder(vlc_object_t *p_this)
return i_ret;
}
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeBlock;
+ p_dec->pf_flush = Flush;
msg_Info(p_dec, "Using Video Toolbox to decode '%4.4s'", (char *)&p_dec->fmt_in.i_codec);
@@ -1028,7 +1028,7 @@ static void Flush(decoder_t *p_dec)
p_sys->b_vt_flush = p_sys->b_vt_feed;
}
-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;
@@ -1037,22 +1037,24 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
p_sys->b_vt_flush = false;
}
- if (!pp_block)
+ if (!p_block)
{
/* draining: return last pictures of the reordered queue */
if (p_sys->session)
VTDecompressionSessionWaitForAsynchronousFrames(p_sys->session);
- vlc_mutex_lock(&p_sys->lock);
- picture_t *p_pic = PicReorder_pop(p_dec, true);
- vlc_mutex_unlock(&p_sys->lock);
- return p_pic;
- }
-
- block_t *p_block = *pp_block;
- *pp_block = NULL;
+ for (;;)
+ {
+ vlc_mutex_lock(&p_sys->lock);
+ picture_t *p_pic = PicReorder_pop(p_dec, true);
+ vlc_mutex_unlock(&p_sys->lock);
- if (p_block == NULL)
- return NULL; /* no need to be called again, pics are queued asynchronously */
+ if (p_pic)
+ decoder_QueueVideo(p_dec, p_pic);
+ else
+ break;
+ }
+ return VLCDEC_SUCCESS;
+ }
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_abort) { /* abort from output thread (DecoderCallback) */
@@ -1089,7 +1091,7 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
if (p_sys->codec == kCMVideoCodecType_H264) {
p_block = H264ProcessBlock(p_dec, p_block);
if (!p_block)
- return NULL;
+ return VLCDEC_SUCCESS;
}
CMSampleBufferRef sampleBuffer =
@@ -1131,7 +1133,7 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
skip:
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
reload:
/* Add an empty variable so that videotoolbox won't be loaded again for
@@ -1141,7 +1143,7 @@ reload:
else
p_dec->b_error = true;
block_Release(p_block);
- return NULL;
+ return VLCDEC_SUCCESS;
}
static int UpdateVideoFormat(decoder_t *p_dec, CVPixelBufferRef imageBuffer)
diff --git a/modules/codec/vorbis.c b/modules/codec/vorbis.c
index 0ce0e26338..a54b0cabab 100644
--- a/modules/codec/vorbis.c
+++ b/modules/codec/vorbis.c
@@ -147,11 +147,12 @@ static const uint32_t pi_3channels_in[] =
static int OpenDecoder ( vlc_object_t * );
static int OpenPacketizer( 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 block_t *Packetize ( decoder_t *, block_t ** );
static void Flush( decoder_t * );
static int ProcessHeaders( decoder_t * );
-static void *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
+static block_t *ProcessPacket ( decoder_t *, ogg_packet *, block_t ** );
static block_t *DecodePacket( decoder_t *, ogg_packet * );
static block_t *SendPacket( decoder_t *, ogg_packet *, block_t * );
@@ -261,9 +262,9 @@ static int OpenDecoder( vlc_object_t *p_this )
#endif
/* Set callbacks */
- p_dec->pf_decode_audio = DecodeBlock;
- p_dec->pf_packetize = DecodeBlock;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeAudio;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -293,8 +294,6 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
- if( !pp_block ) return NULL;
-
if( *pp_block )
{
/* Block to Ogg packet */
@@ -330,6 +329,24 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return ProcessPacket( p_dec, &oggpacket, pp_block );
}
+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;
+}
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+ if( pp_block == NULL ) /* No Drain */
+ return NULL;
+ return DecodeBlock( p_dec, pp_block );
+}
+
/*****************************************************************************
* ProcessHeaders: process Vorbis headers.
*****************************************************************************/
@@ -445,8 +462,8 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* ProcessPacket: processes a Vorbis packet.
*****************************************************************************/
-static void *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
- block_t **pp_block )
+static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+ block_t **pp_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block = *pp_block;
diff --git a/modules/codec/vpx.c b/modules/codec/vpx.c
index 86cb262119..a0db6c86c0 100644
--- a/modules/codec/vpx.c
+++ b/modules/codec/vpx.c
@@ -159,25 +159,23 @@ static vlc_fourcc_t FindVlcChroma( struct vpx_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)
{
struct vpx_codec_ctx *ctx = &dec->p_sys->ctx;
- if( !pp_block || !*pp_block )
- return NULL;
- block_t *block = *pp_block;
+ if (block == NULL) /* 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 ? block->i_pts : block->i_dts;
@@ -186,21 +184,20 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
err = vpx_codec_decode(ctx, block->p_buffer, block->i_buffer, pkt_pts, 0);
block_Release(block);
- *pp_block = NULL;
if (err != VPX_CODEC_OK) {
free(pkt_pts);
VPX_ERR(dec, ctx, "Failed to decode frame");
if (err == VPX_CODEC_UNSUP_BITSTREAM)
dec->b_error = true;
- return NULL;
+ return VLCDEC_SUCCESS;
}
const void *iter = NULL;
struct vpx_image *img = vpx_codec_get_frame(ctx, &iter);
if (!img) {
free(pkt_pts);
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* fetches back the PTS */
@@ -212,7 +209,7 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
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;
@@ -252,10 +249,10 @@ static picture_t *Decode(decoder_t *dec, block_t **pp_block)
dec->fmt_out.video.pose = dec->fmt_in.video.pose;
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];
@@ -274,7 +271,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;
}
/*****************************************************************************
@@ -322,7 +320,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;
diff --git a/modules/codec/wmafixed/wma.c b/modules/codec/wmafixed/wma.c
index f8a8b4c813..a7abfb27cb 100644
--- a/modules/codec/wmafixed/wma.c
+++ b/modules/codec/wmafixed/wma.c
@@ -71,7 +71,7 @@ static unsigned int pi_channels_maps[7] =
static int OpenDecoder ( vlc_object_t * );
static void CloseDecoder ( vlc_object_t * );
-static block_t *DecodeFrame( decoder_t *, block_t ** );
+static int DecodeFrame( decoder_t *, block_t * );
static void Flush( decoder_t * );
/*****************************************************************************
@@ -186,8 +186,8 @@ static int OpenDecoder( vlc_object_t *p_this )
}
/* Set callback */
- p_dec->pf_decode_audio = DecodeFrame;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = DecodeFrame;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
@@ -205,15 +205,13 @@ static void Flush( decoder_t *p_dec )
/*****************************************************************************
* DecodeFrame: decodes a wma frame.
*****************************************************************************/
-static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
+static int DecodeFrame( 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 = NULL;
- if( !pp_block || !*pp_block ) return NULL;
-
- p_block = *pp_block;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
{
@@ -221,24 +219,8 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED)
{
block_Release( p_block );
- *pp_block = NULL;
- return NULL;
- }
- }
-
- if( p_block->i_buffer <= 0 )
- {
- /* we already decoded the samples, just feed a few to aout */
- if( p_sys->i_samples )
- p_aout_buffer = SplitBuffer( p_dec );
- if( !p_sys->i_samples )
- { /* we need to decode new samples now */
- free( p_sys->p_output );
- p_sys->p_output = NULL;
- block_Release( p_block );
- *pp_block = NULL;
+ return VLCDEC_SUCCESS;
}
- return p_aout_buffer;
}
/* Date management */
@@ -253,7 +235,7 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
{
/* We've just started the stream, wait for the first PTS. */
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( wma_decode_superframe_init( &p_sys->wmadec, p_block->p_buffer,
@@ -261,16 +243,14 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
{
msg_Err( p_dec, "failed initializing wmafixed decoder" );
block_Release( p_block );
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
if( p_sys->wmadec.nb_frames <= 0 )
{
msg_Err( p_dec, "can not decode, invalid ASF packet ?" );
block_Release( p_block );
- *pp_block = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
/* worst case */
@@ -283,7 +263,7 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
{
/* OOM, will try a bit later if VLC hasn't been killed */
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_sys->i_samples = 0;
@@ -302,20 +282,26 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
"wma_decode_superframe_frame() failed for frame %d", i );
free( p_sys->p_output );
p_sys->p_output = NULL;
- return NULL;
+ return VLCDEC_SUCCESS;
}
p_sys->i_samples += i_samples; /* advance in the samples buffer */
}
- p_block->i_buffer = 0; /* this block has been decoded */
+ block_Release( p_block ); /* this block has been decoded */
for( size_t s = 0 ; s < i_buffer; s++ )
p_sys->p_output[s] <<= 2; /* Q30 -> Q32 translation */
- p_aout_buffer = SplitBuffer( p_dec );
- assert( p_aout_buffer );
+ while( ( p_aout_buffer = SplitBuffer( p_dec ) ) != NULL )
+ decoder_QueueAudio( p_dec, p_aout_buffer );
+
+ if( !p_sys->i_samples )
+ { /* we need to decode new samples now */
+ free( p_sys->p_output );
+ p_sys->p_output = NULL;
+ }
- return p_aout_buffer;
+ return VLCDEC_SUCCESS;
}
/*****************************************************************************
diff --git a/modules/codec/xwd.c b/modules/codec/xwd.c
index fe8fc18426..dd3c8af7cb 100644
--- a/modules/codec/xwd.c
+++ b/modules/codec/xwd.c
@@ -40,7 +40,7 @@ vlc_module_begin()
set_callbacks(Open, NULL)
vlc_module_end()
-static picture_t *Decode(decoder_t *, block_t **);
+static int Decode(decoder_t *, block_t *);
static int Open(vlc_object_t *obj)
{
@@ -49,24 +49,19 @@ static int Open(vlc_object_t *obj)
if (dec->fmt_in.i_codec != VLC_CODEC_XWD)
return VLC_EGENERIC;
- dec->pf_decode_video = Decode;
+ dec->pf_decode = Decode;
es_format_Copy(&dec->fmt_out, &dec->fmt_in);
dec->fmt_out.i_codec = VLC_CODEC_RGB32;
dec->fmt_out.i_cat = VIDEO_ES;
return VLC_SUCCESS;
}
-static picture_t *Decode (decoder_t *dec, block_t **pp)
+static int Decode (decoder_t *dec, block_t *block)
{
picture_t *pic = NULL;
- if (pp == NULL)
- return NULL;
-
- block_t *block = *pp;
- if (block == NULL)
- return NULL;
- *pp = NULL;
+ if (block == NULL) /* No Drain */
+ return VLCDEC_SUCCESS;
if (block->i_pts <= VLC_TS_INVALID)
goto drop; /* undated block, should never happen */
@@ -153,5 +148,6 @@ static picture_t *Decode (decoder_t *dec, block_t **pp)
drop:
block_Release(block);
- return pic;
+ decoder_QueueVideo(dec, pic);
+ return VLCDEC_SUCCESS;
}
diff --git a/modules/codec/zvbi.c b/modules/codec/zvbi.c
index ff3de7f0af..430a6ba42d 100644
--- a/modules/codec/zvbi.c
+++ b/modules/codec/zvbi.c
@@ -173,7 +173,7 @@ struct decoder_sys_t
int i_key[3];
};
-static subpicture_t *Decode( decoder_t *, block_t ** );
+static int Decode( decoder_t *, block_t * );
static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt,
bool b_text,
@@ -275,7 +275,7 @@ static int Open( vlc_object_t *p_this )
else
p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBA;
- p_dec->pf_decode_sub = Decode;
+ p_dec->pf_decode = Decode;
return VLC_SUCCESS;
}
@@ -307,20 +307,16 @@ 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;
video_format_t fmt;
bool b_cached = false;
vbi_page p_page;
- if( (pp_block == NULL) || (*pp_block == NULL) )
- return NULL;
-
- p_block = *pp_block;
- *pp_block = NULL;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( p_block->i_buffer > 0 &&
( ( p_block->p_buffer[0] >= 0x10 && p_block->p_buffer[0] <= 0x1f ) ||
@@ -498,12 +494,14 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
exit:
vbi_unref_page( &p_page );
block_Release( p_block );
- return p_spu;
+ if( p_spu )
+ decoder_QueueSub( p_dec, p_spu );
+ return VLCDEC_SUCCESS;
error:
vbi_unref_page( &p_page );
block_Release( p_block );
- return NULL;
+ return VLCDEC_SUCCESS;
}
static subpicture_t *Subpicture( decoder_t *p_dec, video_format_t *p_fmt,
diff --git a/modules/hw/mmal/codec.c b/modules/hw/mmal/codec.c
index 98a001ed63..c01d1e4635 100644
--- a/modules/hw/mmal/codec.c
+++ b/modules/hw/mmal/codec.c
@@ -90,7 +90,7 @@ static int send_output_buffer(decoder_t *dec);
static void fill_output_port(decoder_t *dec);
/* VLC decoder callback */
-static picture_t *decode(decoder_t *dec, block_t **block);
+static int decode(decoder_t *dec, block_t *block);
static void flush_decoder(decoder_t *dec);
/* MMAL callbacks */
@@ -236,8 +236,8 @@ static int OpenDecoder(decoder_t *dec)
}
dec->fmt_out.i_cat = VIDEO_ES;
- dec->pf_decode_video = decode;
- dec->pf_flush = flush_decoder;
+ dec->pf_decode = decode;
+ dec->pf_flush = flush_decoder;
vlc_mutex_init_recursive(&sys->mutex);
vlc_sem_init(&sys->sem, 0);
@@ -593,16 +593,14 @@ static void flush_decoder(decoder_t *dec)
msg_Dbg(dec, "Ports flushed, returning to normal operation");
}
-static picture_t *decode(decoder_t *dec, block_t **pblock)
+static int decode(decoder_t *dec, block_t *block)
{
decoder_sys_t *sys = dec->p_sys;
- block_t *block;
MMAL_BUFFER_HEADER_T *buffer;
bool need_flush = false;
uint32_t len;
uint32_t flags = 0;
MMAL_STATUS_T status;
- picture_t *ret = NULL;
/*
* Configure output port if necessary
@@ -612,23 +610,22 @@ static picture_t *decode(decoder_t *dec, block_t **pblock)
msg_Err(dec, "Failed to change output port format");
}
- if (!pblock)
+ if (!block)
goto out;
- block = *pblock;
-
/*
* Check whether full flush is required
*/
if (block && block->i_flags & BLOCK_FLAG_DISCONTINUITY) {
flush_decoder(dec);
- block_Release(*pblock);
- return NULL;
+ block_Release(block);
+ return VLCDEC_SUCCESS;
}
/*
* Send output buffers
*/
+ picture_t *ret = NULL;
if (atomic_load(&sys->started)) {
buffer = mmal_queue_get(sys->decoded_pictures);
if (buffer) {
@@ -646,17 +643,12 @@ static picture_t *decode(decoder_t *dec, block_t **pblock)
fill_output_port(dec);
}
-
if (ret)
- goto out;
+ decoder_QueueVideo(dec, ret);
/*
* Process input
*/
- if (!block)
- goto out;
-
- *pblock = NULL;
if (block->i_flags & BLOCK_FLAG_CORRUPTED)
flags |= MMAL_BUFFER_HEADER_FLAG_CORRUPTED;
@@ -701,7 +693,7 @@ out:
if (need_flush)
flush_decoder(dec);
- return ret;
+ return VLCDEC_SUCCESS;
}
static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
diff --git a/modules/misc/stats.c b/modules/misc/stats.c
index 9a0f112457..6c3d4fdf6c 100644
--- a/modules/misc/stats.c
+++ b/modules/misc/stats.c
@@ -40,13 +40,12 @@
#include <vlc_demux.h>
/*** Decoder ***/
-static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
{
- block_t *p_block;
picture_t * p_pic = NULL;
- if( !pp_block || !*pp_block ) return NULL;
- p_block = *pp_block;
+ if( p_block == NULL ) /* No Drain */
+ return VLCDEC_SUCCESS;
if( !decoder_UpdateVideoFormat( p_dec ) )
p_pic = decoder_NewPicture( p_dec );
@@ -73,8 +72,8 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
error:
block_Release( p_block );
- *pp_block = NULL;
- return p_pic;
+ decoder_QueueVideo( p_dec, p_pic );
+ return VLCDEC_SUCCESS;
}
static int OpenDecoder ( vlc_object_t *p_this )
@@ -84,9 +83,7 @@ static int OpenDecoder ( vlc_object_t *p_this )
msg_Dbg( p_this, "opening stats decoder" );
/* Set callbacks */
- p_dec->pf_decode_video = DecodeBlock;
- p_dec->pf_decode_audio = NULL;
- p_dec->pf_decode_sub = NULL;
+ p_dec->pf_decode = DecodeBlock;
/* */
es_format_Init( &p_dec->fmt_out, VIDEO_ES, VLC_CODEC_I420 );
diff --git a/modules/packetizer/flac.c b/modules/packetizer/flac.c
index fbe161ea1d..877b4868a5 100644
--- a/modules/packetizer/flac.c
+++ b/modules/packetizer/flac.c
@@ -800,9 +800,9 @@ static int Open(vlc_object_t *p_this)
p_dec->fmt_out.i_codec = VLC_CODEC_FLAC;
/* */
- p_dec->pf_decode_audio = NULL;
- p_dec->pf_packetize = Packetize;
- p_dec->pf_flush = Flush;
+ p_dec->pf_decode = NULL;
+ p_dec->pf_packetize = Packetize;
+ p_dec->pf_flush = Flush;
return VLC_SUCCESS;
}
diff --git a/modules/stream_out/mosaic_bridge.c b/modules/stream_out/mosaic_bridge.c
index 1c313f04b6..3e87d5debb 100644
--- a/modules/stream_out/mosaic_bridge.c
+++ b/modules/stream_out/mosaic_bridge.c
@@ -77,6 +77,7 @@ static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
static void Del ( sout_stream_t *, sout_stream_id_sys_t * );
static int Send( sout_stream_t *, sout_stream_id_sys_t *, block_t * );
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic );
inline static int video_update_format_decoder( decoder_t *p_dec );
inline static picture_t *video_new_buffer_decoder( decoder_t * );
inline static picture_t *video_new_buffer_filter( filter_t * );
@@ -290,7 +291,9 @@ static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, const es_format_t *p
p_sys->p_decoder->fmt_out = p_sys->p_decoder->fmt_in;
p_sys->p_decoder->fmt_out.i_extra = 0;
p_sys->p_decoder->fmt_out.p_extra = 0;
- p_sys->p_decoder->pf_decode_video = 0;
+ p_sys->p_decoder->pf_decode = NULL;
+ p_sys->p_decoder->pf_queue_video = decoder_queue_video;
+ p_sys->p_decoder->p_queue_ctx = p_stream;
p_sys->p_decoder->pf_vout_format_update = video_update_format_decoder;
p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
p_sys->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
@@ -306,9 +309,9 @@ static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, const es_format_t *p
p_sys->p_decoder->p_module =
module_need( p_sys->p_decoder, "decoder", "$codec", false );
- if( !p_sys->p_decoder->p_module || !p_sys->p_decoder->pf_decode_video )
+ if( !p_sys->p_decoder->p_module || p_sys->p_decoder->fmt_out.i_cat != VIDEO_ES )
{
- if( p_sys->p_decoder->p_module )
+ if( p_sys->p_decoder->fmt_out.i_cat != VIDEO_ES )
{
msg_Err( p_stream, "instanciated a non video decoder" );
module_unneed( p_sys->p_decoder, p_sys->p_decoder->p_module );
@@ -481,28 +484,97 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
p_sys->b_inited = false;
}
-/*****************************************************************************
- * PushPicture : push a picture in the mosaic-struct structure
- *****************************************************************************/
-static void PushPicture( sout_stream_t *p_stream, picture_t *p_picture )
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
{
+ sout_stream_t *p_stream = p_dec->p_queue_ctx;
sout_stream_sys_t *p_sys = p_stream->p_sys;
- bridged_es_t *p_es = p_sys->p_es;
+ picture_t *p_new_pic;
- vlc_global_lock( VLC_MOSAIC_MUTEX );
+ if( p_sys->i_height || p_sys->i_width )
+ {
+ video_format_t fmt_out, fmt_in;
+
+ memset( &fmt_in, 0, sizeof(video_format_t) );
+ memset( &fmt_out, 0, sizeof(video_format_t) );
+ fmt_in = p_sys->p_decoder->fmt_out.video;
+
+
+ if( p_sys->i_chroma )
+ fmt_out.i_chroma = p_sys->i_chroma;
+ else
+ fmt_out.i_chroma = VLC_CODEC_I420;
+
+ const unsigned i_fmt_in_aspect =
+ (int64_t)VOUT_ASPECT_FACTOR *
+ fmt_in.i_sar_num * fmt_in.i_width /
+ (fmt_in.i_sar_den * fmt_in.i_height);
+ if ( !p_sys->i_height )
+ {
+ fmt_out.i_width = p_sys->i_width;
+ fmt_out.i_height = (p_sys->i_width * VOUT_ASPECT_FACTOR
+ * p_sys->i_sar_num / p_sys->i_sar_den / i_fmt_in_aspect)
+ & ~0x1;
+ }
+ else if ( !p_sys->i_width )
+ {
+ fmt_out.i_height = p_sys->i_height;
+ fmt_out.i_width = (p_sys->i_height * i_fmt_in_aspect
+ * p_sys->i_sar_den / p_sys->i_sar_num / VOUT_ASPECT_FACTOR)
+ & ~0x1;
+ }
+ else
+ {
+ fmt_out.i_width = p_sys->i_width;
+ fmt_out.i_height = p_sys->i_height;
+ }
+ fmt_out.i_visible_width = fmt_out.i_width;
+ fmt_out.i_visible_height = fmt_out.i_height;
+
+ p_new_pic = image_Convert( p_sys->p_image,
+ p_pic, &fmt_in, &fmt_out );
+ if( p_new_pic == NULL )
+ {
+ msg_Err( p_stream, "image conversion failed" );
+ picture_Release( p_pic );
+ return -1;
+ }
+ }
+ else
+ {
+ /* TODO: chroma conversion if needed */
+
+ p_new_pic = picture_New( p_pic->format.i_chroma,
+ p_pic->format.i_width, p_pic->format.i_height,
+ p_sys->p_decoder->fmt_out.video.i_sar_num,
+ p_sys->p_decoder->fmt_out.video.i_sar_den );
+ if( !p_new_pic )
+ {
+ picture_Release( p_pic );
+ msg_Err( p_stream, "image allocation failed" );
+ return -1;
+ }
+
+ picture_Copy( p_new_pic, p_pic );
+ }
+ picture_Release( p_pic );
- *p_es->pp_last = p_picture;
- p_picture->p_next = NULL;
- p_es->pp_last = &p_picture->p_next;
+ if( p_sys->p_vf2 )
+ p_new_pic = filter_chain_VideoFilter( p_sys->p_vf2, p_new_pic );
+ /* push the picture in the mosaic-struct structure */
+ bridged_es_t *p_es = p_sys->p_es;
+ vlc_global_lock( VLC_MOSAIC_MUTEX );
+ *p_es->pp_last = p_new_pic;
+ p_new_pic->p_next = NULL;
+ p_es->pp_last = &p_new_pic->p_next;
vlc_global_unlock( VLC_MOSAIC_MUTEX );
+ return 0;
}
static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
block_t *p_buffer )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
- picture_t *p_pic;
if ( (sout_stream_sys_t *)id != p_sys )
{
@@ -510,86 +582,8 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
return VLC_SUCCESS;
}
- while ( (p_pic = p_sys->p_decoder->pf_decode_video( p_sys->p_decoder,
- &p_buffer )) )
- {
- picture_t *p_new_pic;
-
- if( p_sys->i_height || p_sys->i_width )
- {
- video_format_t fmt_out, fmt_in;
-
- memset( &fmt_in, 0, sizeof(video_format_t) );
- memset( &fmt_out, 0, sizeof(video_format_t) );
- fmt_in = p_sys->p_decoder->fmt_out.video;
-
-
- if( p_sys->i_chroma )
- fmt_out.i_chroma = p_sys->i_chroma;
- else
- fmt_out.i_chroma = VLC_CODEC_I420;
-
- const unsigned i_fmt_in_aspect =
- (int64_t)VOUT_ASPECT_FACTOR *
- fmt_in.i_sar_num * fmt_in.i_width /
- (fmt_in.i_sar_den * fmt_in.i_height);
- if ( !p_sys->i_height )
- {
- fmt_out.i_width = p_sys->i_width;
- fmt_out.i_height = (p_sys->i_width * VOUT_ASPECT_FACTOR
- * p_sys->i_sar_num / p_sys->i_sar_den / i_fmt_in_aspect)
- & ~0x1;
- }
- else if ( !p_sys->i_width )
- {
- fmt_out.i_height = p_sys->i_height;
- fmt_out.i_width = (p_sys->i_height * i_fmt_in_aspect
- * p_sys->i_sar_den / p_sys->i_sar_num / VOUT_ASPECT_FACTOR)
- & ~0x1;
- }
- else
- {
- fmt_out.i_width = p_sys->i_width;
- fmt_out.i_height = p_sys->i_height;
- }
- fmt_out.i_visible_width = fmt_out.i_width;
- fmt_out.i_visible_height = fmt_out.i_height;
-
- p_new_pic = image_Convert( p_sys->p_image,
- p_pic, &fmt_in, &fmt_out );
- if( p_new_pic == NULL )
- {
- msg_Err( p_stream, "image conversion failed" );
- picture_Release( p_pic );
- continue;
- }
- }
- else
- {
- /* TODO: chroma conversion if needed */
-
- p_new_pic = picture_New( p_pic->format.i_chroma,
- p_pic->format.i_width, p_pic->format.i_height,
- p_sys->p_decoder->fmt_out.video.i_sar_num,
- p_sys->p_decoder->fmt_out.video.i_sar_den );
- if( !p_new_pic )
- {
- picture_Release( p_pic );
- msg_Err( p_stream, "image allocation failed" );
- continue;
- }
-
- picture_Copy( p_new_pic, p_pic );
- }
- picture_Release( p_pic );
-
- if( p_sys->p_vf2 )
- p_new_pic = filter_chain_VideoFilter( p_sys->p_vf2, p_new_pic );
-
- PushPicture( p_stream, p_new_pic );
- }
-
- return VLC_SUCCESS;
+ int ret = p_sys->p_decoder->pf_decode( p_sys->p_decoder, p_buffer );
+ return ret == VLCDEC_SUCCESS ? VLC_SUCCESS : VLC_EGENERIC;
}
inline static int video_update_format_decoder( decoder_t *p_dec )
diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c
index 46e65a4f87..cc07ceeba9 100644
--- a/modules/stream_out/transcode/audio.c
+++ b/modules/stream_out/transcode/audio.c
@@ -133,6 +133,28 @@ static int transcode_audio_initialize_encoder( sout_stream_id_sys_t *id, sout_st
return VLC_SUCCESS;
}
+static int decoder_queue_audio( decoder_t *p_dec, block_t *p_audio )
+{
+ sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
+
+ vlc_mutex_lock(&id->fifo.lock);
+ *id->fifo.audio.last = p_audio;
+ id->fifo.audio.last = &p_audio->p_next;
+ vlc_mutex_unlock(&id->fifo.lock);
+ return 0;
+}
+
+static block_t *transcode_dequeue_all_audios( sout_stream_id_sys_t *id )
+{
+ vlc_mutex_lock(&id->fifo.lock);
+ block_t *p_audio_bufs = id->fifo.audio.first;
+ id->fifo.audio.first = NULL;
+ id->fifo.audio.last = &id->fifo.audio.first;
+ vlc_mutex_unlock(&id->fifo.lock);
+
+ return p_audio_bufs;
+}
+
int transcode_audio_new( sout_stream_t *p_stream,
sout_stream_id_sys_t *id )
{
@@ -147,7 +169,9 @@ int transcode_audio_new( sout_stream_t *p_stream,
id->p_decoder->fmt_out = id->p_decoder->fmt_in;
id->p_decoder->fmt_out.i_extra = 0;
id->p_decoder->fmt_out.p_extra = 0;
- id->p_decoder->pf_decode_audio = NULL;
+ id->p_decoder->pf_decode = NULL;
+ id->p_decoder->pf_queue_audio = decoder_queue_audio;
+ id->p_decoder->p_queue_ctx = id;
id->p_decoder->pf_aout_format_update = audio_update_format;
/* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */
id->p_decoder->p_module =
@@ -206,8 +230,8 @@ int transcode_audio_process( sout_stream_t *p_stream,
block_t *in, block_t **out )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
- block_t *p_block, *p_audio_buf;
*out = NULL;
+ bool b_error = false;
if( unlikely( in == NULL ) )
{
@@ -219,9 +243,26 @@ int transcode_audio_process( sout_stream_t *p_stream,
return VLC_SUCCESS;
}
- while( (p_audio_buf = id->p_decoder->pf_decode_audio( id->p_decoder,
- &in )) )
+ int ret = id->p_decoder->pf_decode( id->p_decoder, in );
+ if( ret != VLCDEC_SUCCESS )
+ return VLC_EGENERIC;
+
+ block_t *p_audio_bufs = transcode_dequeue_all_audios( id );
+ if( p_audio_bufs == NULL )
+ return VLC_SUCCESS;
+
+ do
{
+ block_t *p_audio_buf = p_audio_bufs;
+ p_audio_bufs = p_audio_bufs->p_next;
+ p_audio_buf->p_next = NULL;
+
+ if( b_error )
+ {
+ block_Release( p_audio_buf );
+ continue;
+ }
+
if( unlikely( !id->p_encoder->p_module ) )
{
/* Complete destination format */
@@ -245,20 +286,11 @@ int transcode_audio_process( sout_stream_t *p_stream,
if( transcode_audio_initialize_encoder( id, p_stream ) )
{
msg_Err( p_stream, "cannot create audio chain" );
-
- block_Release( in );
- block_Release( p_audio_buf );
-
- return VLC_EGENERIC;
+ goto error;
}
if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys,
&id->p_decoder->fmt_out.audio ) != VLC_SUCCESS ) )
- {
- block_Release( in );
- block_Release( p_audio_buf );
-
- return VLC_EGENERIC;
- }
+ goto error;
date_Init( &id->next_input_pts, id->p_decoder->fmt_out.audio.i_rate, 1 );
date_Set( &id->next_input_pts, p_audio_buf->i_pts );
}
@@ -277,7 +309,7 @@ int transcode_audio_process( sout_stream_t *p_stream,
if( transcode_audio_initialize_filters( p_stream, id, p_sys,
&id->p_decoder->fmt_out.audio ) != VLC_SUCCESS )
- return VLC_EGENERIC;
+ goto error;
/* Set next_input_pts to run with new samplerate */
date_Init( &id->next_input_pts, id->fmt_audio.i_rate, 1 );
@@ -313,17 +345,24 @@ int transcode_audio_process( sout_stream_t *p_stream,
p_audio_buf = aout_FiltersPlay( id->p_af_chain, p_audio_buf,
INPUT_RATE_DEFAULT );
if( !p_audio_buf )
- abort();
+ {
+ b_error = true;
+ continue;
+ }
p_audio_buf->i_dts = p_audio_buf->i_pts;
- p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
+ block_t *p_block = id->p_encoder->pf_encode_audio( id->p_encoder, p_audio_buf );
block_ChainAppend( out, p_block );
block_Release( p_audio_buf );
- }
+ continue;
+error:
+ block_Release( p_audio_buf );
+ b_error = true;
+ } while( p_audio_bufs );
- return VLC_SUCCESS;
+ return b_error ? VLC_EGENERIC : VLC_SUCCESS;
}
bool transcode_audio_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
@@ -335,6 +374,9 @@ bool transcode_audio_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
"creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
(char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );
+ id->fifo.audio.first = NULL;
+ id->fifo.audio.last = &id->fifo.audio.first;
+
/* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;
id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?
diff --git a/modules/stream_out/transcode/spu.c b/modules/stream_out/transcode/spu.c
index 6b9c3f858f..07ef82dec9 100644
--- a/modules/stream_out/transcode/spu.c
+++ b/modules/stream_out/transcode/spu.c
@@ -45,6 +45,28 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
return p_subpicture;
}
+static int decoder_queue_sub( decoder_t *p_dec, subpicture_t *p_spu )
+{
+ sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
+
+ vlc_mutex_lock(&id->fifo.lock);
+ *id->fifo.spu.last = p_spu;
+ id->fifo.spu.last = &p_spu->p_next;
+ vlc_mutex_unlock(&id->fifo.lock);
+ return 0;
+}
+
+static subpicture_t *transcode_dequeue_all_subs( sout_stream_id_sys_t *id )
+{
+ vlc_mutex_lock(&id->fifo.lock);
+ subpicture_t *p_subpics = id->fifo.spu.first;
+ id->fifo.spu.first = NULL;
+ id->fifo.spu.last = &id->fifo.spu.first;
+ vlc_mutex_unlock(&id->fifo.lock);
+
+ return p_subpics;
+}
+
int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
@@ -54,8 +76,10 @@ int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
*/
/* Initialization of decoder structures */
- id->p_decoder->pf_decode_sub = NULL;
+ id->p_decoder->pf_decode = NULL;
id->p_decoder->pf_spu_buffer_new = spu_new_buffer;
+ id->p_decoder->pf_queue_sub = decoder_queue_sub;
+ id->p_decoder->p_queue_ctx = id;
id->p_decoder->p_owner = (decoder_owner_sys_t *)p_stream;
/* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */
@@ -119,41 +143,50 @@ int transcode_spu_process( sout_stream_t *p_stream,
block_t *in, block_t **out )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
- subpicture_t *p_subpic;
*out = NULL;
+ bool b_error = false;
- p_subpic = id->p_decoder->pf_decode_sub( id->p_decoder, &in );
- if( !p_subpic )
- {
- /* We just don't have anything to handle now, go own*/
- return VLC_SUCCESS;
- }
-
- if( p_sys->b_master_sync && p_sys->i_master_drift )
- {
- p_subpic->i_start -= p_sys->i_master_drift;
- if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
- }
+ int ret = id->p_decoder->pf_decode( id->p_decoder, in );
+ if( ret != VLCDEC_SUCCESS )
+ return VLC_EGENERIC;
- if( p_sys->b_soverlay )
- {
- spu_PutSubpicture( p_sys->p_spu, p_subpic );
+ subpicture_t *p_subpics = transcode_dequeue_all_subs( id );
+ if( p_subpics == NULL )
return VLC_SUCCESS;
- }
- else
+ do
{
- block_t *p_block;
+ subpicture_t *p_subpic = p_subpics;
+ p_subpics = p_subpics->p_next;
+ p_subpic->p_next = NULL;
- p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
- subpicture_Delete( p_subpic );
- if( p_block )
+ if( b_error )
{
- block_ChainAppend( out, p_block );
- return VLC_SUCCESS;
+ subpicture_Delete( p_subpic );
+ continue;
}
- }
- return VLC_EGENERIC;
+ if( p_sys->b_master_sync && p_sys->i_master_drift )
+ {
+ p_subpic->i_start -= p_sys->i_master_drift;
+ if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
+ }
+
+ if( p_sys->b_soverlay )
+ spu_PutSubpicture( p_sys->p_spu, p_subpic );
+ else
+ {
+ block_t *p_block;
+
+ p_block = id->p_encoder->pf_encode_sub( id->p_encoder, p_subpic );
+ subpicture_Delete( p_subpic );
+ if( p_block )
+ block_ChainAppend( out, p_block );
+ else
+ b_error = true;
+ }
+ } while( p_subpics );
+
+ return b_error ? VLC_EGENERIC : VLC_SUCCESS;
}
bool transcode_spu_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
@@ -161,6 +194,9 @@ bool transcode_spu_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
+ id->fifo.spu.first = NULL;
+ id->fifo.spu.last = &id->fifo.spu.first;
+
if( p_sys->i_scodec )
{
msg_Dbg( p_stream, "creating subtitle transcoding from fcc=`%4.4s' "
diff --git a/modules/stream_out/transcode/transcode.c b/modules/stream_out/transcode/transcode.c
index 3e5884cb48..ebfcf14ebe 100644
--- a/modules/stream_out/transcode/transcode.c
+++ b/modules/stream_out/transcode/transcode.c
@@ -509,6 +509,7 @@ static sout_stream_id_sys_t *Add( sout_stream_t *p_stream,
if( !id )
goto error;
+ vlc_mutex_init(&id->fifo.lock);
id->id = NULL;
id->p_decoder = NULL;
id->p_encoder = NULL;
@@ -579,6 +580,7 @@ error:
id->p_encoder = NULL;
}
+ vlc_mutex_destroy(&id->fifo.lock);
free( id );
}
return NULL;
@@ -623,6 +625,7 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
vlc_object_release( id->p_encoder );
id->p_encoder = NULL;
}
+ vlc_mutex_destroy(&id->fifo.lock);
free( id );
}
diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index ff36c0986b..0c3aae0868 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -86,6 +86,26 @@ struct sout_stream_id_sys_t
/* Decoder */
decoder_t *p_decoder;
+ struct
+ {
+ vlc_mutex_t lock;
+ union
+ {
+ struct {
+ picture_t *first;
+ picture_t **last;
+ } pic;
+ struct {
+ subpicture_t *first;
+ subpicture_t **last;
+ } spu;
+ struct {
+ block_t *first;
+ block_t **last;
+ } audio;
+ };
+ } fifo;
+
union
{
struct
@@ -110,6 +130,8 @@ struct sout_stream_id_sys_t
date_t next_output_pts; /**< output calculated PTS */
};
+#define SOUT_ID_FROM_DEC(x) \
+ (void *) (((uintptr_t)x) - offsetof(sout_stream_id_sys_t, p_decoder))
/* OSD */
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 9a6f29594a..61f4c880ab 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -148,6 +148,28 @@ static void* EncoderThread( void *obj )
return NULL;
}
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
+{
+ sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
+
+ vlc_mutex_lock(&id->fifo.lock);
+ *id->fifo.pic.last = p_pic;
+ id->fifo.pic.last = &p_pic->p_next;
+ vlc_mutex_unlock(&id->fifo.lock);
+ return 0;
+}
+
+static picture_t *transcode_dequeue_all_pics( sout_stream_id_sys_t *id )
+{
+ vlc_mutex_lock(&id->fifo.lock);
+ picture_t *p_pics = id->fifo.pic.first;
+ id->fifo.pic.first = NULL;
+ id->fifo.pic.last = &id->fifo.pic.first;
+ vlc_mutex_unlock(&id->fifo.lock);
+
+ return p_pics;
+}
+
int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
@@ -159,7 +181,9 @@ int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
id->p_decoder->fmt_out.i_extra = 0;
id->p_decoder->fmt_out.p_extra = NULL;
id->p_decoder->fmt_out.psz_language = NULL;
- id->p_decoder->pf_decode_video = NULL;
+ id->p_decoder->pf_decode = NULL;
+ id->p_decoder->pf_queue_video = decoder_queue_video;
+ id->p_decoder->p_queue_ctx = id;
id->p_decoder->pf_get_cc = NULL;
id->p_decoder->pf_vout_format_update = video_update_format_decoder;
id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
@@ -753,6 +777,7 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
sout_stream_sys_t *p_sys = p_stream->p_sys;
picture_t *p_pic = NULL;
*out = NULL;
+ bool b_error = false;
if( unlikely( in == NULL ) )
{
@@ -783,9 +808,24 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
return VLC_SUCCESS;
}
+ int ret = id->p_decoder->pf_decode( id->p_decoder, in );
+ if( ret != VLCDEC_SUCCESS )
+ return VLC_EGENERIC;
- while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
+ picture_t *p_pics = transcode_dequeue_all_pics( id );
+ if( p_pics == NULL )
+ return VLC_SUCCESS;
+ do
{
+ picture_t *p_pic = p_pics;
+ p_pics = p_pics->p_next;
+ p_pic->p_next = NULL;
+
+ if( b_error )
+ {
+ picture_Release( p_pic );
+ continue;
+ }
if( unlikely (
id->p_encoder->p_module &&
@@ -833,10 +873,10 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )
{
picture_Release( p_pic );
- block_Release( in );
transcode_video_close( p_stream, id );
id->b_transcode = false;
- return VLC_EGENERIC;
+ b_error = true;
+ continue;
}
}
@@ -869,7 +909,7 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
p_pic = NULL;
}
- }
+ } while( p_pics );
if( p_sys->i_threads >= 1 )
{
@@ -880,7 +920,7 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
vlc_mutex_unlock( &p_sys->lock_out );
}
- return VLC_SUCCESS;
+ return b_error ? VLC_EGENERIC : VLC_SUCCESS;
}
bool transcode_video_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
@@ -892,6 +932,9 @@ bool transcode_video_add( sout_stream_t *p_stream, const es_format_t *p_fmt,
"creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",
(char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );
+ id->fifo.audio.first = NULL;
+ id->fifo.audio.last = &id->fifo.audio.first;
+
/* Complete destination format */
id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;
id->p_encoder->fmt_out.video.i_visible_width = p_sys->i_width & ~1;
diff --git a/src/input/decoder.c b/src/input/decoder.c
index f9d14ae001..4ce0ff2b7a 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -156,9 +156,7 @@ static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
p_dec->b_frame_drop_allowed = true;
p_dec->i_extra_picture_buffers = 0;
- p_dec->pf_decode_audio = NULL;
- p_dec->pf_decode_video = NULL;
- p_dec->pf_decode_sub = NULL;
+ p_dec->pf_decode = NULL;
p_dec->pf_get_cc = NULL;
p_dec->pf_packetize = NULL;
p_dec->pf_flush = NULL;
@@ -1039,81 +1037,6 @@ static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic )
return ret;
}
-static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
-{
- picture_t *p_pic;
- block_t **pp_block = p_block ? &p_block : NULL;
- unsigned i_lost = 0, i_decoded = 0;
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- while( (p_pic = p_dec->pf_decode_video( p_dec, pp_block ) ) )
- {
- i_decoded++;
-
- DecoderPlayVideo( p_dec, p_pic, &i_lost );
- }
-
- p_owner->pf_update_stat( p_owner, i_decoded, i_lost );
-}
-
-/* This function process a video block
- */
-static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- if( p_owner->p_packetizer )
- {
- block_t *p_packetized_block;
- block_t **pp_block = p_block ? &p_block : NULL;
- decoder_t *p_packetizer = p_owner->p_packetizer;
-
- while( (p_packetized_block =
- p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
- {
- if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
- {
- msg_Dbg( p_dec, "restarting module due to input format change");
-
- /* Drain the decoder module */
- DecoderDecodeVideo( p_dec, NULL );
-
- if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out,
- RELOAD_DECODER ) != VLC_SUCCESS )
- {
- block_ChainRelease( p_packetized_block );
- return;
- }
- }
-
- if( p_packetizer->pf_get_cc )
- DecoderGetCc( p_dec, p_packetizer );
-
- while( p_packetized_block )
- {
- block_t *p_next = p_packetized_block->p_next;
- p_packetized_block->p_next = NULL;
-
- DecoderDecodeVideo( p_dec, p_packetized_block );
- if( p_dec->b_error )
- {
- block_ChainRelease( p_next );
- return;
- }
-
- p_packetized_block = p_next;
- }
- }
- /* Drain the decoder after the packetizer is drained */
- if( !pp_block )
- DecoderDecodeVideo( p_dec, NULL );
- }
- else
- {
- DecoderDecodeVideo( p_dec, p_block );
- }
-}
-
static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
unsigned *restrict pi_lost_sum )
{
@@ -1234,78 +1157,6 @@ static int DecoderQueueAudio( decoder_t *p_dec, block_t *p_aout_buf )
return ret;
}
-static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
-{
- block_t *p_aout_buf;
- block_t **pp_block = p_block ? &p_block : NULL;
- unsigned decoded = 0, lost = 0;
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, pp_block ) ) )
- {
- decoded++;
-
- DecoderPlayAudio( p_dec, p_aout_buf, &lost );
- }
-
- p_owner->pf_update_stat( p_owner, decoded, lost );
-}
-
-/* This function process a audio block
- */
-static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- if( p_owner->p_packetizer )
- {
- block_t *p_packetized_block;
- block_t **pp_block = p_block ? &p_block : NULL;
- decoder_t *p_packetizer = p_owner->p_packetizer;
-
- while( (p_packetized_block =
- p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
- {
- if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
- {
- msg_Dbg( p_dec, "restarting module due to input format change");
-
- /* Drain the decoder module */
- DecoderDecodeAudio( p_dec, NULL );
-
- if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out,
- RELOAD_DECODER ) != VLC_SUCCESS )
- {
- block_ChainRelease( p_packetized_block );
- return;
- }
- }
-
- while( p_packetized_block )
- {
- block_t *p_next = p_packetized_block->p_next;
- p_packetized_block->p_next = NULL;
-
- DecoderDecodeAudio( p_dec, p_packetized_block );
- if( p_dec->b_error )
- {
- block_ChainRelease( p_next );
- return;
- }
-
- p_packetized_block = p_next;
- }
- }
- /* Drain the decoder after the packetizer is drained */
- if( !pp_block )
- DecoderDecodeAudio( p_dec, NULL );
- }
- else
- {
- DecoderDecodeAudio( p_dec, p_block );
- }
-}
-
static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
@@ -1391,22 +1242,19 @@ static int DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
return i_ret;
}
-/* This function process a subtitle block
- */
-static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
+
+static void DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
- subpicture_t *p_spu;
- block_t **pp_block = p_block ? &p_block : NULL;
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
- while( (p_spu = p_dec->pf_decode_sub( p_dec, pp_block ) ) )
+ int ret = p_dec->pf_decode( p_dec, p_block );
+ switch( ret )
{
- do
- {
- subpicture_t *p = p_spu;
- p_spu = p_spu->p_next;
- p->p_next = NULL;
- DecoderQueueSpu( p_dec, p );
- } while( p_spu );
+ case VLCDEC_SUCCESS:
+ p_owner->pf_update_stat( p_owner, 1, 0 );
+ break;
+ default:
+ vlc_assert_unreachable();
}
}
@@ -1455,13 +1303,55 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
}
#endif
- switch( p_dec->fmt_out.i_cat )
+ if( p_owner->p_packetizer )
{
- case VIDEO_ES: DecoderProcessVideo( p_dec, p_block ); return;
- case AUDIO_ES: DecoderProcessAudio( p_dec, p_block ); return;
- case SPU_ES: DecoderProcessSpu( p_dec, p_block ); return;
- default: vlc_assert_unreachable();
+ block_t *p_packetized_block;
+ block_t **pp_block = p_block ? &p_block : NULL;
+ decoder_t *p_packetizer = p_owner->p_packetizer;
+
+ while( (p_packetized_block =
+ p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
+ {
+ if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
+ {
+ msg_Dbg( p_dec, "restarting module due to input format change");
+
+ /* Drain the decoder module */
+ DecoderDecode( p_dec, NULL );
+
+ if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out,
+ RELOAD_DECODER ) != VLC_SUCCESS )
+ {
+ block_ChainRelease( p_packetized_block );
+ return;
+ }
+ }
+
+ if( p_packetizer->pf_get_cc )
+ DecoderGetCc( p_dec, p_packetizer );
+
+ while( p_packetized_block )
+ {
+ block_t *p_next = p_packetized_block->p_next;
+ p_packetized_block->p_next = NULL;
+
+ DecoderDecode( p_dec, p_packetized_block );
+ if( p_dec->b_error )
+ {
+ block_ChainRelease( p_next );
+ return;
+ }
+
+ p_packetized_block = p_next;
+ }
+ }
+ /* Drain the decoder after the packetizer is drained */
+ if( !pp_block )
+ DecoderDecode( p_dec, NULL );
}
+ else
+ DecoderDecode( p_dec, p_block );
+ return;
error:
if( p_block )
diff --git a/src/input/demux.c b/src/input/demux.c
index f3b0495c75..58234724bc 100644
--- a/src/input/demux.c
+++ b/src/input/demux.c
@@ -504,9 +504,7 @@ decoder_t *demux_PacketizerNew( demux_t *p_demux, es_format_t *p_fmt, const char
}
p_fmt->b_packetized = false;
- p_packetizer->pf_decode_audio = NULL;
- p_packetizer->pf_decode_video = NULL;
- p_packetizer->pf_decode_sub = NULL;
+ p_packetizer->pf_decode = NULL;
p_packetizer->pf_packetize = NULL;
p_packetizer->fmt_in = *p_fmt;
diff --git a/src/misc/image.c b/src/misc/image.c
index 9e0fd7102e..ec372303bc 100644
--- a/src/misc/image.c
+++ b/src/misc/image.c
@@ -93,6 +93,8 @@ image_handler_t *image_HandlerCreate( vlc_object_t *p_this )
p_image->pf_write_url = ImageWriteUrl;
p_image->pf_convert = ImageConvert;
+ p_image->outfifo = picture_fifo_New();
+
return p_image;
}
@@ -108,6 +110,8 @@ void image_HandlerDelete( image_handler_t *p_image )
if( p_image->p_enc ) DeleteEncoder( p_image->p_enc );
if( p_image->p_filter ) DeleteFilter( p_image->p_filter );
+ picture_fifo_Delete( p_image->outfifo );
+
free( p_image );
p_image = NULL;
}
@@ -117,11 +121,18 @@ void image_HandlerDelete( image_handler_t *p_image )
*
*/
+static int ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic )
+{
+ image_handler_t *p_image = p_dec->p_queue_ctx;
+ picture_fifo_Push( p_image->outfifo, p_pic );
+ return 0;
+}
+
static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
video_format_t *p_fmt_in,
video_format_t *p_fmt_out )
{
- picture_t *p_pic = NULL, *p_tmp;
+ picture_t *p_pic = NULL;
/* Check if we can reuse the current decoder */
if( p_image->p_dec &&
@@ -140,15 +151,36 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block,
block_Release(p_block);
return NULL;
}
+ if( p_image->p_dec->fmt_out.i_cat != VIDEO_ES )
+ {
+ DeleteDecoder( p_image->p_dec );
+ p_image->p_dec = NULL;
+ block_Release(p_block);
+ return NULL;
+ }
+ p_image->p_dec->pf_queue_video = ImageQueueVideo;
+ p_image->p_dec->p_queue_ctx = p_image;
}
p_block->i_pts = p_block->i_dts = mdate();
- while( (p_tmp = p_image->p_dec->pf_decode_video( p_image->p_dec, &p_block ))
- != NULL )
+ int ret = p_image->p_dec->pf_decode( p_image->p_dec, p_block );
+ if( ret == VLCDEC_SUCCESS )
{
- if( p_pic != NULL )
- picture_Release( p_pic );
- p_pic = p_tmp;
+ /* Drain */
+ p_image->p_dec->pf_decode( p_image->p_dec, NULL );
+
+ p_pic = picture_fifo_Pop( p_image->outfifo );
+
+ unsigned lostcount = 0;
+ picture_t *lostpic;
+ while( ( lostpic = picture_fifo_Pop( p_image->outfifo ) ) != NULL )
+ {
+ picture_Release( lostpic );
+ lostcount++;
+ }
+ if( lostcount > 0 )
+ msg_Warn( p_image->p_parent, "Image decoder output more than one "
+ "picture (%d)", lostcount );
}
if( p_pic == NULL )
--
2.11.0
More information about the vlc-devel
mailing list