40 const AVCodec* codec{};
42 AVCodecContext* enc{};
48 AVFrame* cache_input_frame{};
53 struct SwsContext* sws_ctx{};
54 std::vector<std::unique_ptr<r8b::CDSPResampler>> resamplers;
56 std::unique_ptr<AudioFrameEncoder> encoder;
59 std::vector<std::vector<double>> resample_in_buf;
60 std::vector<ossia::float_vector> resample_out_buf;
67 codec = avcodec_find_encoder_by_name(opts.codec.c_str());
70 qDebug() <<
"Could not find encoder for " << opts.codec.c_str();
74 this->tmp_pkt = av_packet_alloc();
77 qDebug() <<
"Could not allocate AVPacket";
81 this->st = avformat_new_stream(oc,
nullptr);
84 qDebug() <<
"Could not allocate stream";
87 this->st->id = oc->nb_streams - 1;
89 this->enc = avcodec_alloc_context3(codec);
92 qDebug() <<
"Could not alloc an encoding context";
98 case AVMEDIA_TYPE_AUDIO:
99 init_audio(set, this->enc);
101 case AVMEDIA_TYPE_VIDEO:
102 init_video(set, this->enc);
110 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
112 this->enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
118#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
119 c->sample_fmt = av_get_sample_fmt(set.audio_converted_smpfmt.toStdString().c_str());
122 const int* supported_samplerates{};
123#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 19, 100)
124 avcodec_get_supported_config(
125 c, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0, (
const void**)&supported_samplerates,
128 supported_samplerates = codec->supported_samplerates;
130 if(supported_samplerates)
132 c->sample_rate = supported_samplerates[0];
133 for(
int i = 0; supported_samplerates[i]; i++)
135 if(supported_samplerates[i] == set.audio_sample_rate)
137 c->sample_rate = set.audio_sample_rate;
144 c->sample_rate = set.audio_sample_rate;
148 c->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
149 c->ch_layout.nb_channels = set.audio_channels;
150 c->thread_count = set.threads > 0 ? set.threads : 0;
151 if(set.audio_encoder_short ==
"pcm_s24le" || set.audio_encoder_short ==
"pcm_s24be")
152 c->bits_per_raw_sample = 24;
154 this->st->time_base = AVRational{1, c->sample_rate};
155 c->time_base = AVRational{1, c->sample_rate};
156 c->framerate = AVRational{c->sample_rate, 1};
157 qDebug() <<
"Opening audio encoder with: rate: " << c->sample_rate;
163 c->codec_id = codec->id;
164 c->width = set.width;
165 c->height = set.height;
168 c->thread_count = set.threads > 0 ? set.threads : 0;
169 c->thread_type = FF_THREAD_FRAME | FF_THREAD_SLICE;
174 this->st->time_base = AVRational{100000, int(100000 * set.rate)};
175 c->time_base = this->st->time_base;
176 c->framerate = AVRational{this->st->time_base.den, this->st->time_base.num};
182 c->pix_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
183 if(c->pix_fmt == AV_PIX_FMT_NONE)
186 const AVPixelFormat* fmts =
nullptr;
187#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 19, 100)
188 avcodec_get_supported_config(
189 c, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
190 (
const void**)&fmts,
nullptr);
192 fmts = codec->pix_fmts;
194 if(fmts && fmts[0] != AV_PIX_FMT_NONE)
195 c->pix_fmt = fmts[0];
197 c->pix_fmt = AV_PIX_FMT_YUV420P;
199 c->strict_std_compliance = FF_COMPLIANCE_NORMAL;
204 AVDictionary* opt_arg)
206#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
207 AVDictionary* opt =
nullptr;
209 av_dict_copy(&opt, opt_arg, 0);
210 int ret = avcodec_open2(enc, codec, &opt);
214 qDebug() <<
"Could not open audio codec: " << av_to_string(ret);
219 if(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
222 nb_samples = audio_stgs.getBufferSize();
223 enc->frame_size = nb_samples;
224 qDebug() <<
"Setting frame_size: " << nb_samples;
228 nb_samples = enc->frame_size;
229 qDebug() <<
"Forcing frame_size: " << nb_samples;
232 cache_input_frame = alloc_audio_frame(
233 enc->sample_fmt, &enc->ch_layout, enc->sample_rate, nb_samples);
236 ret = avcodec_parameters_from_context(this->st->codecpar, enc);
239 qDebug() <<
"Could not copy the stream parameters";
245 = av_get_sample_fmt(set.audio_converted_smpfmt.toStdString().c_str());
246 if(conv_fmt == AV_SAMPLE_FMT_NONE)
248 qDebug() <<
"Invalid audio sample format:" << set.audio_converted_smpfmt;
254 const int input_sample_rate = ctx.getRate();
255 if(enc->sample_rate != input_sample_rate)
257 for(
int i = 0; i < set.audio_channels; i++)
258 this->resamplers.push_back(std::make_unique<r8b::CDSPResampler>(
259 input_sample_rate, enc->sample_rate, nb_samples * 2, 3.0, 206.91,
265 case AV_SAMPLE_FMT_NONE:
266 case AV_SAMPLE_FMT_U8:
267 case AV_SAMPLE_FMT_S16:
268 encoder = std::make_unique<S16IAudioFrameEncoder>(nb_samples);
270 case AV_SAMPLE_FMT_S32:
271 if(enc->bits_per_raw_sample == 24)
272 encoder = std::make_unique<S24IAudioFrameEncoder>(nb_samples);
274 encoder = std::make_unique<S32IAudioFrameEncoder>(nb_samples);
276 case AV_SAMPLE_FMT_FLT:
277 encoder = std::make_unique<FltIAudioFrameEncoder>(nb_samples);
279 case AV_SAMPLE_FMT_DBL:
280 encoder = std::make_unique<DblIAudioFrameEncoder>(nb_samples);
283 case AV_SAMPLE_FMT_U8P:
284 case AV_SAMPLE_FMT_S16P:
285 encoder = std::make_unique<S16PAudioFrameEncoder>(nb_samples);
287 case AV_SAMPLE_FMT_S32P:
288 encoder = std::make_unique<S32PAudioFrameEncoder>(nb_samples);
290 case AV_SAMPLE_FMT_FLTP:
291 encoder = std::make_unique<FltPAudioFrameEncoder>(nb_samples);
293 case AV_SAMPLE_FMT_DBLP:
294 encoder = std::make_unique<DblPAudioFrameEncoder>(nb_samples);
296 case AV_SAMPLE_FMT_S64:
297 case AV_SAMPLE_FMT_S64P:
298 qDebug() <<
"64-bit integer audio sample format not supported for encoding";
309#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
310 static AVFrame* alloc_audio_frame(
311 enum AVSampleFormat sample_fmt,
const AVChannelLayout* channel_layout,
312 int sample_rate,
int nb_samples)
314 AVFrame* frame = av_frame_alloc();
317 qDebug() <<
"Error allocating an audio frame";
321 frame->format = sample_fmt;
322 av_channel_layout_copy(&frame->ch_layout, channel_layout);
323 frame->sample_rate = sample_rate;
324 frame->nb_samples = nb_samples;
328 if(av_frame_get_buffer(frame, 0) < 0)
330 qDebug() <<
"Error allocating an audio buffer";
331 av_frame_free(&frame);
340 static AVFrame* alloc_video_frame(
enum AVPixelFormat pix_fmt,
int width,
int height)
342 auto frame = av_frame_alloc();
346 frame->format = pix_fmt;
347 frame->width = width;
348 frame->height = height;
351 const int ret = av_frame_get_buffer(frame, 0);
354 qDebug() <<
"Could not allocate frame data.";
355 av_frame_free(&frame);
364 AVDictionary* opt_arg)
366 AVCodecContext* c = this->enc;
367 AVDictionary* opt =
nullptr;
369 av_dict_copy(&opt, opt_arg, 0);
372 int ret = avcodec_open2(this->enc, codec, &opt);
376 qDebug() <<
"Could not open video codec: " << av_to_string(ret);
381 this->cache_input_frame = alloc_video_frame(AV_PIX_FMT_RGBA, c->width, c->height);
382 if(!this->cache_input_frame)
384 qDebug() <<
"Could not allocate video frame";
388 this->tmp_frame =
nullptr;
390 auto input_fmt = av_get_pix_fmt(set.video_render_pixfmt.toStdString().c_str());
391 auto conv_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
392 if(input_fmt == AV_PIX_FMT_NONE || conv_fmt == AV_PIX_FMT_NONE)
394 qDebug() <<
"Invalid pixel format:" << set.video_render_pixfmt
395 <<
"->" << set.video_converted_pixfmt;
398 sws_ctx = sws_getContext(
399 set.width, set.height, input_fmt, set.width, set.height, conv_fmt,
400 SWS_FAST_BILINEAR,
nullptr,
nullptr,
nullptr);
403 qDebug() <<
"Could not create swscale context";
406 this->tmp_frame = alloc_video_frame(conv_fmt, c->width, c->height);
409 qDebug() <<
"Could not allocate temporary video frame";
415 ret = avcodec_parameters_from_context(this->st->codecpar, c);
418 qDebug() <<
"Could not copy the stream parameters";
427 AVDictionary* opt_arg)
431 if(codec->type == AVMEDIA_TYPE_AUDIO)
433 open_audio(set, oc, codec, opt_arg);
435 else if(codec->type == AVMEDIA_TYPE_VIDEO)
437 open_video(set, oc, codec, opt_arg);
441 void close(AVFormatContext* oc)
443 avcodec_free_context(&enc);
444 av_frame_free(&cache_input_frame);
445 av_frame_free(&tmp_frame);
446 av_packet_free(&tmp_pkt);
447 sws_freeContext(sws_ctx);
451 AVFrame* get_video_frame()
453 if(!m_valid || !this->cache_input_frame)
455 if(av_frame_make_writable(this->cache_input_frame) < 0)
458 this->cache_input_frame->pts = this->next_pts++;
459 return this->cache_input_frame;
462 AVFrame* get_audio_frame()
464 if(!m_valid || !this->cache_input_frame)
466 if(av_frame_make_writable(this->cache_input_frame) < 0)
469 this->cache_input_frame->pts = this->next_pts;
470 this->next_pts += this->enc->frame_size;
471 return this->cache_input_frame;
474 int write_video_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
478#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(7, 5, 100)
480 av_frame_unref(tmp_frame);
481 tmp_frame->format = enc->pix_fmt;
482 tmp_frame->width = enc->width;
483 tmp_frame->height = enc->height;
486 int ret = sws_scale_frame(sws_ctx, tmp_frame, input_frame);
489 qDebug() <<
"Error during sws_scale_frame: " << av_to_string(ret);
493 tmp_frame->pts = input_frame->pts;
496 ret = avcodec_send_frame(enc, tmp_frame);
499 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
505 ret = avcodec_receive_packet(enc, tmp_pkt);
506 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
510 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
515 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
516 tmp_pkt->stream_index = st->index;
518 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
521 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
526 return ret == AVERROR_EOF ? 1 : 0;
533 int write_video_frame_direct(AVFormatContext* fmt_ctx, AVFrame* frame)
538 int ret = avcodec_send_frame(enc, frame);
541 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
547 ret = avcodec_receive_packet(enc, tmp_pkt);
548 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
552 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
556 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
557 tmp_pkt->stream_index = st->index;
559 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
562 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
567 return ret == AVERROR_EOF ? 1 : 0;
570 int write_audio_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
575 int ret = avcodec_send_frame(enc, input_frame);
578 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
584 ret = avcodec_receive_packet(enc, tmp_pkt);
585 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
589 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
594 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
595 tmp_pkt->stream_index = st->index;
597 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
600 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
605 return ret == AVERROR_EOF ? 1 : 0;