1 /*****************************************************************************
2 * libavsmash_audio.c / libavsmash_audio.cpp
3 *****************************************************************************
4 * Copyright (C) 2012-2015 L-SMASH Works project
5 *
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
20
21 /* This file is available under an ISC license. */
22
23 #include "cpp_compat.h"
24
25 #ifdef __cplusplus
26 extern "C"
27 {
28 #endif /* __cplusplus */
29 #include <lsmash.h>
30 #include <libavformat/avformat.h>
31 #include <libavcodec/avcodec.h>
32 #include <libavresample/avresample.h>
33 #include <libavutil/mem.h>
34 #include <libavutil/opt.h>
35 #ifdef __cplusplus
36 }
37 #endif /* __cplusplus */
38
39 #include "utils.h"
40 #include "audio_output.h"
41 #include "resample.h"
42 #include "libavsmash.h"
43 #include "libavsmash_audio.h"
44 #include "libavsmash_audio_internal.h"
45
46 /*****************************************************************************
47 * Allocators / Deallocators
48 *****************************************************************************/
libavsmash_audio_alloc_decode_handler(void)49 libavsmash_audio_decode_handler_t *libavsmash_audio_alloc_decode_handler
50 (
51 void
52 )
53 {
54 libavsmash_audio_decode_handler_t *adhp = (libavsmash_audio_decode_handler_t *)lw_malloc_zero( sizeof(libavsmash_audio_decode_handler_t) );
55 if( !adhp )
56 return NULL;
57 adhp->frame_buffer = av_frame_alloc();
58 if( !adhp->frame_buffer )
59 {
60 libavsmash_audio_free_decode_handler( adhp );
61 return NULL;
62 }
63 return adhp;
64 }
65
libavsmash_audio_alloc_output_handler(void)66 libavsmash_audio_output_handler_t *libavsmash_audio_alloc_output_handler
67 (
68 void
69 )
70 {
71 return (libavsmash_audio_output_handler_t *)lw_malloc_zero( sizeof(libavsmash_audio_output_handler_t) );
72 }
73
libavsmash_audio_free_decode_handler(libavsmash_audio_decode_handler_t * adhp)74 void libavsmash_audio_free_decode_handler
75 (
76 libavsmash_audio_decode_handler_t *adhp
77 )
78 {
79 if( !adhp )
80 return;
81 av_frame_free( &adhp->frame_buffer );
82 cleanup_configuration( &adhp->config );
83 lw_free( adhp );
84 }
85
libavsmash_audio_free_output_handler(libavsmash_audio_output_handler_t * aohp)86 void libavsmash_audio_free_output_handler
87 (
88 libavsmash_audio_output_handler_t *aohp
89 )
90 {
91 if( !aohp )
92 return;
93 lw_cleanup_audio_output_handler( aohp );
94 lw_free( aohp );
95 }
96
libavsmash_audio_free_decode_handler_ptr(libavsmash_audio_decode_handler_t ** adhpp)97 void libavsmash_audio_free_decode_handler_ptr
98 (
99 libavsmash_audio_decode_handler_t **adhpp
100 )
101 {
102 if( !adhpp || !*adhpp )
103 return;
104 libavsmash_audio_free_decode_handler( *adhpp );
105 *adhpp = NULL;
106 }
107
libavsmash_audio_free_output_handler_ptr(libavsmash_audio_output_handler_t ** aohpp)108 void libavsmash_audio_free_output_handler_ptr
109 (
110 libavsmash_audio_output_handler_t **aohpp
111 )
112 {
113 if( !aohpp || !*aohpp )
114 return;
115 libavsmash_audio_free_output_handler( *aohpp );
116 *aohpp = NULL;
117 }
118
119 /*****************************************************************************
120 * Setters
121 *****************************************************************************/
libavsmash_audio_set_root(libavsmash_audio_decode_handler_t * adhp,lsmash_root_t * root)122 void libavsmash_audio_set_root
123 (
124 libavsmash_audio_decode_handler_t *adhp,
125 lsmash_root_t *root
126 )
127 {
128 adhp->root = root;
129 }
130
libavsmash_audio_set_track_id(libavsmash_audio_decode_handler_t * adhp,uint32_t track_id)131 void libavsmash_audio_set_track_id
132 (
133 libavsmash_audio_decode_handler_t *adhp,
134 uint32_t track_id
135 )
136 {
137 adhp->track_id = track_id;
138 }
139
libavsmash_audio_set_preferred_decoder_names(libavsmash_audio_decode_handler_t * adhp,const char ** preferred_decoder_names)140 void libavsmash_audio_set_preferred_decoder_names
141 (
142 libavsmash_audio_decode_handler_t *adhp,
143 const char **preferred_decoder_names
144 )
145 {
146 adhp->config.preferred_decoder_names = preferred_decoder_names;
147 }
148
149 /*****************************************************************************
150 * Getters
151 *****************************************************************************/
libavsmash_audio_get_root(libavsmash_audio_decode_handler_t * adhp)152 lsmash_root_t *libavsmash_audio_get_root
153 (
154 libavsmash_audio_decode_handler_t *adhp
155 )
156 {
157 return adhp ? adhp->root : NULL;
158 }
159
libavsmash_audio_get_track_id(libavsmash_audio_decode_handler_t * adhp)160 uint32_t libavsmash_audio_get_track_id
161 (
162 libavsmash_audio_decode_handler_t *adhp
163 )
164 {
165 return adhp ? adhp->track_id : 0;
166 }
167
libavsmash_audio_get_codec_context(libavsmash_audio_decode_handler_t * adhp)168 AVCodecContext *libavsmash_audio_get_codec_context
169 (
170 libavsmash_audio_decode_handler_t *adhp
171 )
172 {
173 return adhp ? adhp->config.ctx : NULL;
174 }
175
libavsmash_audio_get_preferred_decoder_names(libavsmash_audio_decode_handler_t * adhp)176 const char **libavsmash_audio_get_preferred_decoder_names
177 (
178 libavsmash_audio_decode_handler_t *adhp
179 )
180 {
181 return adhp ? adhp->config.preferred_decoder_names : NULL;
182 }
183
libavsmash_audio_get_error(libavsmash_audio_decode_handler_t * adhp)184 int libavsmash_audio_get_error
185 (
186 libavsmash_audio_decode_handler_t *adhp
187 )
188 {
189 return adhp ? adhp->config.error : -1;
190 }
191
libavsmash_audio_get_best_used_channel_layout(libavsmash_audio_decode_handler_t * adhp)192 uint64_t libavsmash_audio_get_best_used_channel_layout
193 (
194 libavsmash_audio_decode_handler_t *adhp
195 )
196 {
197 return adhp ? adhp->config.prefer.channel_layout : 0;
198 }
199
libavsmash_audio_get_best_used_sample_format(libavsmash_audio_decode_handler_t * adhp)200 enum AVSampleFormat libavsmash_audio_get_best_used_sample_format
201 (
202 libavsmash_audio_decode_handler_t *adhp
203 )
204 {
205 return adhp ? adhp->config.prefer.sample_format : AV_SAMPLE_FMT_NONE;
206 }
207
libavsmash_audio_get_best_used_sample_rate(libavsmash_audio_decode_handler_t * adhp)208 int libavsmash_audio_get_best_used_sample_rate
209 (
210 libavsmash_audio_decode_handler_t *adhp
211 )
212 {
213 return adhp ? adhp->config.prefer.sample_rate : 0;
214 }
215
libavsmash_audio_get_best_used_bits_per_sample(libavsmash_audio_decode_handler_t * adhp)216 int libavsmash_audio_get_best_used_bits_per_sample
217 (
218 libavsmash_audio_decode_handler_t *adhp
219 )
220 {
221 return adhp ? adhp->config.prefer.bits_per_sample : 0;
222 }
223
libavsmash_audio_get_log_handler(libavsmash_audio_decode_handler_t * adhp)224 lw_log_handler_t *libavsmash_audio_get_log_handler
225 (
226 libavsmash_audio_decode_handler_t *adhp
227 )
228 {
229 return adhp ? &adhp->config.lh : NULL;
230 }
231
libavsmash_audio_get_sample_count(libavsmash_audio_decode_handler_t * adhp)232 uint32_t libavsmash_audio_get_sample_count
233 (
234 libavsmash_audio_decode_handler_t *adhp
235 )
236 {
237 return adhp ? adhp->frame_count : 0;
238 }
239
libavsmash_audio_get_media_timescale(libavsmash_audio_decode_handler_t * adhp)240 uint32_t libavsmash_audio_get_media_timescale
241 (
242 libavsmash_audio_decode_handler_t *adhp
243 )
244 {
245 return adhp ? adhp->media_timescale : 0;
246 }
247
libavsmash_audio_get_media_duration(libavsmash_audio_decode_handler_t * adhp)248 uint64_t libavsmash_audio_get_media_duration
249 (
250 libavsmash_audio_decode_handler_t *adhp
251 )
252 {
253 return adhp ? adhp->media_duration : 0;
254 }
255
libavsmash_audio_get_min_cts(libavsmash_audio_decode_handler_t * adhp)256 uint64_t libavsmash_audio_get_min_cts
257 (
258 libavsmash_audio_decode_handler_t *adhp
259 )
260 {
261 return adhp ? adhp->min_cts : UINT64_MAX;
262 }
263
264 /*****************************************************************************
265 * Fetchers
266 *****************************************************************************/
libavsmash_audio_fetch_sample_count(libavsmash_audio_decode_handler_t * adhp)267 static uint32_t libavsmash_audio_fetch_sample_count
268 (
269 libavsmash_audio_decode_handler_t *adhp
270 )
271 {
272 if( !adhp )
273 return 0;
274 adhp->frame_count = lsmash_get_sample_count_in_media_timeline( adhp->root, adhp->track_id );
275 return adhp->frame_count;
276 }
277
libavsmash_audio_fetch_media_timescale(libavsmash_audio_decode_handler_t * adhp)278 static uint32_t libavsmash_audio_fetch_media_timescale
279 (
280 libavsmash_audio_decode_handler_t *adhp
281 )
282 {
283 if( !adhp )
284 return 0;
285 lsmash_media_parameters_t media_param;
286 lsmash_initialize_media_parameters( &media_param );
287 if( lsmash_get_media_parameters( adhp->root, adhp->track_id, &media_param ) < 0 )
288 return 0;
289 adhp->media_timescale = media_param.timescale;
290 return adhp->media_timescale;
291 }
292
libavsmash_audio_fetch_media_duration(libavsmash_audio_decode_handler_t * adhp)293 static uint64_t libavsmash_audio_fetch_media_duration
294 (
295 libavsmash_audio_decode_handler_t *adhp
296 )
297 {
298 if( !adhp )
299 return 0;
300 adhp->media_duration = lsmash_get_media_duration_from_media_timeline( adhp->root, adhp->track_id );
301 return adhp->media_duration;
302 }
303
304 /* This function assume that no audio frame reorderings in composition timeline. */
libavsmash_audio_fetch_min_cts(libavsmash_audio_decode_handler_t * adhp)305 static uint64_t libavsmash_audio_fetch_min_cts
306 (
307 libavsmash_audio_decode_handler_t *adhp
308 )
309 {
310 if( !adhp || lsmash_get_cts_from_media_timeline( adhp->root, adhp->track_id, 1, &adhp->min_cts ) < 0 )
311 return UINT64_MAX;
312 return adhp->min_cts;
313 }
314
315 /*****************************************************************************
316 * Others
317 *****************************************************************************/
libavsmash_audio_get_track(libavsmash_audio_decode_handler_t * adhp,uint32_t track_number)318 int libavsmash_audio_get_track
319 (
320 libavsmash_audio_decode_handler_t *adhp,
321 uint32_t track_number
322 )
323 {
324 lw_log_handler_t *lhp = libavsmash_audio_get_log_handler( adhp );
325 uint32_t track_id =
326 libavsmash_get_track_by_media_type
327 (
328 libavsmash_audio_get_root( adhp ),
329 ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK,
330 track_number,
331 lhp
332 );
333 if( track_id == 0 )
334 return -1;
335 libavsmash_audio_set_track_id( adhp, track_id );
336 (void)libavsmash_audio_fetch_sample_count ( adhp );
337 (void)libavsmash_audio_fetch_media_duration ( adhp );
338 (void)libavsmash_audio_fetch_media_timescale( adhp );
339 (void)libavsmash_audio_fetch_min_cts ( adhp );
340 return 0;
341 }
342
libavsmash_audio_initialize_decoder_configuration(libavsmash_audio_decode_handler_t * adhp,AVFormatContext * format_ctx,int threads)343 int libavsmash_audio_initialize_decoder_configuration
344 (
345 libavsmash_audio_decode_handler_t *adhp,
346 AVFormatContext *format_ctx,
347 int threads
348 )
349 {
350 char error_string[128] = { 0 };
351 if( libavsmash_audio_get_summaries( adhp ) < 0 )
352 return -1;
353 /* libavformat */
354 uint32_t type = AVMEDIA_TYPE_AUDIO;
355 uint32_t i;
356 for( i = 0; i < format_ctx->nb_streams && format_ctx->streams[i]->codecpar->codec_type != type; i++ );
357 if( i == format_ctx->nb_streams )
358 {
359 strcpy( error_string, "Failed to find stream by libavformat.\n" );
360 goto fail;
361 }
362 /* libavcodec */
363 AVCodecParameters *codecpar = format_ctx->streams[i]->codecpar;
364 if( libavsmash_find_and_open_decoder( &adhp->config, codecpar, threads, 0 ) < 0 )
365 {
366 strcpy( error_string, "Failed to find and open the audio decoder.\n" );
367 goto fail;
368 }
369 return initialize_decoder_configuration( adhp->root, adhp->track_id, &adhp->config );
370 fail:;
371 lw_log_handler_t *lhp = libavsmash_audio_get_log_handler( adhp );
372 lw_log_show( lhp, LW_LOG_FATAL, "%s", error_string );
373 return -1;
374 }
375
libavsmash_audio_get_summaries(libavsmash_audio_decode_handler_t * adhp)376 int libavsmash_audio_get_summaries
377 (
378 libavsmash_audio_decode_handler_t *adhp
379 )
380 {
381 return get_summaries( adhp->root, adhp->track_id, &adhp->config );
382 }
383
libavsmash_audio_force_seek(libavsmash_audio_decode_handler_t * adhp)384 void libavsmash_audio_force_seek
385 (
386 libavsmash_audio_decode_handler_t *adhp
387 )
388 {
389 /* Force seek before the next reading. */
390 adhp->next_pcm_sample_number = adhp->pcm_sample_count + 1;
391 }
392
libavsmash_audio_clear_error(libavsmash_audio_decode_handler_t * adhp)393 void libavsmash_audio_clear_error
394 (
395 libavsmash_audio_decode_handler_t *adhp
396 )
397 {
398 adhp->config.error = 0;
399 }
400
libavsmash_audio_close_codec_context(libavsmash_audio_decode_handler_t * adhp)401 void libavsmash_audio_close_codec_context
402 (
403 libavsmash_audio_decode_handler_t *adhp
404 )
405 {
406 if( !adhp || !adhp->config.ctx )
407 return;
408 avcodec_free_context( &adhp->config.ctx );
409 }
410
libavsmash_audio_apply_delay(libavsmash_audio_decode_handler_t * adhp,int64_t delay)411 void libavsmash_audio_apply_delay
412 (
413 libavsmash_audio_decode_handler_t *adhp,
414 int64_t delay
415 )
416 {
417 if( !adhp )
418 return;
419 adhp->pcm_sample_count += delay;
420 }
421
libavsmash_audio_set_implicit_preroll(libavsmash_audio_decode_handler_t * adhp)422 void libavsmash_audio_set_implicit_preroll
423 (
424 libavsmash_audio_decode_handler_t *adhp
425 )
426 {
427 if( !adhp )
428 return;
429 adhp->implicit_preroll = 1;
430 }
431
count_sequence_output_pcm_samples(uint64_t sequence_pcm_count,int current_sample_rate,int output_sample_rate)432 static inline uint64_t count_sequence_output_pcm_samples
433 (
434 uint64_t sequence_pcm_count,
435 int current_sample_rate,
436 int output_sample_rate
437 )
438 {
439 uint64_t resampled_sample_count;
440 if( output_sample_rate == current_sample_rate )
441 resampled_sample_count = sequence_pcm_count;
442 else
443 resampled_sample_count = av_rescale_rnd( sequence_pcm_count, output_sample_rate, current_sample_rate, AV_ROUND_UP );
444 return resampled_sample_count;
445 }
446
get_frame_length(libavsmash_audio_decode_handler_t * adhp,uint32_t frame_number,uint64_t * frame_length,extended_summary_t ** esp)447 static int get_frame_length
448 (
449 libavsmash_audio_decode_handler_t *adhp,
450 uint32_t frame_number,
451 uint64_t *frame_length,
452 extended_summary_t **esp
453 )
454 {
455 lsmash_sample_t sample;
456 if( lsmash_get_sample_info_from_media_timeline( adhp->root, adhp->track_id, frame_number, &sample ) < 0 )
457 return -1;
458 *esp = &adhp->config.entries[ sample.index - 1 ].extended;
459 extended_summary_t *es = *esp;
460 if( es->frame_length == 0 )
461 {
462 /* variable frame length
463 * Guess the frame length from sample duration. */
464 uint32_t frame_length_32;
465 if( lsmash_get_sample_delta_from_media_timeline( adhp->root, adhp->track_id, frame_number, &frame_length_32 ) < 0 )
466 return -1;
467 int64_t temp_frame_length = av_rescale( frame_length_32, es->sample_rate, adhp->media_timescale );
468 if( temp_frame_length < 0 )
469 return -1;
470 *frame_length = (uint64_t)temp_frame_length;
471 }
472 else
473 /* constant frame length */
474 *frame_length = (uint64_t)es->frame_length;
475 return 0;
476 }
477
478 /* Count the number of whole output PCM samples. */
libavsmash_audio_count_overall_pcm_samples(libavsmash_audio_decode_handler_t * adhp,int output_sample_rate,uint64_t start_time)479 uint64_t libavsmash_audio_count_overall_pcm_samples
480 (
481 libavsmash_audio_decode_handler_t *adhp,
482 int output_sample_rate,
483 uint64_t start_time
484 )
485 {
486 codec_configuration_t *config = &adhp->config;
487 extended_summary_t *es = NULL;
488 int current_sample_rate = 0;
489 uint64_t current_frame_length = 0;
490 uint64_t sequence_pcm_count = 0;
491 uint64_t prior_sequences_pcm_count = 0;
492 uint64_t overall_pcm_count = 0;
493 /* Count the number of output PCM audio samples in each sequence. */
494 for( uint32_t i = 1; i <= adhp->frame_count; i++ )
495 {
496 uint64_t frame_length;
497 if( get_frame_length( adhp, i, &frame_length, &es ) < 0 )
498 continue;
499 if( (current_sample_rate != es->sample_rate && es->sample_rate > 0)
500 || current_frame_length != frame_length )
501 {
502 /* Encountered a new sequence. */
503 if( current_sample_rate > 0 )
504 {
505 prior_sequences_pcm_count += sequence_pcm_count;
506 /* Add the number of output PCM audio samples in the previous sequence. */
507 overall_pcm_count += count_sequence_output_pcm_samples( sequence_pcm_count,
508 current_sample_rate,
509 output_sample_rate );
510 sequence_pcm_count = 0;
511 }
512 current_sample_rate = es->sample_rate > 0 ? es->sample_rate : config->ctx->sample_rate;
513 current_frame_length = frame_length;
514 }
515 sequence_pcm_count += frame_length;
516 }
517 if( !es || (sequence_pcm_count == 0 && overall_pcm_count == 0) )
518 {
519 adhp->pcm_sample_count = 0;
520 return 0;
521 }
522 current_sample_rate = es->sample_rate > 0 ? es->sample_rate : config->ctx->sample_rate;
523 overall_pcm_count += count_sequence_output_pcm_samples( sequence_pcm_count,
524 current_sample_rate,
525 output_sample_rate );
526 overall_pcm_count -= av_rescale( start_time, output_sample_rate, adhp->media_timescale );
527 adhp->pcm_sample_count = overall_pcm_count;
528 return overall_pcm_count;
529 }
530
531 /* Get pre-roll to make output samples assured to be correct, and update the target frame number if needed.
532 * Some audio CODEC requires pre-roll for correct composition. */
get_preroll_samples(libavsmash_audio_decode_handler_t * adhp,uint64_t skip_decoded_samples,uint32_t * frame_number)533 static uint64_t get_preroll_samples
534 (
535 libavsmash_audio_decode_handler_t *adhp,
536 uint64_t skip_decoded_samples,
537 uint32_t *frame_number
538 )
539 {
540 lsmash_sample_property_t prop;
541 if( lsmash_get_sample_property_from_media_timeline( adhp->root, adhp->track_id, *frame_number, &prop ) < 0 )
542 return 0;
543 if( prop.pre_roll.distance == 0 )
544 {
545 if( skip_decoded_samples == 0 || !adhp->implicit_preroll )
546 return 0;
547 /* Estimate pre-roll distance. */
548 for( uint32_t i = 1; i <= adhp->frame_count || skip_decoded_samples; i++ )
549 {
550 extended_summary_t *dummy = NULL;
551 uint64_t frame_length;
552 if( get_frame_length( adhp, i, &frame_length, &dummy ) < 0 )
553 break;
554 if( skip_decoded_samples < frame_length )
555 skip_decoded_samples = 0;
556 else
557 skip_decoded_samples -= frame_length;
558 ++ prop.pre_roll.distance;
559 }
560 }
561 uint64_t preroll_samples = 0;
562 for( uint32_t i = 0; i < prop.pre_roll.distance; i++ )
563 {
564 if( *frame_number > 1 )
565 --(*frame_number);
566 else
567 break;
568 extended_summary_t *dummy = NULL;
569 uint64_t frame_length;
570 if( get_frame_length( adhp, *frame_number, &frame_length, &dummy ) < 0 )
571 break;
572 preroll_samples += frame_length;
573 }
574 return preroll_samples;
575 }
576
find_start_audio_frame(libavsmash_audio_decode_handler_t * adhp,int output_sample_rate,uint64_t skip_decoded_samples,uint64_t start_frame_pos,uint64_t * start_offset)577 static int find_start_audio_frame
578 (
579 libavsmash_audio_decode_handler_t *adhp,
580 int output_sample_rate,
581 uint64_t skip_decoded_samples, /* at output sampling rate */
582 uint64_t start_frame_pos, /* at output sampling rate */
583 uint64_t *start_offset /* at codec sampling rate since trimming by this before sending resampler */
584 )
585 {
586 uint32_t frame_number = 1;
587 uint64_t current_frame_pos = 0;
588 uint64_t next_frame_pos = 0;
589 int current_sample_rate = 0;
590 uint64_t current_frame_length = 0;
591 uint64_t decoded_pcm_sample_count = 0; /* the number of accumulated PCM samples before resampling per sequence */
592 uint64_t resampled_sample_count = 0; /* the number of accumulated PCM samples after resampling per sequence */
593 uint64_t prior_sequences_resampled_count = 0; /* the number of accumulated PCM samples of all prior sequences */
594 do
595 {
596 current_frame_pos = next_frame_pos;
597 extended_summary_t *es = NULL;
598 uint64_t frame_length;
599 if( get_frame_length( adhp, frame_number, &frame_length, &es ) < 0 )
600 {
601 ++frame_number;
602 continue;
603 }
604 if( (current_sample_rate != es->sample_rate && es->sample_rate > 0)
605 || current_frame_length != frame_length )
606 {
607 /* Encountered a new sequence. */
608 prior_sequences_resampled_count += resampled_sample_count;
609 decoded_pcm_sample_count = 0;
610 current_sample_rate = es->sample_rate > 0 ? es->sample_rate : adhp->config.ctx->sample_rate;
611 current_frame_length = frame_length;
612 }
613 decoded_pcm_sample_count += frame_length;
614 resampled_sample_count = count_sequence_output_pcm_samples( decoded_pcm_sample_count,
615 current_sample_rate,
616 output_sample_rate );
617 next_frame_pos = prior_sequences_resampled_count + resampled_sample_count;
618 if( start_frame_pos < next_frame_pos )
619 break;
620 ++frame_number;
621 } while( frame_number <= adhp->frame_count );
622 *start_offset = start_frame_pos - current_frame_pos;
623 *start_offset = av_rescale_rnd( *start_offset, current_sample_rate, output_sample_rate, AV_ROUND_UP );
624 *start_offset += get_preroll_samples( adhp, av_rescale( skip_decoded_samples, current_sample_rate, output_sample_rate ), &frame_number );
625 return frame_number;
626 }
627
libavsmash_audio_get_pcm_samples(libavsmash_audio_decode_handler_t * adhp,libavsmash_audio_output_handler_t * aohp,void * buf,int64_t start,int64_t wanted_length)628 uint64_t libavsmash_audio_get_pcm_samples
629 (
630 libavsmash_audio_decode_handler_t *adhp,
631 libavsmash_audio_output_handler_t *aohp,
632 void *buf,
633 int64_t start,
634 int64_t wanted_length
635 )
636 {
637 codec_configuration_t *config = &adhp->config;
638 if( config->error )
639 return 0;
640 uint32_t frame_number;
641 uint64_t output_length = 0;
642 enum audio_output_flag output_flags;
643 aohp->request_length = wanted_length;
644 if( start > 0 && start == adhp->next_pcm_sample_number )
645 {
646 frame_number = adhp->last_frame_number;
647 output_flags = AUDIO_OUTPUT_NO_FLAGS;
648 output_length += output_pcm_samples_from_buffer( aohp, adhp->frame_buffer, (uint8_t **)&buf, &output_flags );
649 if( output_flags & AUDIO_OUTPUT_ENOUGH )
650 goto audio_out;
651 if( adhp->packet.size <= 0 )
652 ++frame_number;
653 aohp->output_sample_offset = 0;
654 }
655 else
656 {
657 /* Seek audio stream. */
658 if( flush_resampler_buffers( aohp->avr_ctx ) < 0 )
659 {
660 config->error = 1;
661 lw_log_show( &config->lh, LW_LOG_FATAL,
662 "Failed to flush resampler buffers.\n"
663 "It is recommended you reopen the file." );
664 return 0;
665 }
666 libavsmash_flush_buffers( config );
667 if( config->error )
668 return 0;
669 adhp->next_pcm_sample_number = 0;
670 adhp->last_frame_number = 0;
671 uint64_t start_frame_pos;
672 if( start >= 0 )
673 start_frame_pos = start;
674 else
675 {
676 uint64_t silence_length = -start;
677 put_silence_audio_samples( (int)(silence_length * aohp->output_block_align), aohp->output_bits_per_sample == 8, (uint8_t **)&buf );
678 output_length += silence_length;
679 aohp->request_length -= silence_length;
680 start_frame_pos = 0;
681 }
682 start_frame_pos += aohp->skip_decoded_samples;
683 frame_number = find_start_audio_frame( adhp, aohp->output_sample_rate, aohp->skip_decoded_samples, start_frame_pos, &aohp->output_sample_offset );
684 }
685 do
686 {
687 AVPacket *pkt = &adhp->packet;
688 if( frame_number > adhp->frame_count )
689 {
690 if( config->delay_count || !(output_flags & AUDIO_OUTPUT_ENOUGH) )
691 {
692 /* Null packet */
693 av_init_packet( pkt );
694 pkt->data = NULL;
695 pkt->size = 0;
696 if( config->delay_count )
697 config->delay_count -= 1;
698 }
699 else
700 goto audio_out;
701 }
702 else if( pkt->size <= 0 )
703 /* Getting an audio packet must be after flushing all remaining samples in resampler's FIFO buffer. */
704 while( get_sample( adhp->root, adhp->track_id, frame_number, config, pkt ) == 2 )
705 if( config->update_pending )
706 /* Update the decoder configuration. */
707 update_configuration( adhp->root, adhp->track_id, config );
708 /* Decode and output from an audio packet. */
709 output_flags = AUDIO_OUTPUT_NO_FLAGS;
710 output_length += output_pcm_samples_from_packet( aohp, config->ctx, pkt, adhp->frame_buffer, (uint8_t **)&buf, &output_flags );
711 if( output_flags & AUDIO_DECODER_DELAY )
712 ++ config->delay_count;
713 if( output_flags & AUDIO_RECONFIG_FAILURE )
714 {
715 config->error = 1;
716 lw_log_show( &config->lh, LW_LOG_FATAL,
717 "Failed to reconfigure resampler.\n"
718 "It is recommended you reopen the file." );
719 goto audio_out;
720 }
721 if( output_flags & AUDIO_OUTPUT_ENOUGH )
722 goto audio_out;
723 if( output_flags & (AUDIO_DECODER_ERROR | AUDIO_DECODER_RECEIVED_PACKET) )
724 ++frame_number;
725 } while( 1 );
726 audio_out:
727 adhp->next_pcm_sample_number = start + output_length;
728 adhp->last_frame_number = frame_number;
729 return output_length;
730 }
731