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