@@ -14,6 +14,7 @@ typedef struct StreamingParams {
1414 char copy_audio ;
1515 char fragmented_mp4 ;
1616 char * video_codec ;
17+ char * audio_codec ;
1718} StreamingParams ;
1819
1920typedef struct StreamingContext {
@@ -110,6 +111,37 @@ int prepare_encoder(StreamingContext *sc, AVCodecContext *decoder_ctx, AVRationa
110111 return 0 ;
111112}
112113
114+ int prepare_audio_encoder (StreamingContext * sc , int sample_rate , StreamingParams sp ){
115+ sc -> audio_avs = avformat_new_stream (sc -> avfc , NULL );
116+
117+ char * codec = "aac" ;
118+ if (sp .audio_codec )
119+ codec = sp .audio_codec ;
120+
121+ sc -> audio_avc = avcodec_find_encoder_by_name (codec );
122+ if (!sc -> audio_avc ) {logging ("could not find the proper codec" ); return -1 ;}
123+
124+ sc -> audio_avcc = avcodec_alloc_context3 (sc -> audio_avc );
125+ if (!sc -> audio_avcc ) {logging ("could not allocated memory for codec context" ); return -1 ;}
126+
127+ int OUTPUT_CHANNELS = 2 ;
128+ int OUTPUT_BIT_RATE = 196000 ;
129+ sc -> audio_avcc -> channels = OUTPUT_CHANNELS ;
130+ sc -> audio_avcc -> channel_layout = av_get_default_channel_layout (OUTPUT_CHANNELS );
131+ sc -> audio_avcc -> sample_rate = sample_rate ;
132+ sc -> audio_avcc -> sample_fmt = sc -> audio_avc -> sample_fmts [0 ];
133+ sc -> audio_avcc -> bit_rate = OUTPUT_BIT_RATE ;
134+
135+ sc -> audio_avcc -> strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL ;
136+
137+ sc -> audio_avs -> time_base .den = sample_rate ;
138+ sc -> audio_avs -> time_base .num = 1 ;
139+
140+ if (avcodec_open2 (sc -> audio_avcc , sc -> audio_avc , NULL ) < 0 ) {logging ("could not open the codec" ); return -1 ;}
141+ avcodec_parameters_from_context (sc -> audio_avs -> codecpar , sc -> audio_avcc );
142+ return 0 ;
143+ }
144+
113145int prepare_copy (AVFormatContext * avfc , AVStream * * avs , AVCodecParameters * decoder_par ) {
114146 * avs = avformat_new_stream (avfc , NULL );
115147 avcodec_parameters_copy ((* avs )-> codecpar , decoder_par );
@@ -140,6 +172,7 @@ int encode(StreamingContext *decoder, StreamingContext *encoder, AVFrame *input_
140172 output_packet -> stream_index = decoder -> video_index ;
141173 output_packet -> duration = encoder -> video_avs -> time_base .den / encoder -> video_avs -> time_base .num / decoder -> video_avs -> avg_frame_rate .num * decoder -> video_avs -> avg_frame_rate .den ;
142174
175+
143176 av_packet_rescale_ts (output_packet , decoder -> video_avs -> time_base , encoder -> video_avs -> time_base );
144177 response = av_interleaved_write_frame (encoder -> avfc , output_packet );
145178 if (response != 0 ) { logging ("Error %d while receiving packet from decoder: %s" , response , av_err2str (response )); return -1 ;}
@@ -149,6 +182,53 @@ int encode(StreamingContext *decoder, StreamingContext *encoder, AVFrame *input_
149182 return 0 ;
150183}
151184
185+ int encode_audio (StreamingContext * decoder , StreamingContext * encoder , AVFrame * input_frame ) {
186+ AVPacket * output_packet = av_packet_alloc ();
187+ if (!output_packet ) {logging ("could not allocate memory for output packet" ); return -1 ;}
188+
189+ int response = avcodec_send_frame (encoder -> audio_avcc , input_frame );
190+
191+ while (response >= 0 ) {
192+ response = avcodec_receive_packet (encoder -> audio_avcc , output_packet );
193+ if (response == AVERROR (EAGAIN ) || response == AVERROR_EOF ) {
194+ break ;
195+ } else if (response < 0 ) {
196+ logging ("Error while receiving packet from encoder: %s" , av_err2str (response ));
197+ return -1 ;
198+ }
199+
200+ output_packet -> stream_index = decoder -> audio_index ;
201+
202+ av_packet_rescale_ts (output_packet , decoder -> audio_avs -> time_base , encoder -> audio_avs -> time_base );
203+ response = av_interleaved_write_frame (encoder -> avfc , output_packet );
204+ if (response != 0 ) { logging ("Error %d while receiving packet from decoder: %s" , response , av_err2str (response )); return -1 ;}
205+ }
206+ av_packet_unref (output_packet );
207+ av_packet_free (& output_packet );
208+ return 0 ;
209+ }
210+
211+ int transcode_audio (StreamingContext * decoder , StreamingContext * encoder , AVPacket * input_packet , AVFrame * input_frame ) {
212+ int response = avcodec_send_packet (decoder -> audio_avcc , input_packet );
213+ if (response < 0 ) {logging ("Error while sending packet to decoder: %s" , av_err2str (response )); return response ;}
214+
215+ while (response >= 0 ) {
216+ response = avcodec_receive_frame (decoder -> audio_avcc , input_frame );
217+ if (response == AVERROR (EAGAIN ) || response == AVERROR_EOF ) {
218+ break ;
219+ } else if (response < 0 ) {
220+ logging ("Error while receiving frame from decoder: %s" , av_err2str (response ));
221+ return response ;
222+ }
223+
224+ if (response >= 0 ) {
225+ if (encode_audio (decoder , encoder , input_frame )) return -1 ;
226+ }
227+ av_frame_unref (input_frame );
228+ }
229+ return 0 ;
230+ }
231+
152232int transcode (StreamingContext * decoder , StreamingContext * encoder , AVPacket * input_packet , AVFrame * input_frame ) {
153233 int response = avcodec_send_packet (decoder -> video_avcc , input_packet );
154234 if (response < 0 ) {logging ("Error while sending packet to decoder: %s" , av_err2str (response )); return response ;}
@@ -177,6 +257,7 @@ int main(int argc, char *argv[])
177257 sp .copy_video = 0 ;
178258 sp .fragmented_mp4 = 0 ;
179259 sp .video_codec = "x264" ;
260+ sp .audio_codec = "aac" ;
180261
181262 StreamingContext * decoder = (StreamingContext * ) calloc (1 , sizeof (StreamingContext ));
182263 decoder -> filename = argv [1 ];
@@ -198,7 +279,7 @@ int main(int argc, char *argv[])
198279 }
199280
200281 if (!sp .copy_audio ) {
201- // transcoding
282+ if ( prepare_audio_encoder ( encoder , decoder -> audio_avcc -> sample_rate , sp )) { return -1 ;}
202283 } else {
203284 if (prepare_copy (encoder -> avfc , & encoder -> audio_avs , decoder -> audio_avs -> codecpar )) {return -1 ;}
204285 }
@@ -238,7 +319,8 @@ int main(int argc, char *argv[])
238319 }
239320 } else if (decoder -> avfc -> streams [input_packet -> stream_index ]-> codecpar -> codec_type == AVMEDIA_TYPE_AUDIO ) {
240321 if (!sp .copy_audio ) {
241- // TODO
322+ transcode_audio (decoder , encoder , input_packet , input_frame );
323+ av_packet_unref (input_packet );
242324 } else {
243325 if (remux (& input_packet , & encoder -> avfc , decoder -> audio_avs -> time_base , encoder -> audio_avs -> time_base )) return -1 ;
244326 }
0 commit comments