/src/vlc/modules/codec/avcodec/audio.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * audio.c: audio decoder using libavcodec library |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 1999-2003 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Gildas Bazin <gbazin@videolan.org> |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify it |
10 | | * under the terms of the GNU Lesser General Public License as published by |
11 | | * the Free Software Foundation; either version 2.1 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public License |
20 | | * along with this program; if not, write to the Free Software Foundation, |
21 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
22 | | *****************************************************************************/ |
23 | | |
24 | | /***************************************************************************** |
25 | | * Preamble |
26 | | *****************************************************************************/ |
27 | | #ifdef HAVE_CONFIG_H |
28 | | # include "config.h" |
29 | | #endif |
30 | | |
31 | | #include <assert.h> |
32 | | |
33 | | #include <vlc_common.h> |
34 | | #include <vlc_aout.h> |
35 | | #include <vlc_codec.h> |
36 | | #include <vlc_avcodec.h> |
37 | | |
38 | | #include "avcodec.h" |
39 | | #include "../../demux/xiph.h" |
40 | | |
41 | | #include <stdbit.h> |
42 | | |
43 | | #include <libavcodec/avcodec.h> |
44 | | #include <libavutil/mem.h> |
45 | | |
46 | | #define API_CHANNEL_LAYOUT_STRUCT (LIBAVCODEC_VERSION_CHECK(59, 24, 100)) // AVCodecContext.ch_layout |
47 | | |
48 | | #include <libavutil/channel_layout.h> |
49 | | |
50 | | |
51 | | /***************************************************************************** |
52 | | * decoder_sys_t : decoder descriptor |
53 | | *****************************************************************************/ |
54 | | typedef struct |
55 | | { |
56 | | AVCodecContext *p_context; |
57 | | const AVCodec *p_codec; |
58 | | |
59 | | /* |
60 | | * Output properties |
61 | | */ |
62 | | audio_sample_format_t aout_format; |
63 | | date_t end_date; |
64 | | |
65 | | /* */ |
66 | | int i_reject_count; |
67 | | |
68 | | /* */ |
69 | | bool b_extract; |
70 | | bool discontinuity; |
71 | | int pi_extraction[AOUT_CHAN_MAX]; |
72 | | int i_previous_channels; |
73 | | uint64_t i_previous_layout; |
74 | | } decoder_sys_t; |
75 | | |
76 | 4.42M | #define BLOCK_FLAG_PRIVATE_REALLOCATED (1 << BLOCK_FLAG_PRIVATE_SHIFT) |
77 | | |
78 | | static void SetupOutputFormat( decoder_t *p_dec, bool b_trust ); |
79 | | static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame ); |
80 | | static int DecodeAudio( decoder_t *, block_t * ); |
81 | | static void Flush( decoder_t * ); |
82 | | |
83 | | static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context ) |
84 | 305k | { |
85 | 305k | if( p_dec->fmt_in->i_extra > 0 ) |
86 | 74.5k | { |
87 | 74.5k | const uint8_t * const p_src = p_dec->fmt_in->p_extra; |
88 | | |
89 | 74.5k | int i_offset = 0; |
90 | 74.5k | int i_size = p_dec->fmt_in->i_extra; |
91 | | |
92 | 74.5k | if( p_dec->fmt_in->i_codec == VLC_CODEC_ALAC ) |
93 | 11 | { |
94 | 11 | static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' }; |
95 | | /* Find alac atom XXX it is a bit ugly */ |
96 | 272 | for( i_offset = 0; i_offset < i_size - (int)sizeof(p_pattern); i_offset++ ) |
97 | 261 | { |
98 | 261 | if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) ) |
99 | 0 | break; |
100 | 261 | } |
101 | 11 | i_size = __MIN( p_dec->fmt_in->i_extra - i_offset, 36 ); |
102 | 11 | if( i_size < 36 ) |
103 | 11 | i_size = 0; |
104 | 11 | } |
105 | 74.5k | else if( p_dec->fmt_in->i_codec == VLC_CODEC_OPUS && |
106 | 0 | i_size > 21 && !memcmp( &p_src[2], "OpusHead", 8 ) ) |
107 | 0 | { |
108 | | /* see opus.c decoder */ |
109 | 0 | size_t hdr_size[XIPH_MAX_HEADER_COUNT]; |
110 | 0 | const void *hdr[XIPH_MAX_HEADER_COUNT]; |
111 | 0 | size_t i_count; |
112 | 0 | if( !xiph_SplitHeaders( hdr_size, hdr, &i_count, |
113 | 0 | i_size, p_src ) && i_count >= 1 ) |
114 | 0 | { |
115 | 0 | i_offset = (const uint8_t *)hdr[0] - p_src; |
116 | 0 | i_size = hdr_size[0]; |
117 | 0 | } |
118 | 0 | } |
119 | | |
120 | 74.5k | if( i_size > 0 ) |
121 | 74.5k | { |
122 | 74.5k | p_context->extradata = |
123 | 74.5k | av_malloc( i_size + AV_INPUT_BUFFER_PADDING_SIZE ); |
124 | 74.5k | if( p_context->extradata ) |
125 | 74.5k | { |
126 | 74.5k | uint8_t *p_dst = p_context->extradata; |
127 | | |
128 | 74.5k | p_context->extradata_size = i_size; |
129 | | |
130 | 74.5k | memcpy( &p_dst[0], &p_src[i_offset], i_size ); |
131 | 74.5k | memset( &p_dst[i_size], 0, AV_INPUT_BUFFER_PADDING_SIZE ); |
132 | 74.5k | } |
133 | 74.5k | } |
134 | 74.5k | } |
135 | 231k | else |
136 | 231k | { |
137 | 231k | p_context->extradata_size = 0; |
138 | 231k | p_context->extradata = NULL; |
139 | 231k | } |
140 | 305k | } |
141 | | |
142 | | static int OpenAudioCodec( decoder_t *p_dec ) |
143 | 305k | { |
144 | 305k | decoder_sys_t *p_sys = p_dec->p_sys; |
145 | 305k | AVCodecContext *ctx = p_sys->p_context; |
146 | 305k | const AVCodec *codec = p_sys->p_codec; |
147 | | |
148 | 305k | if( ctx->extradata_size <= 0 ) |
149 | 231k | { |
150 | 231k | if( codec->id == AV_CODEC_ID_VORBIS || |
151 | 231k | ( codec->id == AV_CODEC_ID_AAC && |
152 | 0 | !p_dec->fmt_in->b_packetized ) ) |
153 | 0 | { |
154 | 0 | msg_Warn( p_dec, "waiting for extra data for codec %s", |
155 | 0 | codec->name ); |
156 | 0 | return 1; |
157 | 0 | } |
158 | 231k | } |
159 | | |
160 | 305k | ctx->sample_rate = p_dec->fmt_in->audio.i_rate; |
161 | 305k | #if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
162 | 305k | av_channel_layout_default( &ctx->ch_layout, p_dec->fmt_in->audio.i_channels ); |
163 | | #else |
164 | | ctx->channels = p_dec->fmt_in->audio.i_channels; |
165 | | #endif |
166 | 305k | ctx->block_align = p_dec->fmt_in->audio.i_blockalign; |
167 | 305k | ctx->bit_rate = p_dec->fmt_in->i_bitrate; |
168 | 305k | ctx->bits_per_coded_sample = p_dec->fmt_in->audio.i_bitspersample; |
169 | | |
170 | 305k | if( codec->id == AV_CODEC_ID_ADPCM_G726 && |
171 | 67 | ctx->bit_rate > 0 && |
172 | 67 | ctx->sample_rate > 0) |
173 | 14 | ctx->bits_per_coded_sample = ctx->bit_rate / ctx->sample_rate; |
174 | | |
175 | 305k | return ffmpeg_OpenCodec( p_dec, ctx, codec ); |
176 | 305k | } |
177 | | |
178 | | /** |
179 | | * Allocates decoded audio buffer for libavcodec to use. |
180 | | */ |
181 | | typedef struct |
182 | | { |
183 | | block_t self; |
184 | | AVFrame *frame; |
185 | | } vlc_av_frame_t; |
186 | | |
187 | | static void vlc_av_frame_Release(block_t *block) |
188 | 0 | { |
189 | 0 | vlc_av_frame_t *b = (void *)block; |
190 | |
|
191 | 0 | av_frame_free(&b->frame); |
192 | 0 | free(b); |
193 | 0 | } |
194 | | |
195 | | static const struct vlc_block_callbacks vlc_av_frame_cbs = |
196 | | { |
197 | | vlc_av_frame_Release, |
198 | | }; |
199 | | |
200 | | static block_t *vlc_av_frame_Wrap(AVFrame *frame) |
201 | 0 | { |
202 | 0 | for (unsigned i = 1; i < AV_NUM_DATA_POINTERS; i++) |
203 | 0 | assert(frame->linesize[i] == 0); /* only packed frame supported */ |
204 | |
|
205 | 0 | if (av_frame_make_writable(frame)) /* TODO: read-only block_t */ |
206 | 0 | return NULL; |
207 | | |
208 | 0 | vlc_av_frame_t *b = malloc(sizeof (*b)); |
209 | 0 | if (unlikely(b == NULL)) |
210 | 0 | return NULL; |
211 | | |
212 | 0 | block_t *block = &b->self; |
213 | |
|
214 | 0 | block_Init(block, &vlc_av_frame_cbs, |
215 | 0 | frame->extended_data[0], frame->linesize[0]); |
216 | 0 | block->i_nb_samples = frame->nb_samples; |
217 | 0 | b->frame = frame; |
218 | 0 | return block; |
219 | 0 | } |
220 | | |
221 | | /***************************************************************************** |
222 | | * EndAudio: decoder destruction |
223 | | ***************************************************************************** |
224 | | * This function is called when the thread ends after a successful |
225 | | * initialization. |
226 | | *****************************************************************************/ |
227 | | void EndAudioDec( vlc_object_t *obj ) |
228 | 232k | { |
229 | 232k | decoder_t *p_dec = (decoder_t *)obj; |
230 | 232k | decoder_sys_t *sys = p_dec->p_sys; |
231 | 232k | AVCodecContext *ctx = sys->p_context; |
232 | | |
233 | 232k | avcodec_free_context( &ctx ); |
234 | 232k | free( sys ); |
235 | 232k | } |
236 | | |
237 | | /***************************************************************************** |
238 | | * InitAudioDec: initialize audio decoder |
239 | | ***************************************************************************** |
240 | | * The avcodec codec will be opened, some memory allocated. |
241 | | *****************************************************************************/ |
242 | | int InitAudioDec( vlc_object_t *obj ) |
243 | 307k | { |
244 | 307k | decoder_t *p_dec = (decoder_t *)obj; |
245 | 307k | const AVCodec *codec; |
246 | 307k | AVCodecContext *avctx = ffmpeg_AllocContext( p_dec, &codec, false ); |
247 | 307k | if( avctx == NULL ) |
248 | 2.16k | return VLC_EGENERIC; |
249 | | |
250 | | /* Allocate the memory needed to store the decoder's structure */ |
251 | 305k | decoder_sys_t *p_sys = malloc(sizeof(*p_sys)); |
252 | 305k | if( unlikely(p_sys == NULL) ) |
253 | 0 | { |
254 | 0 | avcodec_free_context( &avctx ); |
255 | 0 | return VLC_ENOMEM; |
256 | 0 | } |
257 | | |
258 | 305k | p_dec->p_sys = p_sys; |
259 | 305k | p_sys->p_context = avctx; |
260 | 305k | p_sys->p_codec = codec; |
261 | | |
262 | | // Initialize decoder extradata |
263 | 305k | InitDecoderConfig( p_dec, avctx ); |
264 | | |
265 | | /* ***** Open the codec ***** */ |
266 | 305k | if( OpenAudioCodec( p_dec ) < 0 ) |
267 | 73.6k | { |
268 | 73.6k | free( p_sys ); |
269 | 73.6k | avcodec_free_context( &avctx ); |
270 | 73.6k | return VLC_EGENERIC; |
271 | 73.6k | } |
272 | | |
273 | 232k | p_sys->i_reject_count = 0; |
274 | 232k | p_sys->b_extract = false; |
275 | 232k | p_sys->i_previous_channels = 0; |
276 | 232k | p_sys->i_previous_layout = 0; |
277 | 232k | p_sys->discontinuity = false; |
278 | | |
279 | | /* */ |
280 | | /* Try to set as much information as possible but do not trust it */ |
281 | 232k | SetupOutputFormat( p_dec, false ); |
282 | | |
283 | 232k | if( !p_dec->fmt_out.audio.i_rate ) |
284 | 15.1k | p_dec->fmt_out.audio.i_rate = p_dec->fmt_in->audio.i_rate; |
285 | 232k | if( p_dec->fmt_out.audio.i_rate ) |
286 | 216k | date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); |
287 | 232k | p_dec->fmt_out.audio.i_chan_mode = p_dec->fmt_in->audio.i_chan_mode; |
288 | | |
289 | 232k | p_dec->pf_decode = DecodeAudio; |
290 | 232k | p_dec->pf_flush = Flush; |
291 | | |
292 | 232k | return VLC_SUCCESS; |
293 | 305k | } |
294 | | |
295 | | /***************************************************************************** |
296 | | * Flush: |
297 | | *****************************************************************************/ |
298 | | static void Flush( decoder_t *p_dec ) |
299 | 0 | { |
300 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
301 | 0 | AVCodecContext *ctx = p_sys->p_context; |
302 | |
|
303 | 0 | if( avcodec_is_open( ctx ) ) |
304 | 0 | avcodec_flush_buffers( ctx ); |
305 | 0 | date_Set( &p_sys->end_date, VLC_TICK_INVALID ); |
306 | |
|
307 | 0 | if( ctx->codec_id == AV_CODEC_ID_MP2 || |
308 | 0 | ctx->codec_id == AV_CODEC_ID_MP3 ) |
309 | 0 | p_sys->i_reject_count = 3; |
310 | 0 | p_sys->discontinuity = false; |
311 | 0 | } |
312 | | |
313 | | /***************************************************************************** |
314 | | * DecodeBlock: Called to decode one frame |
315 | | *****************************************************************************/ |
316 | | static int DecodeBlock( decoder_t *p_dec, block_t **pp_block ) |
317 | 3.06M | { |
318 | 3.06M | decoder_sys_t *p_sys = p_dec->p_sys; |
319 | 3.06M | AVCodecContext *ctx = p_sys->p_context; |
320 | 3.06M | AVFrame *frame = NULL; |
321 | 3.06M | block_t *p_block = NULL; |
322 | 3.06M | bool b_error = false; |
323 | | |
324 | 3.06M | if( !ctx->extradata_size && p_dec->fmt_in->i_extra |
325 | 0 | && !avcodec_is_open( ctx ) ) |
326 | 0 | { |
327 | 0 | InitDecoderConfig( p_dec, ctx ); |
328 | 0 | if( OpenAudioCodec( p_dec ) < 0 ) |
329 | 0 | { |
330 | 0 | if( pp_block != NULL && *pp_block != NULL ) |
331 | 0 | block_Release( *pp_block ); |
332 | 0 | return VLCDEC_ECRITICAL; |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | 3.06M | if( !avcodec_is_open( ctx ) ) |
337 | 0 | { |
338 | 0 | if( pp_block ) |
339 | 0 | p_block = *pp_block; |
340 | 0 | goto drop; |
341 | 0 | } |
342 | | |
343 | 3.06M | if( pp_block == NULL ) /* Drain request */ |
344 | 849k | { |
345 | | /* we don't need to care about return val */ |
346 | 849k | (void) avcodec_send_packet( ctx, NULL ); |
347 | 849k | } |
348 | 2.21M | else |
349 | 2.21M | { |
350 | 2.21M | p_block = *pp_block; |
351 | 2.21M | } |
352 | | |
353 | 3.06M | if( p_block ) |
354 | 2.21M | { |
355 | 2.21M | if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) |
356 | 0 | { |
357 | 0 | Flush( p_dec ); |
358 | 0 | goto drop; |
359 | 0 | } |
360 | | |
361 | 2.21M | if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) |
362 | 7.20k | { |
363 | 7.20k | date_Set( &p_sys->end_date, VLC_TICK_INVALID ); |
364 | 7.20k | } |
365 | | |
366 | | /* We've just started the stream, wait for the first PTS. */ |
367 | 2.21M | if( p_block->i_pts == VLC_TICK_INVALID && |
368 | 1.67k | date_Get( &p_sys->end_date ) == VLC_TICK_INVALID ) |
369 | 1.67k | goto drop; |
370 | | |
371 | 2.21M | if( p_block->i_buffer <= 0 ) |
372 | 194 | goto drop; |
373 | | |
374 | 2.21M | if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 ) |
375 | 2.21M | { |
376 | 2.21M | *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + AV_INPUT_BUFFER_PADDING_SIZE ); |
377 | 2.21M | if( !p_block ) |
378 | 0 | goto end; |
379 | 2.21M | p_block->i_buffer -= AV_INPUT_BUFFER_PADDING_SIZE; |
380 | 2.21M | memset( &p_block->p_buffer[p_block->i_buffer], 0, AV_INPUT_BUFFER_PADDING_SIZE ); |
381 | | |
382 | 2.21M | p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED; |
383 | 2.21M | } |
384 | 2.21M | } |
385 | | |
386 | 3.06M | frame = av_frame_alloc(); |
387 | 3.06M | if (unlikely(frame == NULL)) |
388 | 0 | goto end; |
389 | | |
390 | 3.06M | bool send_failed = false; |
391 | 4.79M | for( int ret = 0; ret == 0; ) |
392 | 3.06M | { |
393 | | /* Feed in the loop as buffer could have been full on first iterations */ |
394 | 3.06M | if( p_block ) |
395 | 2.21M | { |
396 | 2.21M | AVPacket *pkt = av_packet_alloc(); |
397 | 2.21M | if( !pkt ) |
398 | 0 | goto end; |
399 | 2.21M | pkt->data = p_block->p_buffer; |
400 | 2.21M | pkt->size = p_block->i_buffer; |
401 | 2.21M | ret = avcodec_send_packet( ctx, pkt ); |
402 | 2.21M | av_packet_free(&pkt); |
403 | 2.21M | if( ret == 0 ) /* Block has been consumed */ |
404 | 1.34M | { |
405 | | /* Only set new pts from input block if it has been used, |
406 | | * otherwise let it be through interpolation */ |
407 | 1.34M | if( p_block->i_pts > date_Get( &p_sys->end_date ) ) |
408 | 1.33M | { |
409 | 1.33M | date_Set( &p_sys->end_date, p_block->i_pts ); |
410 | 1.33M | } |
411 | | |
412 | 1.34M | block_Release( p_block ); |
413 | 1.34M | *pp_block = p_block = NULL; |
414 | 1.34M | } |
415 | 868k | else if ( ret != AVERROR(EAGAIN) ) /* Errors other than buffer full */ |
416 | 857k | { |
417 | 857k | if( ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL) ) |
418 | 0 | goto end; |
419 | 857k | else |
420 | 857k | { |
421 | 857k | char errorstring[AV_ERROR_MAX_STRING_SIZE]; |
422 | 857k | if( !av_strerror( ret, errorstring, AV_ERROR_MAX_STRING_SIZE ) ) |
423 | 857k | msg_Err( p_dec, "%s", errorstring ); |
424 | | |
425 | | /* Signal an error, but continue to receive all output |
426 | | * frames. A discontinuity will be triggered for the |
427 | | * output frame coming right after the dropped one. */ |
428 | 857k | send_failed = true; |
429 | 857k | block_Release( p_block ); |
430 | 857k | *pp_block = p_block = NULL; |
431 | 857k | } |
432 | 857k | } |
433 | 2.21M | } |
434 | | |
435 | | /* Try to read one or multiple frames */ |
436 | 3.06M | ret = avcodec_receive_frame( ctx, frame ); |
437 | 3.06M | if( ret == 0 ) |
438 | 1.33M | { |
439 | 1.33M | #if LIBAVUTIL_VERSION_CHECK(57, 24, 100) |
440 | 1.33M | int channels = frame->ch_layout.nb_channels; |
441 | | #else |
442 | | int channels = ctx->channels; |
443 | | #endif |
444 | | /* checks and init from first decoded frame */ |
445 | 1.33M | if( channels <= 0 || channels > INPUT_CHAN_MAX |
446 | 1.33M | || ctx->sample_rate <= 0 ) |
447 | 493 | { |
448 | 493 | msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d", |
449 | 493 | channels, ctx->sample_rate ); |
450 | 493 | goto drop; |
451 | 493 | } |
452 | 1.33M | else if( p_dec->fmt_out.audio.i_rate != (unsigned int)ctx->sample_rate ) |
453 | 582 | { |
454 | 582 | date_Init( &p_sys->end_date, ctx->sample_rate, 1 ); |
455 | 582 | } |
456 | | |
457 | 1.33M | SetupOutputFormat( p_dec, true ); |
458 | 1.33M | if( decoder_UpdateAudioFormat( p_dec ) ) |
459 | 1.33M | goto drop; |
460 | | |
461 | 0 | block_t *p_converted = ConvertAVFrame( p_dec, frame ); /* Consumes frame */ |
462 | 0 | if( p_converted ) |
463 | 0 | { |
464 | | /* Silent unwanted samples */ |
465 | 0 | if( p_sys->i_reject_count > 0 ) |
466 | 0 | { |
467 | 0 | memset( p_converted->p_buffer, 0, p_converted->i_buffer ); |
468 | 0 | p_sys->i_reject_count--; |
469 | 0 | } |
470 | 0 | p_converted->i_buffer = p_converted->i_nb_samples |
471 | 0 | * p_dec->fmt_out.audio.i_bytes_per_frame; |
472 | 0 | p_converted->i_pts = date_Get( &p_sys->end_date ); |
473 | 0 | p_converted->i_length = date_Increment( &p_sys->end_date, |
474 | 0 | p_converted->i_nb_samples ) - p_converted->i_pts; |
475 | |
|
476 | 0 | if (p_sys->discontinuity) |
477 | 0 | { |
478 | 0 | p_sys->discontinuity = false; |
479 | 0 | p_converted->i_flags |= BLOCK_FLAG_DISCONTINUITY; |
480 | 0 | } |
481 | 0 | decoder_QueueAudio( p_dec, p_converted ); |
482 | 0 | } |
483 | | |
484 | | /* Prepare new frame */ |
485 | 0 | frame = av_frame_alloc(); |
486 | 0 | if (unlikely(frame == NULL)) |
487 | 0 | break; |
488 | 0 | } |
489 | 1.72M | else |
490 | 1.72M | { |
491 | | /* After draining, we need to reset decoder with a flush */ |
492 | 1.72M | if( ret == AVERROR_EOF ) |
493 | 846k | avcodec_flush_buffers( p_sys->p_context ); |
494 | 1.72M | av_frame_free( &frame ); |
495 | 1.72M | } |
496 | 3.06M | }; |
497 | | |
498 | 1.72M | if (send_failed) |
499 | 856k | { |
500 | | /* Signal a discontinuity for the next output frame. */ |
501 | 856k | p_sys->discontinuity = true; |
502 | 856k | } |
503 | | |
504 | 1.72M | return VLCDEC_SUCCESS; |
505 | | |
506 | 0 | end: |
507 | 0 | b_error = true; |
508 | 1.33M | drop: |
509 | | /* Signal a discontinuity for the next output frame. */ |
510 | 1.33M | p_sys->discontinuity = true; |
511 | 1.33M | if( pp_block ) |
512 | 1.33M | { |
513 | 1.33M | assert( *pp_block == p_block ); |
514 | 1.33M | *pp_block = NULL; |
515 | 1.33M | } |
516 | 1.33M | if( p_block != NULL ) |
517 | 11.9k | block_Release(p_block); |
518 | 1.33M | if( frame != NULL ) |
519 | 1.33M | av_frame_free( &frame ); |
520 | | |
521 | 1.33M | return (b_error) ? VLCDEC_ECRITICAL : VLCDEC_SUCCESS; |
522 | 1.33M | } |
523 | | |
524 | | static int DecodeAudio( decoder_t *p_dec, block_t *p_block ) |
525 | 3.06M | { |
526 | 3.06M | block_t **pp_block = p_block ? &p_block : NULL; |
527 | 3.06M | int i_ret; |
528 | 3.06M | do |
529 | 3.06M | { |
530 | 3.06M | i_ret = DecodeBlock( p_dec, pp_block ); |
531 | 3.06M | } |
532 | 3.06M | while( i_ret == VLCDEC_SUCCESS && pp_block && *pp_block ); |
533 | | |
534 | 3.06M | return i_ret; |
535 | 3.06M | } |
536 | | |
537 | | static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame ) |
538 | 0 | { |
539 | 0 | decoder_sys_t *p_sys = p_dec->p_sys; |
540 | 0 | AVCodecContext *ctx = p_sys->p_context; |
541 | 0 | block_t *p_block; |
542 | | |
543 | | /* Interleave audio if required */ |
544 | 0 | if( av_sample_fmt_is_planar( ctx->sample_fmt ) ) |
545 | 0 | { |
546 | 0 | p_block = block_Alloc(frame->linesize[0] * p_dec->fmt_out.audio.i_channels ); |
547 | 0 | if ( likely(p_block) ) |
548 | 0 | { |
549 | 0 | const void *planes[p_dec->fmt_out.audio.i_channels]; |
550 | 0 | for (int i = 0; i < p_dec->fmt_out.audio.i_channels; i++) |
551 | 0 | planes[i] = frame->extended_data[i]; |
552 | |
|
553 | 0 | aout_Interleave(p_block->p_buffer, planes, frame->nb_samples, |
554 | 0 | p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_format); |
555 | 0 | p_block->i_nb_samples = frame->nb_samples; |
556 | 0 | } |
557 | 0 | av_frame_free(&frame); |
558 | 0 | } |
559 | 0 | else |
560 | 0 | { |
561 | 0 | p_block = vlc_av_frame_Wrap(frame); |
562 | 0 | frame = NULL; |
563 | 0 | } |
564 | |
|
565 | 0 | if (p_sys->b_extract && p_block) |
566 | 0 | { /* TODO: do not drop channels... at least not here */ |
567 | 0 | block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame |
568 | 0 | * p_block->i_nb_samples ); |
569 | 0 | if( likely(p_buffer) ) |
570 | 0 | { |
571 | 0 | aout_ChannelExtract( p_buffer->p_buffer, |
572 | 0 | p_dec->fmt_out.audio.i_channels, |
573 | 0 | p_block->p_buffer, p_dec->fmt_out.audio.i_channels, |
574 | 0 | p_block->i_nb_samples, p_sys->pi_extraction, |
575 | 0 | p_dec->fmt_out.audio.i_bitspersample ); |
576 | 0 | p_buffer->i_nb_samples = p_block->i_nb_samples; |
577 | 0 | } |
578 | 0 | block_Release( p_block ); |
579 | 0 | p_block = p_buffer; |
580 | 0 | } |
581 | |
|
582 | 0 | return p_block; |
583 | 0 | } |
584 | | |
585 | | /***************************************************************************** |
586 | | * |
587 | | *****************************************************************************/ |
588 | | |
589 | | vlc_fourcc_t GetVlcAudioFormat( int fmt ) |
590 | 1.56M | { |
591 | 1.56M | static const vlc_fourcc_t fcc[] = { |
592 | 1.56M | [AV_SAMPLE_FMT_U8] = VLC_CODEC_U8, |
593 | 1.56M | [AV_SAMPLE_FMT_S16] = VLC_CODEC_S16N, |
594 | 1.56M | [AV_SAMPLE_FMT_S32] = VLC_CODEC_S32N, |
595 | 1.56M | [AV_SAMPLE_FMT_FLT] = VLC_CODEC_FL32, |
596 | 1.56M | [AV_SAMPLE_FMT_DBL] = VLC_CODEC_FL64, |
597 | 1.56M | [AV_SAMPLE_FMT_U8P] = VLC_CODEC_U8, |
598 | 1.56M | [AV_SAMPLE_FMT_S16P] = VLC_CODEC_S16N, |
599 | 1.56M | [AV_SAMPLE_FMT_S32P] = VLC_CODEC_S32N, |
600 | 1.56M | [AV_SAMPLE_FMT_FLTP] = VLC_CODEC_FL32, |
601 | 1.56M | [AV_SAMPLE_FMT_DBLP] = VLC_CODEC_FL64, |
602 | 1.56M | }; |
603 | 1.56M | if( ARRAY_SIZE(fcc) > (unsigned)fmt ) |
604 | 1.54M | return fcc[fmt]; |
605 | 21.7k | return VLC_CODEC_S16N; |
606 | 1.56M | } |
607 | | |
608 | | static const uint64_t pi_channels_map[][2] = |
609 | | { |
610 | | { AV_CH_FRONT_LEFT, AOUT_CHAN_LEFT }, |
611 | | { AV_CH_FRONT_RIGHT, AOUT_CHAN_RIGHT }, |
612 | | { AV_CH_FRONT_CENTER, AOUT_CHAN_CENTER }, |
613 | | { AV_CH_LOW_FREQUENCY, AOUT_CHAN_LFE }, |
614 | | { AV_CH_BACK_LEFT, AOUT_CHAN_REARLEFT }, |
615 | | { AV_CH_BACK_RIGHT, AOUT_CHAN_REARRIGHT }, |
616 | | { AV_CH_FRONT_LEFT_OF_CENTER, 0 }, |
617 | | { AV_CH_FRONT_RIGHT_OF_CENTER, 0 }, |
618 | | { AV_CH_BACK_CENTER, AOUT_CHAN_REARCENTER }, |
619 | | { AV_CH_SIDE_LEFT, AOUT_CHAN_MIDDLELEFT }, |
620 | | { AV_CH_SIDE_RIGHT, AOUT_CHAN_MIDDLERIGHT }, |
621 | | { AV_CH_TOP_CENTER, 0 }, |
622 | | { AV_CH_TOP_FRONT_LEFT, 0 }, |
623 | | { AV_CH_TOP_FRONT_CENTER, 0 }, |
624 | | { AV_CH_TOP_FRONT_RIGHT, 0 }, |
625 | | { AV_CH_TOP_BACK_LEFT, 0 }, |
626 | | { AV_CH_TOP_BACK_CENTER, 0 }, |
627 | | { AV_CH_TOP_BACK_RIGHT, 0 }, |
628 | | { AV_CH_STEREO_LEFT, 0 }, |
629 | | { AV_CH_STEREO_RIGHT, 0 }, |
630 | | { 0, 0 }, |
631 | | }; |
632 | | |
633 | | static void SetupOutputFormat( decoder_t *p_dec, bool b_trust ) |
634 | 1.56M | { |
635 | 1.56M | decoder_sys_t *p_sys = p_dec->p_sys; |
636 | | |
637 | 1.56M | p_dec->fmt_out.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt ); |
638 | 1.56M | p_dec->fmt_out.audio.channel_type = p_dec->fmt_in->audio.channel_type; |
639 | 1.56M | p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec; |
640 | 1.56M | p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate; |
641 | | |
642 | | /* */ |
643 | 1.56M | #if API_CHANNEL_LAYOUT_STRUCT |
644 | 1.56M | if( p_sys->i_previous_channels == p_sys->p_context->ch_layout.nb_channels && |
645 | 1.20M | p_sys->i_previous_layout == p_sys->p_context->ch_layout.u.mask ) |
646 | 1.20M | return; |
647 | 368k | if( b_trust ) |
648 | 147k | { |
649 | 147k | p_sys->i_previous_channels = p_sys->p_context->ch_layout.nb_channels; |
650 | 147k | p_sys->i_previous_layout = p_sys->p_context->ch_layout.u.mask; |
651 | 147k | } |
652 | | #else |
653 | | if( p_sys->i_previous_channels == p_sys->p_context->channels && |
654 | | p_sys->i_previous_layout == p_sys->p_context->channel_layout ) |
655 | | return; |
656 | | if( b_trust ) |
657 | | { |
658 | | p_sys->i_previous_channels = p_sys->p_context->channels; |
659 | | p_sys->i_previous_layout = p_sys->p_context->channel_layout; |
660 | | } |
661 | | #endif |
662 | | |
663 | 368k | int i_channels_src = 0; |
664 | 368k | #if API_CHANNEL_LAYOUT_STRUCT |
665 | 368k | uint64_t channel_layout_mask = p_sys->p_context->ch_layout.u.mask; |
666 | 368k | int channel_count = p_sys->p_context->ch_layout.nb_channels; |
667 | | #else |
668 | | uint64_t channel_layout_mask = |
669 | | p_sys->p_context->channel_layout ? p_sys->p_context->channel_layout : |
670 | | (uint64_t)av_get_default_channel_layout( p_sys->p_context->channels ); |
671 | | int channel_count = p_sys->p_context->channels; |
672 | | #endif |
673 | | |
674 | 368k | if( channel_layout_mask ) |
675 | 364k | { |
676 | 364k | uint32_t* pi_order_src = calloc(channel_count,sizeof(uint32_t)); |
677 | | |
678 | 364k | if( unlikely(pi_order_src == NULL) ) |
679 | 0 | { |
680 | 0 | p_dec->fmt_out.audio.i_physical_channels = 0; |
681 | 0 | p_dec->fmt_out.audio.i_channels = channel_count; |
682 | |
|
683 | 0 | aout_FormatPrepare(&p_dec->fmt_out.audio); |
684 | 0 | p_sys->b_extract = false; |
685 | 0 | return; |
686 | 0 | } |
687 | | |
688 | 364k | assert(stdc_count_ones(channel_layout_mask) == (unsigned)channel_count); |
689 | | |
690 | 2.07M | for( unsigned i = 0; pi_channels_map[i][0] |
691 | 2.06M | && i_channels_src < channel_count; i++ ) |
692 | 1.70M | { |
693 | 1.70M | if( channel_layout_mask & pi_channels_map[i][0] ) |
694 | 1.22M | pi_order_src[i_channels_src++] = pi_channels_map[i][1]; |
695 | 1.70M | } |
696 | | |
697 | 364k | if( i_channels_src != channel_count && b_trust ) |
698 | 364k | msg_Err( p_dec, "Channel layout not understood" ); |
699 | | |
700 | | /* Detect special dual mono case */ |
701 | 364k | if( i_channels_src == 2 && pi_order_src[0] == AOUT_CHAN_CENTER |
702 | 6.52k | && pi_order_src[1] == AOUT_CHAN_CENTER ) |
703 | 0 | { |
704 | 0 | p_dec->fmt_out.audio.i_chan_mode |= AOUT_CHANMODE_DUALMONO; |
705 | 0 | pi_order_src[0] = AOUT_CHAN_LEFT; |
706 | 0 | pi_order_src[1] = AOUT_CHAN_RIGHT; |
707 | 0 | } |
708 | | |
709 | 364k | uint32_t i_layout_dst; |
710 | 364k | int i_channels_dst; |
711 | 364k | p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction, |
712 | 364k | &i_layout_dst, &i_channels_dst, |
713 | 364k | NULL, pi_order_src, i_channels_src ); |
714 | 364k | if( i_channels_dst != i_channels_src && b_trust ) |
715 | 364k | msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst ); |
716 | | |
717 | | /* No reordering for Ambisonic order 1 channels encoded in AAC... */ |
718 | 364k | if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_AMBISONICS |
719 | 364k | && p_dec->fmt_in->i_codec == VLC_CODEC_MP4A |
720 | 0 | && i_channels_src == 4) |
721 | 0 | p_sys->b_extract = false; |
722 | | |
723 | 364k | p_dec->fmt_out.audio.i_physical_channels = i_layout_dst; |
724 | 364k | free(pi_order_src); |
725 | 364k | } |
726 | 3.77k | else |
727 | 3.77k | { |
728 | 3.77k | msg_Warn( p_dec, "no channel layout found"); |
729 | 3.77k | p_dec->fmt_out.audio.i_physical_channels = 0; |
730 | 3.77k | p_dec->fmt_out.audio.i_channels = channel_count; |
731 | 3.77k | } |
732 | | |
733 | 368k | aout_FormatPrepare( &p_dec->fmt_out.audio ); |
734 | 368k | } |