UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
libavcodec.c File Reference
#include "debug.h"
#include "lib_common.h"
#include <inttypes.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/mem.h>
#include <stddef.h>
#include "audio/audio.h"
#include "audio/codec.h"
#include "audio/utils.h"
#include "libavcodec/lavc_common.h"
#include "utils/color_out.h"
#include "utils/macros.h"
#include "utils/string.h"
#include "utils/text.h"
Include dependency graph for libavcodec.c:

Go to the source code of this file.

Classes

struct  codec_param
 
struct  libavcodec_codec_state
 reallocate tmp_buffer if requested size is greater than currently allocated size More...
 

Macros

#define __STDC_CONSTANT_MACROS
 
#define LOW_LATENCY_AUDIOENC_FRAME_DURATION   2.5
 
#define MAGIC   0xb135ca11
 
#define MOD_NAME   "[lavcd aud.] "
 

Enumerations

enum  { TMP_DATA_LEN = 1024 * 1024 }
 

Functions

 ADD_TO_PARAM ("audio-lavc-decoder", "* audio-lavc-decoder=<decoder_name>\n" " Use selected audio lavc decoder\n")
 
 ADD_TO_PARAM ("audio-lavc-encoder", "* audio-lavc-encoder=<encoder_name>\n" " Use selected audio lavc encoder\n")
 
 ADD_TO_PARAM ("audioenc-frame-duration", "* audioenc-frame-duration=<ms>\n" " Sets audio encoder frame duration (in ms), default is " TOSTRING(LOW_LATENCY_AUDIOENC_FRAME_DURATION) " ms for low-latency-audio\n")
 
static void append (char *dst, size_t dst_len, const char *name, bool prefered)
 
static int check_sample_fmt (const AVCodec *codec, enum AVSampleFormat sample_fmt)
 
static void cleanup_common (struct libavcodec_codec_state *s)
 
static int get_bitrate (struct libavcodec_codec_state *s)
 
static void get_encoders_decoders (enum AVCodecID id, const char *prefenc, char *buf, size_t buflen)
 
static int64_t get_in_ts (const audio_channel *channel, int cached_samples)
 
static const struct AVCodec * init_decoder (enum AVCodecID codec_id)
 
static const struct AVCodec * init_encoder (enum AVCodecID codec_id, const char *preferred_encoder, bool silent)
 
static audio_channel * libavcodec_compress (void *, audio_channel *)
 
static audio_channel * libavcodec_decompress (void *, audio_channel *)
 
static void libavcodec_done (void *)
 
static const char * libavcodec_get_codec_desc (void *state, size_t buflen, char *buffer)
 
static const int * libavcodec_get_sample_rates (void *state)
 
static void * libavcodec_init (audio_codec_t audio_codec, audio_codec_direction_t direction, bool silent, int bitrate)
 
static void print_libav_audio_error (int verbosity, const char *msg, int rc)
 
static bool process_input (struct libavcodec_codec_state *s, const audio_channel *channel)
 
 REGISTER_MODULE (libavcodec, &libavcodec_audio_codec, LIBRARY_CLASS_AUDIO_COMPRESS, AUDIO_COMPRESS_ABI_VERSION)
 
static bool reinitialize_decoder (struct libavcodec_codec_state *s, struct audio_desc desc)
 
static bool reinitialize_encoder (struct libavcodec_codec_state *s, struct audio_desc desc)
 
static void resize_tmp_buffer (unsigned char **tmp_buffer, size_t *cur_size, size_t new_size)
 
static void set_out_ts (int recv_ret, struct libavcodec_codec_state *s)
 
static void write_out_data (struct libavcodec_codec_state *s)
 

Variables

static const struct audio_compress_info libavcodec_audio_codec
 
static const struct codec_param mapping [AC_COUNT]
 
static const audio_codec_t supported_codecs [] = { AC_ALAW, AC_MULAW, AC_SPEEX, AC_OPUS, AC_G722, AC_FLAC, AC_MP3, AC_AAC, AC_NONE }
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file libavcodec.c.

Macro Definition Documentation

◆ __STDC_CONSTANT_MACROS

#define __STDC_CONSTANT_MACROS

Definition at line 38 of file libavcodec.c.

◆ LOW_LATENCY_AUDIOENC_FRAME_DURATION

