32 #include <libavformat/avformat.h> 33 #include <libavcodec/avcodec.h> 34 #include <libavutil/mathematics.h> 35 #include <libavutil/opt.h> 36 #include <libswscale/swscale.h> 37 #include <libmediaprocsutils/log.h> 38 #include <libmediaprocsutils/stat_codes.h> 39 #include <libmediaprocsutils/check_utils.h> 40 #include <libmediaprocsutils/fair_lock.h> 41 #include <libmediaprocsutils/fifo.h> 42 #include <libmediaprocs/proc_if.h> 43 #include <libmediaprocs/proc.h> 49 #define LOOP_GUARD_MAX 20 59 const enum AVSampleFormat *samplefmt;
60 int loop_guard, ret_code, end_code= STAT_ERROR;
61 const AVCodec *avcodec= NULL;
62 AVCodecContext *avcodecctx= NULL;
63 AVDictionary *avdictionary= NULL;
64 LOG_CTX_INIT(log_ctx);
67 CHECK_DO(ffmpeg_audio_enc_ctx!= NULL,
return STAT_ERROR);
68 CHECK_DO(audio_settings_enc_ctx!= NULL,
return STAT_ERROR);
74 avcodec= avcodec_find_encoder((
enum AVCodecID)avcodecid);
76 LOGE(
"Audio encoder not supported '%s'\n", avcodec_get_name(
77 (
enum AVCodecID)avcodecid));
78 end_code= STAT_EBAVFORMAT;
81 ffmpeg_audio_enc_ctx->
avcodec= avcodec;
82 CHECK_DO(avcodec->type== AVMEDIA_TYPE_AUDIO,
goto end);
85 avcodecctx= avcodec_alloc_context3(avcodec);
86 CHECK_DO(avcodecctx!= NULL,
goto end);
94 avcodecctx->codec_id= avcodecid;
96 avcodecctx->sample_fmt= AV_SAMPLE_FMT_NONE;
97 for(samplefmt= avcodec->sample_fmts, loop_guard= 0;
98 *samplefmt!= AV_SAMPLE_FMT_NONE && loop_guard< LOOP_GUARD_MAX;
99 samplefmt++, loop_guard++) {
100 if(*samplefmt== AV_SAMPLE_FMT_S16P) {
101 avcodecctx->sample_fmt= AV_SAMPLE_FMT_S16P;
105 if(avcodecctx->sample_fmt!= AV_SAMPLE_FMT_S16P) {
106 LOGE(
"Unsupported audio sample format %s\n", av_get_sample_fmt_name(
107 avcodecctx->sample_fmt));
111 avcodecctx->channel_layout= AV_CH_LAYOUT_STEREO;
112 avcodecctx->channels= av_get_channel_layout_nb_channels(
113 avcodecctx->channel_layout);
123 ret_code= avcodec_open2(ffmpeg_audio_enc_ctx->
avcodecctx,
124 ffmpeg_audio_enc_ctx->
avcodec, NULL);
126 LOGE(
"Could not open audio encoder: %s.\n", av_err2str(ret_code));
130 end_code= STAT_SUCCESS;
132 if(avdictionary!= NULL)
133 av_dict_free(&avdictionary);
134 if(end_code!= STAT_SUCCESS)
142 if(ffmpeg_audio_enc_ctx== NULL)
146 avcodec_free_context(&ffmpeg_audio_enc_ctx->
avcodecctx);
153 uint64_t flag_proc_features;
154 int ret_code, end_code= STAT_ERROR;
156 AVCodecContext *avcodecctx= NULL;
158 AVPacket pkt_oput= {0};
159 LOG_CTX_INIT(log_ctx);
162 CHECK_DO(ffmpeg_audio_enc_ctx!= NULL,
return STAT_ERROR);
163 CHECK_DO(avframe_iput!= NULL,
return STAT_ERROR);
164 CHECK_DO(oput_fifo_ctx!= NULL,
return STAT_ERROR);
177 CHECK_DO(avcodecctx!= NULL,
goto end);
180 av_init_packet(&pkt_oput);
188 ret_code= avcodec_send_frame(avcodecctx, avframe_iput);
192 while(ret_code>= 0 && proc_ctx->
flag_exit== 0) {
193 av_packet_unref(&pkt_oput);
194 ret_code= avcodec_receive_packet(avcodecctx, &pkt_oput);
195 if(ret_code== AVERROR(EAGAIN) || ret_code== AVERROR_EOF) {
196 end_code= STAT_EAGAIN;
212 pkt_oput.pos= avcodecctx->sample_rate;
215 if((flag_proc_features&PROC_FEATURE_LATENCY) &&
216 pkt_oput.pts!= AV_NOPTS_VALUE)
217 proc_stats_register_accumulated_latency(proc_ctx, pkt_oput.pts);
223 end_code= STAT_SUCCESS;
225 av_packet_unref(&pkt_oput);
234 int ret_code, end_code= STAT_ERROR;
235 const AVCodec *avcodec= NULL;
236 AVCodecContext *avcodecctx= NULL;
237 LOG_CTX_INIT(log_ctx);
240 CHECK_DO(ffmpeg_audio_dec_ctx!= NULL,
return STAT_ERROR);
241 CHECK_DO(audio_settings_dec_ctx!= NULL,
return STAT_ERROR);
247 avcodec= avcodec_find_decoder((
enum AVCodecID)avcodecid);
249 LOGE(
"Audio decoder not supported '%s'\n", avcodec_get_name(
250 (
enum AVCodecID)avcodecid));
251 end_code= STAT_EBAVFORMAT;
254 ffmpeg_audio_dec_ctx->
avcodec= avcodec;
255 CHECK_DO(avcodec->type== AVMEDIA_TYPE_AUDIO,
goto end);
258 avcodecctx= avcodec_alloc_context3(avcodec);
259 CHECK_DO(avcodecctx!= NULL,
goto end);
266 CHECK_DO(fmt_output!= NULL,
goto end);
268 if(strncmp(fmt_output,
"planar_signed_16b",
269 strlen(
"planar_signed_16b"))== 0) {
271 }
else if(strncmp(fmt_output,
"interleaved_signed_16b",
272 strlen(
"interleaved_signed_16b"))== 0) {
287 ret_code= avcodec_open2(ffmpeg_audio_dec_ctx->
avcodecctx,
288 ffmpeg_audio_dec_ctx->
avcodec, NULL);
290 LOGE(
"Could not open audio decoder: %s.\n", av_err2str(ret_code));
294 end_code= STAT_SUCCESS;
296 if(end_code!= STAT_SUCCESS)
304 if(ffmpeg_audio_dec_ctx== NULL)
308 avcodec_free_context(&ffmpeg_audio_dec_ctx->
avcodecctx);
315 uint64_t flag_proc_features;
316 int ret_code, end_code= STAT_ERROR;
318 AVCodecContext *avcodecctx= NULL;
320 AVFrame *avframe_oput= NULL;
321 LOG_CTX_INIT(log_ctx);
324 CHECK_DO(ffmpeg_audio_dec_ctx!= NULL,
return STAT_ERROR);
325 CHECK_DO(avpacket_iput!= NULL,
return STAT_ERROR);
326 CHECK_DO(oput_fifo_ctx!= NULL,
return STAT_ERROR);
339 CHECK_DO(avcodecctx!= NULL,
goto end);
347 ret_code= avcodec_send_packet(avcodecctx, avpacket_iput);
351 while(ret_code>= 0 && proc_ctx->
flag_exit== 0) {
352 if(avframe_oput!= NULL)
353 av_frame_free(&avframe_oput);
354 avframe_oput= av_frame_alloc();
355 CHECK_DO(avframe_oput!= NULL,
goto end);
356 ret_code= avcodec_receive_frame(avcodecctx, avframe_oput);
357 if(ret_code== AVERROR(EAGAIN) || ret_code== AVERROR_EOF) {
358 end_code= STAT_EAGAIN;
373 avframe_oput->sample_rate= avcodecctx->sample_rate;
376 if((flag_proc_features&PROC_FEATURE_LATENCY) &&
377 avframe_oput->pts!= AV_NOPTS_VALUE)
378 proc_stats_register_accumulated_latency(proc_ctx,
382 fifo_put_dup(oput_fifo_ctx, avframe_oput,
sizeof(
void*));
385 end_code= STAT_SUCCESS;
387 if(avframe_oput!= NULL)
388 av_frame_free(&avframe_oput);
393 volatile void *audio_settings_opaque,
int flag_is_encoder,
396 int ret_code, flag_io_locked= 0, flag_thr_joined= 0;
397 void *thread_end_code= NULL;
398 LOG_CTX_INIT(log_ctx);
423 pthread_join(proc_ctx->
proc_thread, &thread_end_code);
424 if(thread_end_code!= NULL) {
425 ASSERT(*((
int*)thread_end_code)== STAT_SUCCESS);
426 free(thread_end_code);
427 thread_end_code= NULL;
437 if(flag_is_encoder!= 0) {
438 enum AVCodecID avcodecid;
439 AVCodecContext *avcodecctx= NULL;
447 CHECK_DO(avcodecctx!= NULL,
goto end);
448 avcodecid= avcodecctx->codec_id;
452 (
int)avcodecid, audio_settings_enc_ctx, LOG_CTX_GET());
453 CHECK_DO(ret_code== STAT_SUCCESS,
goto end);
455 enum AVCodecID avcodecid;
456 AVCodecContext *avcodecctx= NULL;
464 CHECK_DO(avcodecctx!= NULL,
goto end);
465 avcodecid= avcodecctx->codec_id;
469 (
int)avcodecid, audio_settings_dec_ctx, LOG_CTX_GET());
470 CHECK_DO(ret_code== STAT_SUCCESS,
goto end);
479 if(flag_thr_joined!= 0) {
481 ret_code= pthread_create(&proc_ctx->
proc_thread, NULL,
487 if(flag_io_locked!= 0) {
AVCodecContext * avcodecctx
void ffmpeg_audio_enc_ctx_deinit(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, log_ctx_t *log_ctx)
int fifo_put_dup(fifo_ctx_t *fifo_ctx, const void *elem, size_t elem_size)
void fifo_set_blocking_mode(fifo_ctx_t *fifo_ctx, int do_block)
void ffmpeg_audio_dec_ctx_deinit(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, log_ctx_t *log_ctx)
int ffmpeg_audio_enc_frame(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, AVFrame *avframe_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
int ffmpeg_audio_dec_frame(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, AVPacket *avpacket_iput, fifo_ctx_t *oput_fifo_ctx, log_ctx_t *log_ctx)
Generic processor module context (see type proc_ctx_t) extension for audio encoders and decoders...
void fifo_empty(fifo_ctx_t *fifo_ctx)
uint64_t flag_proc_features
const void *(* start_routine)(void *)
void ffmpeg_audio_reset_on_new_settings(proc_ctx_t *proc_ctx, volatile void *audio_settings_opaque, int flag_is_encoder, log_ctx_t *log_ctx)
char * samples_format_output
#define CHECK_DO(COND, ACTION)
const proc_if_t * proc_if
fifo_ctx_t * fifo_ctx_array[PROC_IO_NUM]
AVCodecContext * avcodecctx
Audio encoder and decoder generic settings.
int ffmpeg_audio_enc_ctx_init(ffmpeg_audio_enc_ctx_t *ffmpeg_audio_enc_ctx, int avcodecid, const audio_settings_enc_ctx_t *audio_settings_enc_ctx, log_ctx_t *log_ctx)
int ffmpeg_audio_dec_ctx_init(ffmpeg_audio_dec_ctx_t *ffmpeg_audio_dec_ctx, int avcodecid, const audio_settings_dec_ctx_t *audio_settings_dec_ctx, log_ctx_t *log_ctx)
fair_lock_t * fair_lock_io_array[PROC_IO_NUM]