decoder: refactor pf_decode_* callbacks

Use only one callback for every decoder types:

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

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

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

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

The pf_decode callback returns, for now, only one value: SUCCESS. This will
allow a module to send more status.
This commit is contained in:
Thomas Guillem 2017-02-07 10:21:22 +01:00
parent f4eec050da
commit a8b249bc6b
76 changed files with 1413 additions and 1372 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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:
*****************************************************************************/

View File

@ -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 )
{

View File

@ -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;

View File

@ -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 )

View File

@ -41,7 +41,7 @@
*****************************************************************************/
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
static subpicture_t *Decode( decoder_t *, block_t ** );
static int Decode( decoder_t *, block_t * );
#define IGNORE_RUBY_TEXT N_("Ignore ruby(furigana)")
#define IGNORE_RUBY_LONGTEXT N_("Ignore ruby(furigana) in the subtitle.")
@ -117,7 +117,7 @@ static int Open( vlc_object_t *p_this )
}
p_dec->p_sys = p_sys;
p_dec->pf_decode_sub = Decode;
p_dec->pf_decode = Decode;
p_dec->fmt_out.i_cat = SPU_ES;
p_dec->fmt_out.i_codec = 0;
@ -161,22 +161,17 @@ static void Close( vlc_object_t *p_this )
/*****************************************************************************
* Decode:
*****************************************************************************/
static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
static int Decode( decoder_t *p_dec, block_t *p_block )
{
decoder_sys_t *p_sys = p_dec->p_sys;
block_t *p_block;
subpicture_t *p_spu = NULL;
if( ( pp_block == NULL ) || ( *pp_block == NULL ) )
{
return NULL;
}
p_block = *pp_block;
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{
block_Release( p_block );
return NULL;
return VLCDEC_SUCCESS;
}
arib_parser_t *p_parser = arib_get_parser( p_sys->p_arib_instance );
@ -184,13 +179,13 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if ( p_parser && p_decoder )
{
arib_parse_pes( p_parser, p_block->p_buffer, p_block->i_buffer );
p_spu = render( p_dec, p_parser, p_decoder, p_block );
subpicture_t *p_spu = render( p_dec, p_parser, p_decoder, p_block );
if( p_spu != NULL )
decoder_QueueSub( p_dec, p_spu );
}
block_Release( p_block );
*pp_block = NULL;
return p_spu;
return VLCDEC_SUCCESS;
}
/* following functions are local */

View File

@ -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;

View File

@ -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.
*/

View File

@ -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
*****************************************************************************

View File

@ -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 )

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
}
/*****************************************************************************

View File

@ -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

View File

@ -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;
}
/*****************************************************************************

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
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 );
}
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 );

View File

@ -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 */

View File

@ -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;
}
/*****************************************************************************

View File

@ -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

View File

@ -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;
}

View File

@ -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 )

View File

@ -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 */

View File

@ -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;
}
/*

View File

@ -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 */

View File

@ -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;
}
/****************************************************************************

View File

@ -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
*****************************************************************************/

View File

@ -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
*****************************************************************************/

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
/*****************************************************************************

View File

@ -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 )
{

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
@ -206,6 +205,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
p_spu_sys->p_default_style->i_features |= STYLE_HAS_FONT_COLOR;
p_spu_sys->region.p_segments = text_segment_New( p_cea->psz_alert_text );
decoder_QueueSub( p_dec, p_spu );
}
msg_Info( p_dec, "Received %s", p_cea->psz_alert_text );
scte18_cea_Free( p_cea );
@ -213,7 +213,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
exit:
block_Release( p_block );
return p_spu;
return VLCDEC_SUCCESS;
}
static int Open( vlc_object_t *object )
@ -235,7 +235,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;

View File

@ -405,16 +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;
subpicture_t *sub_first = NULL;
subpicture_t **sub_last = &sub_first;
if (b == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
if (b->i_flags & (BLOCK_FLAG_CORRUPTED))
goto exit;
@ -479,9 +475,8 @@ static subpicture_t *Decode(decoder_t *dec, block_t **block)
section_length - 1 - 4,
b->i_pts > VLC_TS_INVALID ? b->i_pts : b->i_dts);
}
*sub_last = sub;
if (*sub_last)
sub_last = &(*sub_last)->p_next;
if (sub != NULL)
decoder_QueueSub(dec, sub);
b->i_buffer -= 3 + section_length;
b->p_buffer += 3 + section_length;
@ -490,7 +485,7 @@ static subpicture_t *Decode(decoder_t *dec, block_t **block)
exit:
block_Release(b);
return sub_first;
return VLCDEC_SUCCESS;
}
static int Open(vlc_object_t *object)
@ -507,7 +502,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;

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
}

View File

@ -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;
}
/*****************************************************************************

View File

@ -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 shouldnt 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 )
{

View File

@ -363,16 +363,10 @@ 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;
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 == NULL) /* No Drain */
return VLCDEC_SUCCESS;
if(p_block->i_buffer < STL_TTI_SIZE)
p_block->i_flags |= BLOCK_FLAG_CORRUPTED;
@ -384,7 +378,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;
}
}
@ -414,15 +408,13 @@ static subpicture_t *Decode(decoder_t *p_dec, block_t **pp_block)
p_sub->i_stop = p_block->i_pts + p_block->i_length;
p_sub->b_ephemer = (p_block->i_length == 0);
}
*pp_sub_last = p_sub;
pp_sub_last = &p_sub->p_next;
decoder_QueueSub(p_dec, p_sub);
}
}
}
block_Release(p_block);
return p_sub_first;
return VLCDEC_SUCCESS;
}
static int ExtractCCT(const decoder_t *dec, cct_number_value_t *cct_number)
@ -472,7 +464,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;