#define LOW_LATENCY_AUDIOENC_FRAME_DURATION   2.5

Definition at line 65 of file libavcodec.c.

◆ MAGIC

#define MAGIC   0xb135ca11

◆ MOD_NAME

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
TMP_DATA_LEN 

Definition at line 67 of file libavcodec.c.

67 {
68 TMP_DATA_LEN = 1024 * 1024,
69};
@ TMP_DATA_LEN
Definition libavcodec.c:68

Function Documentation

◆ ADD_TO_PARAM() [1/3]

ADD_TO_PARAM ( "audio-lavc-decoder" )

◆ ADD_TO_PARAM() [2/3]

ADD_TO_PARAM ( "audio-lavc-encoder" )

◆ ADD_TO_PARAM() [3/3]

ADD_TO_PARAM ( "audioenc-frame-duration" ,
"* audioenc-frame- duration = <ms>\n" "  Sets audio encoder frame duration (in ms),
default is " TOSTRING(LOW_LATENCY_AUDIOENC_FRAME_DURATION) " ms for low-latency-audio\n"  )

◆ append()

static void append ( char * dst,
size_t dst_len,
const char * name,
bool prefered )
static

Definition at line 788 of file libavcodec.c.

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}
#define TERM_BOLD
Definition color_out.h:48
#define TERM_RESET
Definition color_out.h:47
static void strappend(char **dst, size_t *dst_alloc_len, const char *src)
Definition sdp.c:366
const char * name
Definition settings.cpp:193

References name, strappend(), TERM_BOLD, and TERM_RESET.

Referenced by get_encoders_decoders().

Here is the call graph for this function:

◆ check_sample_fmt()

static int check_sample_fmt ( const AVCodec * codec,
enum AVSampleFormat sample_fmt )
static

Definition at line 302 of file libavcodec.c.

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}

Referenced by reinitialize_encoder().

◆ cleanup_common()

static void cleanup_common ( struct libavcodec_codec_state * s)
static

Definition at line 742 of file libavcodec.c.

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}
#define MOD_NAME
Definition libavcodec.c:70
@ AUDIO_DECODER
Definition codec.h:47
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
void lavd_flush(AVCodecContext *codec_ctx)
struct AVPacket * pkt
Definition libavcodec.c:100
struct AVCodecContext * codec_ctx
Definition libavcodec.c:101

References AUDIO_DECODER, libavcodec_codec_state::av_frame, libavcodec_codec_state::codec_ctx, lavd_flush(), LOG_LEVEL_WARNING, log_msg(), MOD_NAME, and libavcodec_codec_state::pkt.

Referenced by libavcodec_done(), reinitialize_decoder(), and reinitialize_encoder().

Here is the call graph for this function:

◆ get_bitrate()

static int get_bitrate ( struct libavcodec_codec_state * s)
static

Definition at line 316 of file libavcodec.c.

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}
static const struct codec_param mapping[AC_COUNT]
Definition libavcodec.c:87
#define MSG(l, fmt,...)
Definition debug.h:96
int default_bitrate
Definition libavcodec.c:84
const struct AVCodec * codec
Definition libavcodec.c:102

References libavcodec_codec_state::codec, codec_param::default_bitrate, mapping, and MSG.

Referenced by reinitialize_encoder().

◆ get_encoders_decoders()

static void get_encoders_decoders ( enum AVCodecID id,
const char * prefenc,
char * buf,
size_t buflen )
static

Definition at line 803 of file libavcodec.c.

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}
static void append(char *dst, size_t dst_len, const char *name, bool prefered)
Definition libavcodec.c:788
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
static const struct decoder_item decoders[]
std::string name

References append(), decoders, codec::name, and STR_LEN.

Referenced by libavcodec_get_codec_desc().

Here is the call graph for this function:

◆ get_in_ts()

static int64_t get_in_ts ( const audio_channel * channel,
int cached_samples )
static
Returns
timestamp of the channel minus already buffered frames (in s->tmp)

Definition at line 561 of file libavcodec.c.

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}
int64_t timestamp
Definition types.h:128
int sample_rate
Definition types.h:124
uint32_t ts
Definition tfrc.c:101
@ kHz90
timestamp time base
Definition types.h:149

References kHz90, audio_channel::sample_rate, audio_channel::timestamp, and ts.

Referenced by libavcodec_compress().

◆ init_decoder()

