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;
61 codec = avcodec_find_encoder_by_name(opts.codec.c_str());
64 qDebug() <<
"Could not find encoder for " << opts.codec.c_str();
68 this->tmp_pkt = av_packet_alloc();
71 qDebug() <<
"Could not allocate AVPacket";
75 this->st = avformat_new_stream(oc,
nullptr);
78 qDebug() <<
"Could not allocate stream";
81 this->st->id = oc->nb_streams - 1;
86 AVBufferRef* hw_ctx{};
89 AVHWDeviceType device = AV_HWDEVICE_TYPE_QSV;
90 int ret = av_hwdevice_ctx_create(&hw_ctx, device,
"auto",
nullptr, 0);
93 qDebug() <<
"Error while opening hardware encoder: " << av_to_string(ret);
98 this->enc = avcodec_alloc_context3(codec);
101 qDebug() <<
"Could not alloc an encoding context";
107 case AVMEDIA_TYPE_AUDIO:
108 init_audio(set, this->enc);
110 case AVMEDIA_TYPE_VIDEO:
111 init_video(set, this->enc);
119 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
121 this->enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
127#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
128 c->sample_fmt = av_get_sample_fmt(set.audio_converted_smpfmt.toStdString().c_str());
131 const int* supported_samplerates{};
132#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 19, 100)
133 avcodec_get_supported_config(
134 c, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0, (
const void**)&supported_samplerates,
137 supported_samplerates = codec->supported_samplerates;
139 if(supported_samplerates)
141 c->sample_rate = supported_samplerates[0];
142 for(
int i = 0; supported_samplerates[i]; i++)
144 if(supported_samplerates[i] == set.audio_sample_rate)
146 c->sample_rate = set.audio_sample_rate;
153 c->sample_rate = set.audio_sample_rate;
157 c->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
158 c->ch_layout.nb_channels = set.audio_channels;
159 if(set.audio_encoder_short ==
"pcm_s24le" || set.audio_encoder_short ==
"pcm_s24be")
160 c->bits_per_raw_sample = 24;
162 this->st->time_base = AVRational{1, c->sample_rate};
163 c->time_base = AVRational{1, c->sample_rate};
164 c->framerate = AVRational{c->sample_rate, 1};
165 qDebug() <<
"Opening audio encoder with: rate: " << c->sample_rate;
171 c->codec_id = codec->id;
181 c->width = set.width;
182 c->height = set.height;
187 this->st->time_base = AVRational{100000, int(100000 * set.rate)};
188 c->time_base = this->st->time_base;
189 c->framerate = AVRational{this->st->time_base.den, this->st->time_base.num};
198 c->pix_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
199 c->strict_std_compliance = FF_COMPLIANCE_NORMAL;
200 if(c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
205 if(c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
216 AVDictionary* opt_arg)
218#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
219 AVDictionary* opt =
nullptr;
221 av_dict_copy(&opt, opt_arg, 0);
222 int ret = avcodec_open2(enc, codec, &opt);
226 qDebug() <<
"Could not open audio codec: " << av_to_string(ret);
231 if(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
234 nb_samples = audio_stgs.getBufferSize();
235 enc->frame_size = nb_samples;
236 qDebug() <<
"Setting frame_size: " << nb_samples;
240 nb_samples = enc->frame_size;
241 qDebug() <<
"Forcing frame_size: " << nb_samples;
244 cache_input_frame = alloc_audio_frame(
245 enc->sample_fmt, &enc->ch_layout, enc->sample_rate, nb_samples);
248 ret = avcodec_parameters_from_context(this->st->codecpar, enc);
251 qDebug() <<
"Could not copy the stream parameters";
256 auto input_fmt = AV_SAMPLE_FMT_FLTP;
258 = av_get_sample_fmt(set.audio_converted_smpfmt.toStdString().c_str());
259 SCORE_ASSERT(input_fmt != -1);
260 SCORE_ASSERT(conv_fmt != -1);
264 const int input_sample_rate = ctx.getRate();
265 if(enc->sample_rate != input_sample_rate)
267 for(
int i = 0; i < set.audio_channels; i++)
268 this->resamplers.push_back(std::make_unique<r8b::CDSPResampler>(
269 input_sample_rate, enc->sample_rate, nb_samples * 2, 3.0, 206.91,
275 case AV_SAMPLE_FMT_NONE:
276 case AV_SAMPLE_FMT_U8:
277 case AV_SAMPLE_FMT_S16:
278 encoder = std::make_unique<S16IAudioFrameEncoder>(nb_samples);
280 case AV_SAMPLE_FMT_S32:
281 if(enc->bits_per_raw_sample == 24)
282 encoder = std::make_unique<S24IAudioFrameEncoder>(nb_samples);
284 encoder = std::make_unique<S32IAudioFrameEncoder>(nb_samples);
286 case AV_SAMPLE_FMT_FLT:
287 encoder = std::make_unique<FltIAudioFrameEncoder>(nb_samples);
289 case AV_SAMPLE_FMT_DBL:
290 encoder = std::make_unique<DblIAudioFrameEncoder>(nb_samples);
293 case AV_SAMPLE_FMT_U8P:
294 case AV_SAMPLE_FMT_S16P:
295 case AV_SAMPLE_FMT_S32P:
296 case AV_SAMPLE_FMT_FLTP:
297 encoder = std::make_unique<FltPAudioFrameEncoder>(nb_samples);
299 case AV_SAMPLE_FMT_DBLP:
300 case AV_SAMPLE_FMT_S64:
301 case AV_SAMPLE_FMT_S64P:
310#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
311 static AVFrame* alloc_audio_frame(
312 enum AVSampleFormat sample_fmt,
const AVChannelLayout* channel_layout,
313 int sample_rate,
int nb_samples)
315 AVFrame* frame = av_frame_alloc();
318 qDebug() <<
"Error allocating an audio frame";
322 frame->format = sample_fmt;
323 frame->ch_layout.order = channel_layout->order;
324 frame->ch_layout.nb_channels = channel_layout->nb_channels;
325 frame->sample_rate = sample_rate;
326 frame->nb_samples = nb_samples;
330 if(av_frame_get_buffer(frame, 0) < 0)
332 qDebug() <<
"Error allocating an audio buffer";
341 static AVFrame* alloc_video_frame(
enum AVPixelFormat pix_fmt,
int width,
int height)
343 auto frame = av_frame_alloc();
347 frame->format = pix_fmt;
348 frame->width = width;
349 frame->height = height;
352 const int ret = av_frame_get_buffer(frame, 0);
355 qDebug() <<
"Could not allocate frame data.";
364 AVDictionary* opt_arg)
366 AVCodecContext* c = this->enc;
367 AVDictionary* opt =
nullptr;
369 av_dict_copy(&opt, opt_arg, 0);
372 int err = av_opt_set_double(this->enc->priv_data,
"crf", 0.0, 0);
375 qDebug() <<
"failed to initialize encoder: " << av_to_string(err);
379 SCORE_ASSERT(this->enc->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
380 int ret = avcodec_open2(this->enc, codec, &opt);
384 qDebug() <<
"Could not open video codec: " << av_to_string(ret);
389 this->cache_input_frame = alloc_video_frame(AV_PIX_FMT_RGBA, c->width, c->height);
390 if(!this->cache_input_frame)
392 qDebug() <<
"Could not allocate video frame";
396 this->tmp_frame =
nullptr;
400 auto input_fmt = av_get_pix_fmt(set.video_render_pixfmt.toStdString().c_str());
401 auto conv_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
402 SCORE_ASSERT(input_fmt != -1);
403 SCORE_ASSERT(conv_fmt != -1);
404 sws_ctx = sws_getContext(
405 set.width, set.height, input_fmt, set.width, set.height, conv_fmt, 1,
nullptr,
407 SCORE_ASSERT(sws_ctx);
408 this->tmp_frame = alloc_video_frame(conv_fmt, c->width, c->height);
411 qDebug() <<
"Could not allocate temporary video frame";
417 ret = avcodec_parameters_from_context(this->st->codecpar, c);
420 qDebug() <<
"Could not copy the stream parameters";
427 AVDictionary* opt_arg)
431 SCORE_ASSERT(opt_arg);
432 if(codec->type == AVMEDIA_TYPE_AUDIO)
434 open_audio(set, oc, codec, opt_arg);
436 else if(codec->type == AVMEDIA_TYPE_VIDEO)
438 open_video(set, oc, codec, opt_arg);
442 void close(AVFormatContext* oc)
444 avcodec_free_context(&enc);
445 av_frame_free(&cache_input_frame);
446 av_frame_free(&tmp_frame);
447 av_packet_free(&tmp_pkt);
448 sws_freeContext(sws_ctx);
452 AVFrame* get_video_frame()
456 if(av_frame_make_writable(this->cache_input_frame) < 0)
459 this->cache_input_frame->pts = this->next_pts++;
461 return this->cache_input_frame;
464 AVFrame* get_audio_frame()
468 if(av_frame_make_writable(this->cache_input_frame) < 0)
471 this->cache_input_frame->pts = this->next_pts;
472 this->next_pts += this->enc->frame_size;
474 return this->cache_input_frame;
477 int write_video_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
479#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(7, 5, 100)
481 int ret = sws_scale_frame(sws_ctx, tmp_frame, input_frame);
484 qDebug() <<
"Error during sws_scale_frame: " << av_to_string(ret);
488 tmp_frame->quality = FF_LAMBDA_MAX;
489 tmp_frame->pict_type = AV_PICTURE_TYPE_I;
493 ret = avcodec_send_frame(enc, tmp_frame);
496 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
502 ret = avcodec_receive_packet(enc, tmp_pkt);
503 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
507 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
512 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
513 tmp_pkt->stream_index = st->index;
514 tmp_pkt->flags |= AV_PKT_FLAG_KEY;
516 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
519 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
524 return ret == AVERROR_EOF ? 1 : 0;
546 int write_audio_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
549 int ret = avcodec_send_frame(enc, input_frame);
552 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
558 ret = avcodec_receive_packet(enc, tmp_pkt);
559 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
563 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
568 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
569 tmp_pkt->stream_index = st->index;
571 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
574 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
579 return ret == AVERROR_EOF ? 1 : 0;