View File

@ -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;
}
/*****************************************************************************

View File

@ -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,6 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
block_Release( p_block );
return p_spu;
decoder_QueueSub( p_dec, p_spu );
return VLCDEC_SUCCESS;
}

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
}
/*****************************************************************************

View File

@ -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;
}

View File

@ -222,41 +222,35 @@ 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;
decoder_QueueSub(p_dec, p_sub);
}
return p_sub;
block_Release(p_block);
return VLCDEC_SUCCESS;
}
static void Close(vlc_object_t *object)
@ -278,7 +272,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;

View File

@ -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;

View File

@ -705,11 +705,8 @@ static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, int64_t i_playback
return p_regions;
}
static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block )
static int ParseBlock( decoder_t *p_dec, const block_t *p_block )
{
subpicture_t *p_spus_head = NULL;
subpicture_t **pp_spus_tail = &p_spus_head;
int64_t *p_timings_array = NULL;
size_t i_timings_count = 0;
@ -720,18 +717,18 @@ static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block )
temporal_extent.i_dur = -1;
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
return NULL;
return VLCDEC_SUCCESS;
/* We cannot display a subpicture with no date */
if( p_block->i_pts <= VLC_TS_INVALID )
{
msg_Warn( p_dec, "subtitle without a date" );
return NULL;
return VLCDEC_SUCCESS;
}
tt_node_t *p_rootnode = ParseTTML( p_dec, p_block->p_buffer, p_block->i_buffer );
if( !p_rootnode )
return NULL;
return VLCDEC_SUCCESS;
tt_timings_Resolve( (tt_basenode_t *) p_rootnode, &temporal_extent,
&p_timings_array, &i_timings_count );
@ -804,17 +801,14 @@ static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block )
}
if( p_spu )
{
*pp_spus_tail = p_spu;
pp_spus_tail = &p_spu->p_next;
}
decoder_QueueSub( p_dec, p_spu );
}
tt_node_RecursiveDelete( p_rootnode );
free( p_timings_array );
return p_spus_head;
return VLCDEC_SUCCESS;
}
@ -822,18 +816,14 @@ 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;
block_t* p_block = *pp_block;
subpicture_t *p_spu = ParseBlock( p_dec, p_block );
if( p_block == NULL ) /* No Drain */
return VLCDEC_SUCCESS;
int ret = ParseBlock( p_dec, p_block );
block_Release( p_block );
*pp_block = NULL;
return p_spu;
return ret;
}
/*****************************************************************************
@ -852,7 +842,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" );

View File

@ -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;
}

View File

@ -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,23 +1037,25 @@ 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;
for (;;)
{
vlc_mutex_lock(&p_sys->lock);
picture_t *p_pic = PicReorder_pop(p_dec, true);
vlc_mutex_unlock(&p_sys->lock);
if (p_pic)
decoder_QueueVideo(p_dec, p_pic);
else
break;
}
return VLCDEC_SUCCESS;
}
block_t *p_block = *pp_block;
*pp_block = NULL;
if (p_block == NULL)
return NULL; /* no need to be called again, pics are queued asynchronously */
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_abort) { /* abort from output thread (DecoderCallback) */
vlc_mutex_unlock(&p_sys->lock);
@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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,26 +219,10 @@ 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;
return VLCDEC_SUCCESS;
}
}
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 p_aout_buffer;
}
/* Date management */
if( p_block->i_pts > VLC_TS_INVALID &&
p_block->i_pts != date_Get( &p_sys->end_date ) )
@ -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 );
return 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 VLCDEC_SUCCESS;
}
/*****************************************************************************

View File

@ -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;
}

View File

@ -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,

View File

@ -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)

View File

@ -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 );

View File

@ -811,9 +811,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;
}

View File

@ -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;
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 );
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 );
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_picture;
p_picture->p_next = NULL;
p_es->pp_last = &p_picture->p_next;
*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 )

View File

@ -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 ?

View File

@ -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*/
int ret = id->p_decoder->pf_decode( id->p_decoder, in );
if( ret != VLCDEC_SUCCESS )
return VLC_EGENERIC;
subpicture_t *p_subpics = transcode_dequeue_all_subs( id );
if( p_subpics == NULL )
return VLC_SUCCESS;
}
if( p_sys->b_master_sync && p_sys->i_master_drift )
do
{
p_subpic->i_start -= p_sys->i_master_drift;
if( p_subpic->i_stop ) p_subpic->i_stop -= p_sys->i_master_drift;
}
subpicture_t *p_subpic = p_subpics;
p_subpics = p_subpics->p_next;
p_subpic->p_next = NULL;
if( p_sys->b_soverlay )
{
spu_PutSubpicture( p_sys->p_spu, p_subpic );
return VLC_SUCCESS;
}
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 )
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' "

View File

@ -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 );
}

View File

@ -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 */

View File

@ -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;

View File

@ -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 )
{
subpicture_t *p_spu;
block_t **pp_block = p_block ? &p_block : NULL;
while( (p_spu = p_dec->pf_decode_sub( p_dec, pp_block ) ) )
static void DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
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();
}
}
@ -1424,7 +1272,7 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
goto error;
/* Here, the atomic doesn't prevent to miss a reload request.
* DecoderProcess*() can still be called after the decoder module or the
* DecoderProcess() can still be called after the decoder module or the
* audio output requested a reload. This will only result in a drop of an
* input block or an output buffer. */
enum reload reload;
@ -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 )

View File

@ -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;

View File

@ -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 )