UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
libavcodec.c
Go to the documentation of this file.
1
5/*
6 * Copyright (c) 2012-2023 CESNET z.s.p.o.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, is permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * 3. Neither the name of CESNET nor the names of its contributors may be
21 * used to endorse or promote products derived from this software without
22 * specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#define __STDC_CONSTANT_MACROS
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#include "config_unix.h"
43#include "config_win32.h"
44#endif /* HAVE_CONFIG_H */
45
46#include "debug.h"
47#include "lib_common.h"
48
49#include <inttypes.h>
50#include <libavcodec/avcodec.h>
51#include <libavutil/channel_layout.h>
52#include <libavutil/mem.h>
53#include <stddef.h>
54
55#include "audio/audio.h"
56#include "audio/codec.h"
57#include "audio/utils.h"
59#include "utils/color_out.h"
60#include "utils/macros.h"
61#include "utils/string.h"
62#include "utils/text.h"
63
64#define MAGIC 0xb135ca11
65#define LOW_LATENCY_AUDIOENC_FRAME_DURATION 2.5
66
67enum {
68 TMP_DATA_LEN = 1024 * 1024,
69};
70#define MOD_NAME "[lavcd aud.] "
71
73
74static void *libavcodec_init(audio_codec_t audio_codec, audio_codec_direction_t direction,
75 bool silent, int bitrate);
78static void libavcodec_done(void *);
79static void cleanup_common(struct libavcodec_codec_state *s);
80
82 enum AVCodecID id;
83 const char *preferred_encoder;
85};
86
87static const struct codec_param mapping[AC_COUNT] = {
88 [AC_ALAW] = {AV_CODEC_ID_PCM_ALAW, NULL, 0 },
89 [AC_MULAW] = { AV_CODEC_ID_PCM_MULAW, NULL, 0 },
90 [AC_SPEEX] = { AV_CODEC_ID_SPEEX, NULL, 0 },
91 [AC_OPUS] = { AV_CODEC_ID_OPUS, "libopus", 96000},
92 [AC_G722] = { AV_CODEC_ID_ADPCM_G722, NULL, 0 },
93 [AC_FLAC] = { AV_CODEC_ID_FLAC, NULL, 0 },
94 [AC_MP3] = { AV_CODEC_ID_MP3, NULL, 0 },
95 [AC_AAC] = { AV_CODEC_ID_AAC, "libfdk_aac", 0 },
96};
97
99 uint32_t magic;
100 struct AVPacket *pkt;
101 struct AVCodecContext *codec_ctx;
102 const struct AVCodec *codec;
103
104 AVFrame *av_frame;
105
107
109 _Alignas(16) char tmp_data[TMP_DATA_LEN];
110 audio_channel output_channel;
111 _Alignas(16) char output_channel_data[TMP_DATA_LEN];
112
113 int bitrate;
114
115 bool context_initialized;
116 audio_codec_direction_t direction;
117
118 unsigned char *tmp_buffer;
119 size_t tmp_buffer_size;
120};
121
123static void resize_tmp_buffer(unsigned char **tmp_buffer, size_t *cur_size, size_t new_size) {
124 if (new_size <= *cur_size) {
125 return;
126 }
127 unsigned char *new_buf = realloc(*tmp_buffer, new_size);
128 assert(new_buf);
129 *tmp_buffer = new_buf;
130 *cur_size = new_size;
131}
132
137static void print_libav_audio_error(int verbosity, const char *msg, int rc) {
138 char errbuf[1024];
139 av_strerror(rc, errbuf, sizeof(errbuf));
140
141 log_msg(verbosity, "%s: %s\n", msg, errbuf);
142}
143
144static const struct AVCodec *
145init_encoder(enum AVCodecID codec_id, const char *preferred_encoder,
146 bool silent)
147{
148 const char *const requested_encoder =
149 get_commandline_param("audio-lavc-encoder");
150 if (requested_encoder != NULL) {
151 preferred_encoder = requested_encoder;
152 }
153 const struct AVCodec *ret = NULL;
154 if (preferred_encoder) {
155 ret = avcodec_find_encoder_by_name(preferred_encoder);
156 if (ret != NULL && ret->id != codec_id) {
157 MSG(ERROR,
158 "Requested encoder %s cannot handle "
159 "specified codec!\n",
160 preferred_encoder);
161 assert(preferred_encoder == requested_encoder);
162 return NULL;
163 }
164 if (ret == NULL && requested_encoder != NULL) {
165 MSG(ERROR, "Requested encoder %s was not found!\n",
166 requested_encoder);
167 return NULL;
168 }
169 }
170 if (ret == NULL) {
171 ret = avcodec_find_encoder(codec_id);
172 }
173 if (ret == NULL || silent ||
174 (ret->id != AV_CODEC_ID_MP3 && ret->id != AV_CODEC_ID_AAC)) {
175 return ret;
176 }
177 // using MP3 or AAC - suggest Opus instead
178 const int level = strcmp(ret->name, "aac") == 0 /* FF native AAC */
181 log_msg(
182 level,
184 "Consider using Opus instead of encoder %s,\nsee also: "
185 "https://github.com/CESNET/UltraGrid/wiki/Audio-Settings#codecs\n",
186 ret->name);
187
188 return ret;
189}
190
191static const struct AVCodec *
192init_decoder(enum AVCodecID codec_id)
193{
194 const char *pref_dec = get_commandline_param("audio-lavc-decoder");
195 if (pref_dec != NULL) {
196 const struct AVCodec *ret =
197 avcodec_find_decoder_by_name(pref_dec);
198 if (ret && ret->id == codec_id) {
199 return ret;
200 }
201 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Requested decoder '%s' %s\n",
202 pref_dec,
203 ret ? "cannot handle received codec"
204 : "not found");
206 }
207 return avcodec_find_decoder(codec_id);
208}
209
211 "audioenc-frame-duration",
212 "* audioenc-frame-duration=<ms>\n"
213 " Sets audio encoder frame duration (in ms), default is " TOSTRING(
214 LOW_LATENCY_AUDIOENC_FRAME_DURATION) " ms for low-latency-audio\n");
215ADD_TO_PARAM("audio-lavc-decoder", "* audio-lavc-decoder=<decoder_name>\n"
216 " Use selected audio lavc decoder\n");
217ADD_TO_PARAM("audio-lavc-encoder", "* audio-lavc-encoder=<encoder_name>\n"
218 " Use selected audio lavc encoder\n");
228static void *libavcodec_init(audio_codec_t audio_codec, audio_codec_direction_t direction, bool silent,
229 int bitrate)
230{
232
233 enum AVCodecID codec_id = AV_CODEC_ID_NONE;
234
235 const struct codec_param *it = &mapping[audio_codec];
236
237 if (!it->id) {
238 if (!silent) {
239 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Cannot find mapping for codec \"%s\"!\n",
240 get_name_to_audio_codec(audio_codec));
241 }
242 return NULL;
243 } else {
244 codec_id = it->id;
245 }
246
247#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(58, 9, 100)
248 avcodec_register_all();
249#endif
250
251 struct libavcodec_codec_state *s = calloc(1, sizeof *s);
252 s->magic = MAGIC;
253 s->direction = direction;
254
255 s->codec = direction == AUDIO_CODER
256 ? init_encoder(codec_id, it->preferred_encoder, silent)
257 : init_decoder(codec_id);
258 if(!s->codec) {
259 if (!silent &&
260 (direction != AUDIO_CODER ||
261 get_commandline_param("audio-lavc-encoder") == NULL)) {
262 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Your Libavcodec build doesn't contain codec \"%s\".\n",
263 get_name_to_audio_codec(audio_codec));
264 }
265 free(s);
266 return NULL;
267 }
268
269 if (!silent) {
270 log_msg(LOG_LEVEL_NOTICE, MOD_NAME "Using audio %scoder: %s\n",
271 (direction == AUDIO_CODER ? "en" : "de"), s->codec->name);
272 }
273
274 s->codec_ctx = avcodec_alloc_context3(s->codec);
275 if(!s->codec_ctx) { // not likely :)
276 if (!silent) {
277 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Could not allocate audio codec context\n");
278 }
279 free(s);
280 return NULL;
281 }
282 s->codec_ctx->strict_std_compliance = -2;
283
284 s->bitrate = bitrate;
285
286 s->av_frame = av_frame_alloc();
287 s->pkt = av_packet_alloc();
288
289 s->tmp.data = s->tmp_data;
290 s->output_channel.data = s->output_channel_data;
291
292 if(direction == AUDIO_CODER) {
293 s->output_channel.codec = audio_codec;
294 } else {
295 s->output_channel.codec = AC_PCM;
296 }
297
298 return s;
299}
300
301/* check that a given sample format is supported by the encoder */
302static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
303{
304 const enum AVSampleFormat *p = codec->sample_fmts;
305
306 while (*p != AV_SAMPLE_FMT_NONE) {
307 if (*p == sample_fmt)
308 return 1;
309 p++;
310 }
311 return 0;
312}
313
314
315static int
317{
318 if (s->bitrate > 0) {
319 MSG(INFO, "Setting bit rate to: %d bps\n", s->bitrate);
320 return s->bitrate;
321 }
322 const int default_rate =
323 mapping[s->output_channel.codec].default_bitrate;
324 if (default_rate > 0) {
325 MSG(INFO, "Setting defaulat bit rate: %d bps\n", default_rate);
326 return default_rate;
327 }
328 return 0;
329}
330
332{
334
335 s->codec_ctx = avcodec_alloc_context3(s->codec);
336 if (s->codec_ctx == NULL) { // not likely :)
337 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Could not allocate audio codec context\n");
338 return false;
339 }
340 s->codec_ctx->strict_std_compliance = -2;
341
342 /* put sample parameters */
343 s->codec_ctx->bit_rate = get_bitrate(s);
344 s->codec_ctx->sample_rate = desc.sample_rate;
345
346 enum AVSampleFormat sample_fmts[AV_SAMPLE_FMT_NB];
347 int count = 0;
348
349 switch(desc.bps) {
350 case 1:
351 sample_fmts[count++] = AV_SAMPLE_FMT_U8;
352 sample_fmts[count++] = AV_SAMPLE_FMT_U8P;
353 break;
354 case 2:
355 sample_fmts[count++] = AV_SAMPLE_FMT_S16;
356 sample_fmts[count++] = AV_SAMPLE_FMT_S16P;
357 break;
358 case 3:
359 case 4:
360 sample_fmts[count++] = AV_SAMPLE_FMT_S32;
361 sample_fmts[count++] = AV_SAMPLE_FMT_S32P;
362 sample_fmts[count++] = AV_SAMPLE_FMT_FLT;
363 sample_fmts[count++] = AV_SAMPLE_FMT_FLTP;
364 break;
365 }
366
367 s->codec_ctx->sample_fmt = AV_SAMPLE_FMT_NONE;
368
369 for (int i = 0; i < count; ++i) {
370 if (check_sample_fmt(s->codec, sample_fmts[i])) {
371 s->codec_ctx->sample_fmt = sample_fmts[i];
372 break;
373 }
374 }
375
376 if (s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE) {
377 int i = 0;
378 while (s->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE) {
379 if (s->codec->sample_fmts[i] != AV_SAMPLE_FMT_DBL &&
380 s->codec->sample_fmts[i] != AV_SAMPLE_FMT_DBLP) {
381 s->codec_ctx->sample_fmt = s->codec->sample_fmts[i];
382 break;
383 }
384 i++;
385 }
386 }
387
388 if (s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_NONE) {
389 log_msg(LOG_LEVEL_ERROR, "[Libavcodec] Unsupported audio sample!\n");
390 return false;
391 }
392
394#if FF_API_NEW_CHANNEL_LAYOUT
395 s->codec_ctx->ch_layout = (struct AVChannelLayout) AV_CHANNEL_LAYOUT_MONO;
396#else
397 s->codec_ctx->channel_layout = AV_CH_LAYOUT_MONO;
398#endif
399
400 if (strcmp(s->codec->name, "libopus") == 0) {
401 int ret = av_opt_set(s->codec_ctx->priv_data, "application", "lowdelay", 0);
402 if (ret != 0) {
403 print_libav_audio_error(LOG_LEVEL_WARNING, "Could not set Opus low delay app type", ret);
404 }
405 } else if (strcmp(s->codec->name, "opus") == 0) {
406 char warn[] = MOD_NAME "Native FFmpeg Opus encoder seems to be currently broken "
407 "with UltraGrid. You may be able to use 'libopus' encoder instead. Please let "
408 "us know to " PACKAGE_BUGREPORT " if you either want to use the native encoder "
409 "or it even works for you.\n";
410 log_msg(LOG_LEVEL_WARNING, "%s", wrap_paragraph(warn));
411 int ret = av_opt_set_double(s->codec_ctx->priv_data, "opus_delay", 5, 0);
412 if (ret != 0) {
413 print_libav_audio_error(LOG_LEVEL_WARNING, "Cannot set Opus delay to 5", ret);
414 }
415 }
416
417 if (s->direction == AUDIO_CODER && (get_commandline_param("low-latency-audio") != NULL
418 || get_commandline_param("audioenc-frame-duration") != NULL)) {
419 double frame_duration = get_commandline_param("audioenc-frame-duration") == NULL ?
420 LOW_LATENCY_AUDIOENC_FRAME_DURATION : atof(get_commandline_param("audioenc-frame-duration"));
421 if (s->codec->id == AV_CODEC_ID_OPUS) {
422 int ret = av_opt_set_double(s->codec_ctx->priv_data, "frame_duration", frame_duration, 0);
423 if (ret != 0) {
424 print_libav_audio_error(LOG_LEVEL_ERROR, "Could not set Opus frame duration", ret);
425 }
426 }
427 if (s->codec->id == AV_CODEC_ID_FLAC) {
428 s->codec_ctx->frame_size = desc.sample_rate * frame_duration / MS_IN_SEC;
429 }
430 }
431
432 /* open it */
433 int ret = avcodec_open2(s->codec_ctx, s->codec, NULL);
434 if (ret != 0) {
435 print_libav_audio_error(LOG_LEVEL_ERROR, "Could not open codec", ret);
436 return false;
437 }
438
439 if(s->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) {
440 s->codec_ctx->frame_size = 1;
441 }
442
443 s->av_frame->nb_samples = s->codec_ctx->frame_size;
444 s->av_frame->format = s->codec_ctx->sample_fmt;
445#if FF_API_NEW_CHANNEL_LAYOUT
446 s->av_frame->ch_layout = (struct AVChannelLayout) AV_CHANNEL_LAYOUT_MONO;
447#else
448 s->av_frame->channel_layout = AV_CH_LAYOUT_MONO;
449#endif
450 s->av_frame->sample_rate = s->codec_ctx->sample_rate;
451 MSG(VERBOSE,
452 "Setting AV frame: %d samples, format %d, sample rate %d\n",
453 s->av_frame->nb_samples, s->av_frame->format,
454 s->av_frame->sample_rate);
455
456 ret = av_frame_get_buffer(s->av_frame, 0);
457 if (ret != 0) {
458 print_libav_audio_error(LOG_LEVEL_ERROR, "Could not allocate audio data buffers", ret);
459 return false;
460 }
461
462 s->tmp.data_len = 0;
463 s->output_channel.sample_rate = desc.sample_rate;
464 s->output_channel.bps = av_get_bytes_per_sample(s->codec_ctx->sample_fmt);
465 s->saved_desc = desc;
466
467 s->context_initialized = true;
468
469 return true;
470}
471
473{
475
476 s->codec_ctx = avcodec_alloc_context3(s->codec);
477 if (s->codec_ctx == NULL) { // not likely :)
478 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Could not allocate audio codec context\n");
479 return false;
480 }
481 s->codec_ctx->strict_std_compliance = -2;
482
484
485 s->codec_ctx->bits_per_coded_sample = 4; // ADPCM
486 s->codec_ctx->sample_rate = desc.sample_rate;
487 s->codec_ctx->time_base = (AVRational) { 1, desc.sample_rate };
488
489 /* open it */
490 if (avcodec_open2(s->codec_ctx, s->codec, NULL) < 0) {
491 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Could not open codec\n");
492 return false;
493 }
494
495 s->saved_desc = desc;
496
497 s->context_initialized = true;
498
499 return true;
500}
501
502static bool
504{
505 if (channel == NULL) {
506 return true;
507 }
508
512 s, audio_desc_from_audio_channel(channel))) {
513 MSG(ERROR, "Unable to reinitialize audio compress!\n");
514 return false;
515 }
516 }
517
518 if (s->output_channel.bps == channel->bps &&
519 s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_FLT &&
520 s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
521 memcpy(s->tmp_data + s->tmp.data_len, channel->data,
522 channel->data_len);
523 s->tmp.data_len += channel->data_len;
524 return true;
525 }
526 if (s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_FLT &&
527 s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
528 change_bps(s->tmp_data + s->tmp.data_len, s->output_channel.bps,
529 channel->data, s->saved_desc.bps, channel->data_len);
530 s->tmp.data_len += channel->data_len / s->saved_desc.bps *
531 s->output_channel.bps;
532 return true;
533 }
534 if (s->output_channel.bps == channel->bps) {
535 if (s->tmp.data_len + channel->data_len > TMP_DATA_LEN) {
536 MSG(ERROR, "Auxiliary buffer overflow!\n");
537 } else {
538 int2float(s->tmp_data + s->tmp.data_len, channel->data,
539 channel->data_len);
540 s->tmp.data_len += channel->data_len;
541 }
542 } else {
543 int data_len = channel->data_len / channel->bps * 4;
544 resize_tmp_buffer(&s->tmp_buffer, &s->tmp_buffer_size,
545 data_len);
546 change_bps((char *) s->tmp_buffer, 4, channel->data,
547 channel->bps, channel->data_len);
548 if (s->tmp.data_len + data_len > TMP_DATA_LEN) {
549 MSG(ERROR, "Auxiliary buffer overflow!\n");
550 } else {
551 int2float(s->tmp_data + s->tmp.data_len,
552 (char *) s->tmp_buffer, data_len);
553 s->tmp.data_len += data_len;
554 }
555 }
556 return true;
557}
558
560static int64_t
561get_in_ts(const audio_channel *channel, int cached_samples)
562{
563 if (channel->timestamp == -1) {
564 return AV_NOPTS_VALUE;
565 }
566 const int64_t ts = channel->timestamp * channel->sample_rate / kHz90;
567 return ts - cached_samples;
568}
569
570static void
571set_out_ts(int recv_ret, struct libavcodec_codec_state *s)
572{
573 if (recv_ret != 0 || s->output_channel.timestamp != -1 ||
574 s->pkt->pts < 0) {
575 return;
576 }
577 s->output_channel.timestamp =
578 (s->pkt->pts * kHz90 + s->codec_ctx->sample_rate - 1) /
579 s->codec_ctx->sample_rate;
580}
581
582static void
584{
585 if (s->output_channel.data_len + s->pkt->size > TMP_DATA_LEN) {
586 MSG(ERROR, "Output buffer overflow!\n");
587 }
588 if (s->pkt->pts != AV_NOPTS_VALUE && s->pkt->pts < 0) {
589 return;
590 }
591 memcpy(s->output_channel_data + s->output_channel.data_len,
592 s->pkt->data, s->pkt->size);
593 s->output_channel.data_len += s->pkt->size;
594 s->output_channel.duration +=
595 s->codec_ctx->frame_size / (double) s->output_channel.sample_rate;
596}
597
599{
601 assert(s->magic == MAGIC);
602
603 assert(s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_DBL && // not supported yet
604 s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_DBLP);
605
606 const int cached_bytes = s->tmp.data_len;
607 if (!process_input(s, channel)) {
608 return NULL;
609 }
610 if (channel != NULL) {
611 s->av_frame->pts =
612 get_in_ts(channel, cached_bytes / s->output_channel.bps);
613 }
614
615 int bps = s->output_channel.bps;
616 int offset = 0;
617 s->output_channel.data_len = 0;
618 s->output_channel.duration = 0.0;
619 s->output_channel.timestamp = -1;
620 int chunk_size = s->codec_ctx->frame_size * bps;
621 while(offset + chunk_size <= s->tmp.data_len) {
622 if (bps == 1) {
623 signed2unsigned((char *) s->av_frame->data[0], s->tmp.data + offset, chunk_size);
624 } else {
625 memcpy(s->av_frame->data[0], s->tmp.data + offset, chunk_size);
626 }
627 MSG(DEBUG2, "Sending PTS %" PRId64 "\n", s->av_frame->pts);
628 int ret = avcodec_send_frame(s->codec_ctx, s->av_frame);
629 if (ret != 0) {
630 print_libav_audio_error(LOG_LEVEL_ERROR, "Error encoding frame", ret);
631 return NULL;
632 }
633 if (s->av_frame->pts != AV_NOPTS_VALUE) {
634 s->av_frame->pts += s->codec_ctx->frame_size;
635 }
636 ret = avcodec_receive_packet(s->codec_ctx, s->pkt);
637 set_out_ts(ret, s);
638 while (ret == 0) {
640 av_packet_unref(s->pkt);
641 ret = avcodec_receive_packet(s->codec_ctx, s->pkt);
642 }
643 if (ret != AVERROR(EAGAIN) && ret != 0) {
645 "Receive packet error", ret);
646 }
647 offset += chunk_size;
648 // since 2023-04-25, this may not be necessary (for AAC/MP3, it just triggers "Multiple frames in a packet." It seems not
649 // working only with native Opus encoder+decoder combination (which doesn't work anyways now). Consider removing this
650 // after some decent period (UG prior that date won't decode all frames for AAC when removed).
651 if(!(s->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) && s->output_channel.data_len > 0)
652 break;
653 }
654
655 s->tmp.data_len -= offset;
656 memmove(s->tmp_data, s->tmp.data + offset, s->tmp.data_len);
657
659 if(s->output_channel.data_len) {
660 return &s->output_channel;
661 } else {
662 return NULL;
663 }
664}
665
667{
669 assert(channel->data_len > 0);
670 assert(s->magic == MAGIC);
671
674 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to reinitialize audio decompress!\n");
675 return NULL;
676 }
677 }
678
679 // FFMPEG buffer needs to be FF_INPUT_BUFFER_PADDING_SIZE longer than data
680 resize_tmp_buffer(&s->tmp_buffer, &s->tmp_buffer_size, channel->data_len + AV_INPUT_BUFFER_PADDING_SIZE);
681 memcpy(s->tmp_buffer, channel->data, channel->data_len);
682
683 s->pkt->data = s->tmp_buffer;
684 s->pkt->size = channel->data_len;
685 s->output_channel.data_len = 0;
686
687 av_frame_unref(s->av_frame);
688
689 int ret = avcodec_send_packet(s->codec_ctx, s->pkt);
690 if (ret != 0) {
691 print_decoder_error(MOD_NAME "error sending decoded frame -", ret);
692 return NULL;
693 }
694 /* read all the output frames (in general there may be any number of them */
695 while (ret >= 0) {
696 ret = avcodec_receive_frame(s->codec_ctx, s->av_frame);
697 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
698 break;
699 }
700 if (ret < 0) {
701 print_decoder_error(MOD_NAME "error receiving decoded frame -", ret);
702 return NULL;
703 }
704 int channels = 1;
705 /* if a frame has been decoded, output it */
706 int data_size = av_samples_get_buffer_size(NULL, channels,
707 s->av_frame->nb_samples,
708 s->codec_ctx->sample_fmt, 1);
709 memcpy(s->output_channel_data + s->output_channel.data_len, s->av_frame->data[0],
710 data_size);
711 s->output_channel.data_len += data_size;
712 s->pkt->dts = s->pkt->pts = AV_NOPTS_VALUE;
713 }
714
715 //
716 // perform needed conversions (float->int32, int32->dest_bps)
717 //
718 assert(s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_DBL && // not supported yet
719 s->codec_ctx->sample_fmt != AV_SAMPLE_FMT_DBLP);
720
721 // convert from float if needed
722 if (s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLT ||
723 s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
724 float2int(s->output_channel_data, s->output_channel.data, s->output_channel.data_len);
725 } else if (s->codec_ctx->sample_fmt == AV_SAMPLE_FMT_U8) {
726 signed2unsigned(s->output_channel_data, s->output_channel.data, s->output_channel.data_len);
727 }
728
729 s->output_channel.bps = av_get_bytes_per_sample(s->codec_ctx->sample_fmt);
730 s->output_channel.sample_rate = s->codec_ctx->sample_rate;
731
732 return &s->output_channel;
733}
734
735static const int *libavcodec_get_sample_rates(void *state)
736{
738
739 return s->codec->supported_samplerates;
740}
741
743{
744 if (s->context_initialized) {
745 if (s->direction == AUDIO_DECODER) {
747 } else {
748 int ret;
749 ret = avcodec_send_frame(s->codec_ctx, NULL);
750 if (ret != 0) {
751 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Unexpected return value %d\n",
752 ret);
753 }
754 do {
755 ret = avcodec_receive_packet(s->codec_ctx, s->pkt);
756 av_packet_unref(s->pkt);
757 } while (ret >= 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN));
758 if (ret < 0 && ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) {
759 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Unexpected return value %d\n",
760 ret);
761 }
762 }
763 av_frame_unref(s->av_frame);
764 }
765
766 avcodec_free_context(&s->codec_ctx);
767
768 s->context_initialized = false;
769}
770
771static void libavcodec_done(void *state)
772{
774 assert(s->magic == MAGIC);
775
777
778 av_frame_free(&s->av_frame);
779 av_packet_free(&s->pkt);
780
781 free(s->tmp_buffer);
782 free(s);
783}
784
786
787static void
788append(char *dst, size_t dst_len, const char *name, bool prefered)
789{
790 const char *const end = dst + dst_len - 1;
791 dst += strlen(dst);
792 strappend(&dst, end, " ");
793 if (prefered) {
794 strappend(&dst, end, "*");
795 }
796 strappend(&dst, end, TERM_BOLD);
797 strappend(&dst, end, name);
798 strappend(&dst, end, TERM_RESET);
799 *dst = '\0';
800}
801
802static void
803get_encoders_decoders(enum AVCodecID id, const char *prefenc, char *buf,
804 size_t buflen)
805{
806 char encoders[STR_LEN] = "";
807 char decoders[STR_LEN] = "";
808 const AVCodec *codec = NULL;
809#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 9, 100)
810 void *i = NULL;
811 while ((codec = av_codec_iterate(&i)) != NULL) {
812 if (codec->id != id) {
813 continue;
814 }
815 char *dst = av_codec_is_encoder(codec) ? encoders : decoders;
816 const bool prefered = av_codec_is_encoder(codec) &&
817 strcmp(codec->name, prefenc) == 0;
818 append(dst, sizeof encoders, codec->name, prefered);
819 }
820#else
821 codec = avcodec_find_encoder(id);
822 while (codec != NULL) {
823 if (codec->id == id && av_codec_is_encoder(codec)) {
824 const bool prefered = strcmp(codec->name, prefenc) == 0;
825 append(encoders, sizeof encoders, codec->name,
826 prefered);
827 }
828 codec = av_codec_next(codec);
829 }
830 codec = avcodec_find_decoder(id);
831 while (codec != NULL) {
832 if (codec->id == id && av_codec_is_decoder(codec)) {
833 append(decoders, sizeof decoders, codec->name, false);
834 }
835 codec = av_codec_next(codec);
836 }
837#endif
838 snprintf(buf, buflen, "encoders:%s decoders:%s", encoders, decoders);
839}
840
841static const char *
842libavcodec_get_codec_desc(void *state, size_t buflen, char *buffer)
843{
844 struct libavcodec_codec_state *s = state;
845 assert(buflen >= 1);
846 char *tmp = buffer;
847 const char *const end = buffer + buflen - 1;
848 if (s->output_channel.codec == AC_SPEEX) {
849 strappend(&tmp, end, TYELLOW("deprecated") "; ");
850 }
851 const char *prefenc =
852 mapping[s->output_channel.codec].preferred_encoder;
853 if (prefenc == NULL) {
854 prefenc = "";
855 }
856 get_encoders_decoders(mapping[s->output_channel.codec].id, prefenc,
857 tmp, end - tmp);
858 return buffer;
859}
860
870
872
873/* vim: set expandtab sw=8 : */
void ** state
struct video_desc desc
int int channels
static bool reinitialize_decoder(struct libavcodec_codec_state *s, struct audio_desc desc)
Definition libavcodec.c:472
static void cleanup_common(struct libavcodec_codec_state *s)
Definition libavcodec.c:742
#define LOW_LATENCY_AUDIOENC_FRAME_DURATION
Definition libavcodec.c:65
static const char * libavcodec_get_codec_desc(void *state, size_t buflen, char *buffer)
Definition libavcodec.c:842
static audio_channel * libavcodec_compress(void *, audio_channel *)
Definition libavcodec.c:598
static bool process_input(struct libavcodec_codec_state *s, const audio_channel *channel)
Definition libavcodec.c:503
static int get_bitrate(struct libavcodec_codec_state *s)
Definition libavcodec.c:316
static const struct AVCodec * init_encoder(enum AVCodecID codec_id, const char *preferred_encoder, bool silent)
Definition libavcodec.c:145
static const audio_codec_t supported_codecs[]
Definition libavcodec.c:785
static void set_out_ts(int recv_ret, struct libavcodec_codec_state *s)
Definition libavcodec.c:571
@ TMP_DATA_LEN
Definition libavcodec.c:68
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
Definition libavcodec.c:302
static void libavcodec_done(void *)
Definition libavcodec.c:771
static const struct audio_compress_info libavcodec_audio_codec
Definition libavcodec.c:861
#define MAGIC
Definition libavcodec.c:64
static void append(char *dst, size_t dst_len, const char *name, bool prefered)
Definition libavcodec.c:788
static void get_encoders_decoders(enum AVCodecID id, const char *prefenc, char *buf, size_t buflen)
Definition libavcodec.c:803
static void print_libav_audio_error(int verbosity, const char *msg, int rc)
Definition libavcodec.c:137
#define MOD_NAME
Definition libavcodec.c:70
static const struct codec_param mapping[AC_COUNT]
Definition libavcodec.c:87
static void write_out_data(struct libavcodec_codec_state *s)
Definition libavcodec.c:583
static void * libavcodec_init(audio_codec_t audio_codec, audio_codec_direction_t direction, bool silent, int bitrate)
Definition libavcodec.c:228
static audio_channel * libavcodec_decompress(void *, audio_channel *)
Definition libavcodec.c:666
static const int * libavcodec_get_sample_rates(void *state)
Definition libavcodec.c:735
static int64_t get_in_ts(const audio_channel *channel, int cached_samples)
Definition libavcodec.c:561
static void resize_tmp_buffer(unsigned char **tmp_buffer, size_t *cur_size, size_t new_size)
Definition libavcodec.c:123
static bool reinitialize_encoder(struct libavcodec_codec_state *s, struct audio_desc desc)
Definition libavcodec.c:331
static const struct AVCodec * init_decoder(enum AVCodecID codec_id)
Definition libavcodec.c:192
audio_codec_t
Definition types.h:51
@ AC_G722
Definition types.h:58
@ AC_AAC
Definition types.h:60
@ AC_OPUS
Definition types.h:57
@ AC_FLAC
Definition types.h:61
@ AC_MULAW
Definition types.h:55
@ AC_SPEEX
Definition types.h:56
@ AC_MP3
Definition types.h:59
@ AC_COUNT
Definition types.h:62
@ AC_PCM
Definition types.h:53
@ AC_ALAW
Definition types.h:54
@ AC_NONE
Definition types.h:52
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450
audio_codec_direction_t
Definition codec.h:45
@ AUDIO_DECODER
Definition codec.h:47
@ AUDIO_CODER
Definition codec.h:46
#define AUDIO_COMPRESS_ABI_VERSION
Definition codec.h:43
#define TERM_BOLD
Definition color_out.h:48
#define TYELLOW(x)
Definition color_out.h:73
#define TERM_RESET
Definition color_out.h:47
static __device__ const float offset
Definition cuda_dxt.cu:139
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
int count
Definition hd-rum.c:44
void handle_error(int status)
Definition host.cpp:1184
const char * get_commandline_param(const char *key)
Definition host.cpp:894
#define ADD_TO_PARAM(param, doc)
Definition host.h:203
#define EXIT_FAIL_USAGE
Definition host.h:61
void print_decoder_error(const char *mod_name, int rc)
void lavd_flush(AVCodecContext *codec_ctx)
void ug_set_av_logging()
Sets specified log level either given explicitly or from UG-wide log_level.
#define AVCODECCTX_CHANNELS(context)
Definition lavc_common.h:91
@ LIBRARY_CLASS_AUDIO_COMPRESS
Definition lib_common.h:80
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
Definition lib_common.h:144
#define TOSTRING(A)
Definition macros.h:49
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
static const struct decoder_item decoders[]
static void strappend(char **dst, size_t *dst_alloc_len, const char *src)
Definition sdp.c:366
const char * name
Definition settings.cpp:193
Audio channel is a non-owning view on audio_frame2 isolating one channel.
Definition types.h:122
int64_t timestamp
Definition types.h:128
const char * data
Definition types.h:125
int sample_rate
Definition types.h:124
int data_len
Definition types.h:126
int bps
Definition types.h:77
const char * preferred_encoder
Definition libavcodec.c:83
enum AVCodecID id
Definition libavcodec.c:82
int default_bitrate
Definition libavcodec.c:84
std::string name
reallocate tmp_buffer if requested size is greater than currently allocated size
Definition libavcodec.c:98
struct audio_desc saved_desc
Definition libavcodec.c:106
struct AVPacket * pkt
Definition libavcodec.c:100
struct AVCodecContext * codec_ctx
Definition libavcodec.c:101
const struct AVCodec * codec
Definition libavcodec.c:102
uint32_t ts
Definition tfrc.c:101
#define MS_IN_SEC
Definition tv.h:87
@ kHz90
timestamp time base
Definition types.h:149
bool audio_desc_eq(struct audio_desc a1, struct audio_desc a2)
Definition utils.cpp:189
void signed2unsigned(char *out, const char *in, int in_len)
Definition utils.cpp:515
void float2int(char *out, const char *in, int len)
Definition utils.cpp:482
void change_bps(char *out, int out_bps, const char *in, int in_bps, int in_len)
Definition utils.cpp:258
void int2float(char *out, const char *in, int len)
Definition utils.cpp:496
struct audio_desc audio_desc_from_audio_channel(const audio_channel *channel)
Definition utils.cpp:205