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