static const struct AVCodec * init_decoder ( enum AVCodecID codec_id)
static

Definition at line 192 of file libavcodec.c.

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}
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
void handle_error(int status)
Definition host.cpp:1184
const char * get_commandline_param(const char *key)
Definition host.cpp:894
#define EXIT_FAIL_USAGE
Definition host.h:61

References EXIT_FAIL_USAGE, get_commandline_param(), handle_error(), LOG_LEVEL_ERROR, log_msg(), and MOD_NAME.

Referenced by libavcodec_init().

Here is the call graph for this function:

◆ init_encoder()

static const struct AVCodec * init_encoder ( enum AVCodecID codec_id,
const char * preferred_encoder,
bool silent )
static

Definition at line 145 of file libavcodec.c.

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}
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62

References get_commandline_param(), LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, and MSG.

Referenced by libavcodec_init().

Here is the call graph for this function:

◆ libavcodec_compress()

static audio_channel * libavcodec_compress ( void * state,
audio_channel * channel )
static

fprintf(stderr, "%d %d\n", i++% 2, s->output_channel.data_len);

Definition at line 598 of file libavcodec.c.

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}
void ** state
static bool process_input(struct libavcodec_codec_state *s, const audio_channel *channel)
Definition libavcodec.c:503
static void set_out_ts(int recv_ret, struct libavcodec_codec_state *s)
Definition libavcodec.c:571
#define MAGIC
Definition libavcodec.c:64
static void print_libav_audio_error(int verbosity, const char *msg, int rc)
Definition libavcodec.c:137
static void write_out_data(struct libavcodec_codec_state *s)
Definition libavcodec.c:583
static int64_t get_in_ts(const audio_channel *channel, int cached_samples)
Definition libavcodec.c:561
static __device__ const float offset
Definition cuda_dxt.cu:139
const char * data
Definition types.h:125
int data_len
Definition types.h:126
reallocate tmp_buffer if requested size is greater than currently allocated size
Definition libavcodec.c:98
void signed2unsigned(char *out, const char *in, int in_len)
Definition utils.cpp:515

References libavcodec_codec_state::av_frame, libavcodec_codec_state::codec, libavcodec_codec_state::codec_ctx, audio_channel::data, audio_channel::data_len, get_in_ts(), LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, MAGIC, libavcodec_codec_state::magic, MSG, offset, libavcodec_codec_state::pkt, print_libav_audio_error(), process_input(), set_out_ts(), signed2unsigned(), state, libavcodec_codec_state::tmp, and write_out_data().

Here is the call graph for this function:

◆ libavcodec_decompress()

static audio_channel * libavcodec_decompress ( void * state,
audio_channel * channel )
static

Definition at line 666 of file libavcodec.c.

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}
int int channels
static bool reinitialize_decoder(struct libavcodec_codec_state *s, struct audio_desc desc)
Definition libavcodec.c:472
static void resize_tmp_buffer(unsigned char **tmp_buffer, size_t *cur_size, size_t new_size)
Definition libavcodec.c:123
void print_decoder_error(const char *mod_name, int rc)
struct audio_desc saved_desc
Definition libavcodec.c:106
bool audio_desc_eq(struct audio_desc a1, struct audio_desc a2)
Definition utils.cpp:189
void float2int(char *out, const char *in, int len)
Definition utils.cpp:482
struct audio_desc audio_desc_from_audio_channel(const audio_channel *channel)
Definition utils.cpp:205

References audio_desc_eq(), audio_desc_from_audio_channel(), libavcodec_codec_state::av_frame, channels, libavcodec_codec_state::codec_ctx, audio_channel::data, audio_channel::data_len, float2int(), LOG_LEVEL_ERROR, log_msg(), MAGIC, libavcodec_codec_state::magic, MOD_NAME, libavcodec_codec_state::pkt, print_decoder_error(), reinitialize_decoder(), resize_tmp_buffer(), libavcodec_codec_state::saved_desc, signed2unsigned(), and state.

Here is the call graph for this function:

◆ libavcodec_done()

static void libavcodec_done ( void * state)
static

Definition at line 771 of file libavcodec.c.

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}
static void cleanup_common(struct libavcodec_codec_state *s)
Definition libavcodec.c:742

References libavcodec_codec_state::av_frame, cleanup_common(), MAGIC, libavcodec_codec_state::magic, libavcodec_codec_state::pkt, and state.

