[vlc-commits] avcodec: use reference counting for audio decoding
Rémi Denis-Courmont
git at videolan.org
Thu Aug 8 20:23:58 CEST 2013
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Aug 8 21:22:11 2013 +0300| [18fbf7fd17a0f4e9cabcc2e34ac54b210ba08b27] | committer: Rémi Denis-Courmont
avcodec: use reference counting for audio decoding
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=18fbf7fd17a0f4e9cabcc2e34ac54b210ba08b27
---
modules/codec/avcodec/audio.c | 86 +++++++++++++++++++++++++++++++++++++----
1 file changed, 78 insertions(+), 8 deletions(-)
diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c
index 6b68f40..aa89255 100644
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -118,6 +118,42 @@ static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
/**
* Allocates decoded audio buffer for libavcodec to use.
*/
+#if (LIBAVCODEC_VERSION_MAJOR >= 55)
+typedef struct
+{
+ block_t self;
+ AVFrame *frame;
+} vlc_av_frame_t;
+
+static void vlc_av_frame_Release(block_t *block)
+{
+ vlc_av_frame_t *b = (void *)block;
+
+ av_frame_free(&b->frame);
+ free(b);
+}
+
+static block_t *vlc_av_frame_Wrap(AVFrame *frame)
+{
+ for (unsigned i = 1; i < AV_NUM_DATA_POINTERS; i++)
+ assert(frame->linesize[i] == 0); /* only packed frame supported */
+
+ if (av_frame_make_writable(frame)) /* TODO: read-only block_t */
+ return NULL;
+
+ vlc_av_frame_t *b = malloc(sizeof (*b));
+ if (unlikely(b == NULL))
+ return NULL;
+
+ block_t *block = &b->self;
+
+ block_Init(block, frame->extended_data[0], frame->linesize[0]);
+ block->i_nb_samples = frame->nb_samples;
+ block->pf_release = vlc_av_frame_Release;
+ b->frame = frame;
+ return block;
+}
+#else
static int GetAudioBuf( AVCodecContext *ctx, AVFrame *buf )
{
block_t *block;
@@ -159,6 +195,7 @@ static int GetAudioBuf( AVCodecContext *ctx, AVFrame *buf )
return 0;
}
+#endif
/*****************************************************************************
* InitAudioDec: initialize audio decoder
@@ -179,7 +216,11 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
p_codec->type = AVMEDIA_TYPE_AUDIO;
p_context->codec_type = AVMEDIA_TYPE_AUDIO;
p_context->codec_id = i_codec_id;
+#if (LIBAVCODEC_VERSION_MAJOR >= 55)
+ p_context->refcounted_frames = true;
+#else
p_context->get_buffer = GetAudioBuf;
+#endif
p_sys->p_context = p_context;
p_sys->p_codec = p_codec;
p_sys->i_codec_id = i_codec_id;
@@ -270,7 +311,13 @@ block_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
}
+#if (LIBAVCODEC_VERSION_MAJOR >= 55)
+ AVFrame *frame = av_frame_alloc();
+ if (unlikely(frame == NULL))
+ goto end;
+#else
AVFrame *frame = &(AVFrame) { };
+#endif
for( int got_frame = 0; !got_frame; )
{
@@ -317,23 +364,38 @@ block_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
*pp_block = NULL;
}
+#if (LIBAVCODEC_VERSION_MAJOR < 55)
/* NOTE WELL: Beyond this point, p_block refers to the DECODED block! */
p_block = frame->opaque;
+#endif
SetupOutputFormat( p_dec, true );
if( decoder_UpdateAudioFormat( p_dec ) )
goto drop;
- /* Silent unwanted samples */
- if( p_sys->i_reject_count > 0 )
+ /* Interleave audio if required */
+ if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
+#if (LIBAVCODEC_VERSION_MAJOR >= 55)
{
- memset( p_block->p_buffer, 0, p_block->i_buffer );
- p_sys->i_reject_count--;
- }
+ p_block = block_Alloc(frame->linesize[0] * ctx->channels);
+ if (unlikely(p_block == NULL))
+ goto drop;
- assert( p_block->i_nb_samples >= (unsigned)frame->nb_samples );
+ const void *planes[ctx->channels];
+ for (int i = 0; i < ctx->channels; i++)
+ planes[i] = frame->extended_data[i];
- /* Interleave audio if required */
- if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
+ aout_Interleave(p_block->p_buffer, planes, frame->nb_samples,
+ ctx->channels, p_dec->fmt_out.audio.i_format);
+ p_block->i_nb_samples = frame->nb_samples;
+ av_frame_free(&frame);
+ }
+ else
+ {
+ p_block = vlc_av_frame_Wrap(frame);
+ if (unlikely(p_block == NULL))
+ goto drop;
+ }
+#else
{
block_t *p_buffer = block_Alloc( p_block->i_buffer );
if( unlikely(p_buffer == NULL) )
@@ -351,6 +413,7 @@ block_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
p_block = p_buffer;
}
p_block->i_nb_samples = frame->nb_samples;
+#endif
if (p_sys->b_extract)
{ /* TODO: do not drop channels... at least not here */
@@ -368,6 +431,13 @@ block_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
p_block = p_buffer;
}
+ /* Silent unwanted samples */
+ if( p_sys->i_reject_count > 0 )
+ {
+ memset( p_block->p_buffer, 0, p_block->i_buffer );
+ p_sys->i_reject_count--;
+ }
+
p_block->i_buffer = p_block->i_nb_samples
* p_dec->fmt_out.audio.i_bytes_per_frame;
p_block->i_pts = date_Get( &p_sys->end_date );
More information about the vlc-commits
mailing list