Add an audio output stream
| 1010 | |
| 1011 | // Add an audio output stream |
| 1012 | AVStream *FFmpegWriter::add_audio_stream() { |
| 1013 | // Find the audio codec |
| 1014 | const AVCodec *codec = avcodec_find_encoder_by_name(info.acodec.c_str()); |
| 1015 | if (codec == NULL) |
| 1016 | throw InvalidCodec("A valid audio codec could not be found for this file.", path); |
| 1017 | |
| 1018 | // Free any previous memory allocations |
| 1019 | if (audio_codec_ctx != nullptr) { |
| 1020 | AV_FREE_CONTEXT(audio_codec_ctx); |
| 1021 | } |
| 1022 | |
| 1023 | // Create a new audio stream |
| 1024 | AVStream* st = avformat_new_stream(oc, codec); |
| 1025 | if (!st) |
| 1026 | throw OutOfMemory("Could not allocate memory for the audio stream.", path); |
| 1027 | |
| 1028 | // Allocate a new codec context for the stream |
| 1029 | ALLOC_CODEC_CTX(audio_codec_ctx, codec, st) |
| 1030 | #if (LIBAVFORMAT_VERSION_MAJOR >= 58) |
| 1031 | st->codecpar->codec_id = codec->id; |
| 1032 | #endif |
| 1033 | AVCodecContext* c = audio_codec_ctx; |
| 1034 | |
| 1035 | c->codec_id = codec->id; |
| 1036 | c->codec_type = AVMEDIA_TYPE_AUDIO; |
| 1037 | |
| 1038 | // Set the sample parameters |
| 1039 | c->bit_rate = info.audio_bit_rate; |
| 1040 | #if !HAVE_CH_LAYOUT |
| 1041 | c->channels = info.channels; |
| 1042 | #endif |
| 1043 | |
| 1044 | // Set valid sample rate (or throw error) |
| 1045 | if (codec->supported_samplerates) { |
| 1046 | int i; |
| 1047 | for (i = 0; codec->supported_samplerates[i] != 0; i++) |
| 1048 | if (info.sample_rate == codec->supported_samplerates[i]) { |
| 1049 | // Set the valid sample rate |
| 1050 | c->sample_rate = info.sample_rate; |
| 1051 | break; |
| 1052 | } |
| 1053 | if (codec->supported_samplerates[i] == 0) |
| 1054 | throw InvalidSampleRate("An invalid sample rate was detected for this codec.", path); |
| 1055 | } else |
| 1056 | // Set sample rate |
| 1057 | c->sample_rate = info.sample_rate; |
| 1058 | |
| 1059 | uint64_t channel_layout = info.channel_layout; |
| 1060 | #if HAVE_CH_LAYOUT |
| 1061 | // Set a valid number of channels (or throw error) |
| 1062 | AVChannelLayout ch_layout; |
| 1063 | av_channel_layout_from_mask(&ch_layout, info.channel_layout); |
| 1064 | if (codec->ch_layouts) { |
| 1065 | int i; |
| 1066 | for (i = 0; av_channel_layout_check(&codec->ch_layouts[i]); i++) |
| 1067 | if (av_channel_layout_compare(&ch_layout, &codec->ch_layouts[i])) { |
| 1068 | // Set valid channel layout |
| 1069 | av_channel_layout_copy(&c->ch_layout, &ch_layout); |
nothing calls this directly
no test coverage detected