Here is the call graph for this function:

◆ libavcodec_get_codec_desc()

static const char * libavcodec_get_codec_desc ( void * state,
size_t buflen,
char * buffer )
static

Definition at line 842 of file libavcodec.c.

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}
static void get_encoders_decoders(enum AVCodecID id, const char *prefenc, char *buf, size_t buflen)
Definition libavcodec.c:803
@ AC_SPEEX
Definition types.h:56
#define TYELLOW(x)
Definition color_out.h:73
const char * preferred_encoder
Definition libavcodec.c:83
enum AVCodecID id
Definition libavcodec.c:82

References AC_SPEEX, libavcodec_codec_state::codec, get_encoders_decoders(), codec_param::id, mapping, codec_param::preferred_encoder, state, strappend(), libavcodec_codec_state::tmp, and TYELLOW.

Here is the call graph for this function:

◆ libavcodec_get_sample_rates()

static const int * libavcodec_get_sample_rates ( void * state)
static

Definition at line 735 of file libavcodec.c.

736{
738
739 return s->codec->supported_samplerates;
740}

References libavcodec_codec_state::codec, and state.

◆ libavcodec_init()

static void * libavcodec_init ( audio_codec_t audio_codec,
audio_codec_direction_t direction,
bool silent,
int bitrate )
static

Initializates selected audio codec

Parameters
audio_codecrequested audio codec
directionwhich direction will be used (encoding or decoding)
silentif true no error messages will be printed. This is intended for checking which codecs are present
Return values
NULLif initialization failed
!=NULLcodec state

Definition at line 228 of file libavcodec.c.

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}
static const struct AVCodec * init_encoder(enum AVCodecID codec_id, const char *preferred_encoder, bool silent)
Definition libavcodec.c:145
static const struct AVCodec * init_decoder(enum AVCodecID codec_id)
Definition libavcodec.c:192
@ AC_PCM
Definition types.h:53
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450
@ AUDIO_CODER
Definition codec.h:46
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
void ug_set_av_logging()
Sets specified log level either given explicitly or from UG-wide log_level.

References AC_PCM, AUDIO_CODER, libavcodec_codec_state::av_frame, libavcodec_codec_state::codec, libavcodec_codec_state::codec_ctx, audio_channel::data, get_commandline_param(), get_name_to_audio_codec(), codec_param::id, init_decoder(), init_encoder(), LOG_LEVEL_ERROR, LOG_LEVEL_NOTICE, log_msg(), MAGIC, libavcodec_codec_state::magic, mapping, MOD_NAME, libavcodec_codec_state::pkt, codec_param::preferred_encoder, libavcodec_codec_state::tmp, and ug_set_av_logging().

Here is the call graph for this function:

◆ print_libav_audio_error()

static void print_libav_audio_error ( int verbosity,
const char * msg,
int rc )
static
Todo
Remove and use the global print_libav_error. Dependencies need to be resolved first.

Definition at line 137 of file libavcodec.c.

137 {
138 char errbuf[1024];
139 av_strerror(rc, errbuf, sizeof(errbuf));
140
141 log_msg(verbosity, "%s: %s\n", msg, errbuf);
142}

References log_msg().

Referenced by libavcodec_compress().

Here is the call graph for this function:

◆ process_input()

static bool process_input ( struct libavcodec_codec_state * s,
const audio_channel * channel )
static

Definition at line 503 of file libavcodec.c.

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}
static bool reinitialize_encoder(struct libavcodec_codec_state *s, struct audio_desc desc)
Definition libavcodec.c:331
int bps
Definition types.h:77
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

References audio_desc_eq(), audio_desc_from_audio_channel(), audio_channel::bps, audio_desc::bps, change_bps(), libavcodec_codec_state::codec_ctx, audio_channel::data, audio_channel::data_len, int2float(), MSG, reinitialize_encoder(), resize_tmp_buffer(), libavcodec_codec_state::saved_desc, libavcodec_codec_state::tmp, and TMP_DATA_LEN.

Referenced by libavcodec_compress().

Here is the call graph for this function:

◆ REGISTER_MODULE()

REGISTER_MODULE ( libavcodec ,
& libavcodec_audio_codec,
LIBRARY_CLASS_AUDIO_COMPRESS ,
AUDIO_COMPRESS_ABI_VERSION  )

