1 /*****************************************************************************
2  * audio_output.c / audio_output.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 <libavcodec/avcodec.h>
30 #include <libavresample/avresample.h>
31 #include <libavutil/mem.h>
32 #ifdef __cplusplus
33 }
34 #endif  /* __cplusplus */
35 
36 #include "audio_output.h"
37 #include "resample.h"
38 #include "decode.h"
39 
consume_decoded_audio_samples(lw_audio_output_handler_t * aohp,AVFrame * frame,int input_sample_count,int wanted_sample_count,uint8_t ** out_data,int sample_offset)40 static int consume_decoded_audio_samples
41 (
42     lw_audio_output_handler_t *aohp,
43     AVFrame                   *frame,
44     int                        input_sample_count,
45     int                        wanted_sample_count,
46     uint8_t                  **out_data,
47     int                        sample_offset
48 )
49 {
50     /* Input */
51     uint8_t *in_data[AVRESAMPLE_MAX_CHANNELS];
52     int decoded_data_offset = sample_offset * aohp->input_block_align;
53     for( int i = 0; i < aohp->input_planes; i++ )
54         in_data[i] = frame->extended_data[i] + decoded_data_offset;
55     audio_samples_t in;
56     in.channel_layout = frame->channel_layout;
57     in.sample_count   = input_sample_count;
58     in.sample_format  = (enum AVSampleFormat)frame->format;
59     in.data           = in_data;
60     /* Output */
61     uint8_t *resampled_buffer = NULL;
62     if( aohp->s24_output )
63     {
64         int out_channels = get_channel_layout_nb_channels( aohp->output_channel_layout );
65         int out_linesize = get_linesize( out_channels, wanted_sample_count, aohp->output_sample_format );
66         if( !aohp->resampled_buffer || out_linesize > aohp->resampled_buffer_size )
67         {
68             uint8_t *temp = (uint8_t *)av_realloc( aohp->resampled_buffer, out_linesize );
69             if( !temp )
70                 return 0;
71             aohp->resampled_buffer_size = out_linesize;
72             aohp->resampled_buffer      = temp;
73         }
74         resampled_buffer = aohp->resampled_buffer;
75     }
76     audio_samples_t out;
77     out.channel_layout = aohp->output_channel_layout;
78     out.sample_count   = wanted_sample_count;
79     out.sample_format  = aohp->output_sample_format;
80     out.data           = resampled_buffer ? &resampled_buffer : out_data;
81     /* Resample */
82     int resampled_size = resample_audio( aohp->avr_ctx, &out, &in );
83     if( resampled_buffer && resampled_size > 0 )
84         resampled_size = resample_s32_to_s24( out_data, aohp->resampled_buffer, resampled_size );
85     return resampled_size > 0 ? resampled_size / aohp->output_block_align : 0;
86 }
87 
output_pcm_samples_from_buffer(lw_audio_output_handler_t * aohp,AVFrame * frame_buffer,uint8_t ** output_buffer,enum audio_output_flag * output_flags)88 uint64_t output_pcm_samples_from_buffer
89 (
90     lw_audio_output_handler_t *aohp,
91     AVFrame                   *frame_buffer,
92     uint8_t                  **output_buffer,
93     enum audio_output_flag    *output_flags
94 )
95 {
96     uint64_t output_length = 0;
97     if( frame_buffer->extended_data
98      && frame_buffer->extended_data[0] )
99     {
100         /* Flush remaing audio samples. */
101         int resampled_length = consume_decoded_audio_samples( aohp, frame_buffer,
102                                                               0, (int)aohp->request_length,
103                                                               output_buffer, 0 );
104         output_length        += resampled_length;
105         aohp->request_length -= resampled_length;
106         if( aohp->request_length <= 0 )
107             *output_flags |= AUDIO_OUTPUT_ENOUGH;
108     }
109     return output_length;
110 }
111 
output_pcm_samples_from_packet(lw_audio_output_handler_t * aohp,AVCodecContext * ctx,AVPacket * pkt,AVFrame * frame_buffer,uint8_t ** output_buffer,enum audio_output_flag * output_flags)112 uint64_t output_pcm_samples_from_packet
113 (
114     lw_audio_output_handler_t *aohp,
115     AVCodecContext            *ctx,
116     AVPacket                  *pkt,
117     AVFrame                   *frame_buffer,
118     uint8_t                  **output_buffer,
119     enum audio_output_flag    *output_flags
120 )
121 {
122     uint64_t output_length = 0;
123     int      output_audio  = 0;
124     do
125     {
126         int decode_complete;
127         int consumed_data_length = decode_audio_packet( ctx, frame_buffer, &decode_complete, pkt );
128         if( consumed_data_length < 0 )
129         {
130             /* Force to request the next sample. */
131             *output_flags |= AUDIO_DECODER_ERROR;
132             pkt->size = 0;
133             break;
134         }
135         if( pkt->data )
136         {
137             if( consumed_data_length > 0 )
138             {
139                 pkt->size -= consumed_data_length;
140                 pkt->data += consumed_data_length;
141                 *output_flags |= AUDIO_DECODER_RECEIVED_PACKET;
142             }
143         }
144         else if( !decode_complete )
145         {
146             /* No more PCM audio samples in this stream. */
147             *output_flags |= AUDIO_OUTPUT_ENOUGH;
148             break;
149         }
150         output_audio |= decode_complete ? 1 : 0;
151         if( decode_complete
152          && frame_buffer->extended_data
153          && frame_buffer->extended_data[0] )
154         {
155             /* Check channel layout, sample rate and sample format of decoded audio samples. */
156             if( frame_buffer->channel_layout == 0 )
157                 frame_buffer->channel_layout = av_get_default_channel_layout( ctx->channels );
158             enum AVSampleFormat input_sample_format = (enum AVSampleFormat)frame_buffer->format;
159             if( aohp->input_channel_layout != frame_buffer->channel_layout
160              || aohp->input_sample_rate    != frame_buffer->sample_rate
161              || aohp->input_sample_format  != input_sample_format )
162             {
163                 /* Detected a change of channel layout, sample rate or sample format.
164                  * Reconfigure audio resampler. */
165                 if( update_resampler_configuration( aohp->avr_ctx,
166                                                     aohp->output_channel_layout,
167                                                     aohp->output_sample_rate,
168                                                     aohp->output_sample_format,
169                                                     frame_buffer->channel_layout,
170                                                     frame_buffer->sample_rate,
171                                                     input_sample_format,
172                                                     &aohp->input_planes,
173                                                     &aohp->input_block_align ) < 0 )
174                 {
175                     *output_flags |= AUDIO_RECONFIG_FAILURE;
176                     break;
177                 }
178                 aohp->input_channel_layout = frame_buffer->channel_layout;
179                 aohp->input_sample_rate    = frame_buffer->sample_rate;
180                 aohp->input_sample_format  = input_sample_format;
181             }
182             /* Process decoded audio samples. */
183             int decoded_length = frame_buffer->nb_samples;
184             if( decoded_length > aohp->output_sample_offset )
185             {
186                 /* Send decoded audio data to resampler and get desired resampled audio as you want as much as possible. */
187                 int useful_length = (int)(decoded_length - aohp->output_sample_offset);
188                 int resampled_length = consume_decoded_audio_samples( aohp, frame_buffer,
189                                                                       useful_length, (int)aohp->request_length,
190                                                                       output_buffer, (int)aohp->output_sample_offset );
191                 output_length        += resampled_length;
192                 aohp->request_length -= resampled_length;
193                 aohp->output_sample_offset = 0;
194                 if( aohp->request_length <= 0 )
195                 {
196                     *output_flags |= AUDIO_OUTPUT_ENOUGH;
197                     break;
198                 }
199             }
200             else
201                 aohp->output_sample_offset -= decoded_length;
202         }
203     } while( pkt->size > 0 );
204     if( !output_audio && pkt->data )
205         /* Count audio frame delay only if feeding non-NULL packet. */
206         *output_flags |= AUDIO_DECODER_DELAY;
207     return output_length;
208 }
209 
lw_cleanup_audio_output_handler(lw_audio_output_handler_t * aohp)210 void lw_cleanup_audio_output_handler
211 (
212     lw_audio_output_handler_t *aohp
213 )
214 {
215     if( aohp->resampled_buffer )
216         av_freep( &aohp->resampled_buffer );
217     if( aohp->avr_ctx )
218         avresample_free( &aohp->avr_ctx );
219 }
220