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