◆ reinitialize_decoder()

static bool reinitialize_decoder ( struct libavcodec_codec_state * s,
struct audio_desc desc )
static

Definition at line 472 of file libavcodec.c.

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}
struct video_desc desc
#define AVCODECCTX_CHANNELS(context)
Definition lavc_common.h:91

References AVCODECCTX_CHANNELS, cleanup_common(), libavcodec_codec_state::codec, libavcodec_codec_state::codec_ctx, desc, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, and libavcodec_codec_state::saved_desc.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ reinitialize_encoder()

static bool reinitialize_encoder ( struct libavcodec_codec_state * s,
struct audio_desc desc )
static

Definition at line 331 of file libavcodec.c.

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";
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}
#define LOW_LATENCY_AUDIOENC_FRAME_DURATION
Definition libavcodec.c:65
static int get_bitrate(struct libavcodec_codec_state *s)
Definition libavcodec.c:316
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
Definition libavcodec.c:302
int count
Definition hd-rum.c:44
#define MS_IN_SEC
Definition tv.h:87
char * wrap_paragraph(char *text)
Definition text.c:204

References AVCODECCTX_CHANNELS, check_sample_fmt(), cleanup_common(), libavcodec_codec_state::codec, libavcodec_codec_state::codec_ctx, count, desc, get_bitrate(), LOG_LEVEL_ERROR, log_msg(), and MOD_NAME.

Referenced by process_input().

Here is the call graph for this function:

◆ resize_tmp_buffer()

static void resize_tmp_buffer ( unsigned char ** tmp_buffer,
size_t * cur_size,
size_t new_size )
static

Definition at line 123 of file libavcodec.c.

123 {
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}

Referenced by libavcodec_decompress(), and process_input().

◆ set_out_ts()

static void set_out_ts ( int recv_ret,
struct libavcodec_codec_state * s )
static

Definition at line 571 of file libavcodec.c.

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}

References libavcodec_codec_state::codec_ctx, kHz90, and libavcodec_codec_state::pkt.

Referenced by libavcodec_compress().

◆ write_out_data()

static void write_out_data ( struct libavcodec_codec_state * s)
static

Definition at line 583 of file libavcodec.c.

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}

References libavcodec_codec_state::codec_ctx, MSG, libavcodec_codec_state::pkt, and TMP_DATA_LEN.

Referenced by libavcodec_compress().

Variable Documentation

◆ libavcodec_audio_codec

const struct audio_compress_info libavcodec_audio_codec
static
Initial value:
= {
}
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 const audio_codec_t supported_codecs[]
Definition libavcodec.c:785
static void libavcodec_done(void *)
Definition libavcodec.c:771
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

Definition at line 861 of file libavcodec.c.

◆ mapping

const struct codec_param mapping[AC_COUNT]
static
Initial value:
= {
[AC_ALAW] = {AV_CODEC_ID_PCM_ALAW, NULL, 0 },
[AC_MULAW] = { AV_CODEC_ID_PCM_MULAW, NULL, 0 },
[AC_SPEEX] = { AV_CODEC_ID_SPEEX, NULL, 0 },
[AC_OPUS] = { AV_CODEC_ID_OPUS, "libopus", 96000},
[AC_G722] = { AV_CODEC_ID_ADPCM_G722, NULL, 0 },
[AC_FLAC] = { AV_CODEC_ID_FLAC, NULL, 0 },
[AC_MP3] = { AV_CODEC_ID_MP3, NULL, 0 },
[AC_AAC] = { AV_CODEC_ID_AAC, "libfdk_aac", 0 },
}
@ 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_MP3
Definition types.h:59
@ AC_ALAW
Definition types.h:54

Definition at line 87 of file libavcodec.c.

87 {
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};

Referenced by delta_set_nb_channels(), get_bitrate(), device_state::init(), libavcodec_get_codec_desc(), libavcodec_init(), map_cuda_memcpy_kind(), parse_log_cfg(), and response_status_to_text().

◆ supported_codecs

const audio_codec_t supported_codecs[] = { AC_ALAW, AC_MULAW, AC_SPEEX, AC_OPUS, AC_G722, AC_FLAC, AC_MP3, AC_AAC, AC_NONE }
static

Definition at line 785 of file libavcodec.c.