5 #include <libavcodec/avcodec.h>
6 #include <libavdevice/avdevice.h>
7 #include <libavformat/avformat.h>
8 #include <libavutil/pixdesc.h>
9 #include <libswresample/swresample.h>
10 #include <libswscale/swscale.h>
13 #include <Audio/Settings/Model.hpp>
14 #include <Gfx/Libav/AudioFrameEncoder.hpp>
15 #include <Gfx/Libav/LibavOutputSettings.hpp>
17 #include <score/application/ApplicationContext.hpp>
18 #include <score/tools/Debug.hpp>
20 #include <ossia/detail/flat_map.hpp>
22 #include <QApplication>
24 #include <CDSPResampler.h>
35 ossia::flat_map<std::string, std::string> options;
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());
130 if(codec->supported_samplerates)
132 c->sample_rate = codec->supported_samplerates[0];
133 for(
int i = 0; codec->supported_samplerates[i]; i++)
135 if(codec->supported_samplerates[i] == set.audio_sample_rate)
136 c->sample_rate = set.audio_sample_rate;
141 c->sample_rate = set.audio_sample_rate;
144 c->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
145 c->ch_layout.nb_channels = set.audio_channels;
146 if(set.audio_encoder_short ==
"pcm_s24le" || set.audio_encoder_short ==
"pcm_s24be")
147 c->bits_per_raw_sample = 24;
149 this->st->time_base = AVRational{1, c->sample_rate};
150 c->time_base = AVRational{1, c->sample_rate};
151 c->framerate = AVRational{c->sample_rate, 1};
152 qDebug() <<
"Opening audio encoder with: rate: " << c->sample_rate;
158 c->codec_id = codec->id;
168 c->width = set.width;
169 c->height = set.height;
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};
185 c->pix_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
186 c->strict_std_compliance = FF_COMPLIANCE_NORMAL;
187 if(c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
192 if(c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
203 AVDictionary* opt_arg)
205 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
206 AVDictionary* opt =
nullptr;
208 av_dict_copy(&opt, opt_arg, 0);
209 int ret = avcodec_open2(enc, codec, &opt);
213 qDebug() <<
"Could not open audio codec: " << av_to_string(ret);
218 if(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
221 nb_samples = audio_stgs.getBufferSize();
222 enc->frame_size = nb_samples;
223 qDebug() <<
"Setting frame_size: " << nb_samples;
227 nb_samples = enc->frame_size;
228 qDebug() <<
"Forcing frame_size: " << nb_samples;
231 cache_input_frame = alloc_audio_frame(
232 enc->sample_fmt, &enc->ch_layout, enc->sample_rate, nb_samples);
235 ret = avcodec_parameters_from_context(this->st->codecpar, enc);
238 qDebug() <<
"Could not copy the stream parameters";
243 auto input_fmt = AV_SAMPLE_FMT_FLTP;
245 = av_get_sample_fmt(set.audio_converted_smpfmt.toStdString().c_str());
246 SCORE_ASSERT(input_fmt != -1);
247 SCORE_ASSERT(conv_fmt != -1);
251 const int input_sample_rate = ctx.getRate();
252 if(enc->sample_rate != input_sample_rate)
254 for(
int i = 0; i < set.audio_channels; i++)
255 this->resamplers.push_back(std::make_unique<r8b::CDSPResampler>(
256 input_sample_rate, enc->sample_rate, nb_samples * 2, 3.0, 206.91,
262 case AV_SAMPLE_FMT_NONE:
263 case AV_SAMPLE_FMT_U8:
264 case AV_SAMPLE_FMT_S16:
265 encoder = std::make_unique<S16IAudioFrameEncoder>(nb_samples);
267 case AV_SAMPLE_FMT_S32:
268 if(enc->bits_per_raw_sample == 24)
269 encoder = std::make_unique<S24IAudioFrameEncoder>(nb_samples);
271 encoder = std::make_unique<S32IAudioFrameEncoder>(nb_samples);
273 case AV_SAMPLE_FMT_FLT:
274 encoder = std::make_unique<FltIAudioFrameEncoder>(nb_samples);
276 case AV_SAMPLE_FMT_DBL:
277 encoder = std::make_unique<DblIAudioFrameEncoder>(nb_samples);
280 case AV_SAMPLE_FMT_U8P:
281 case AV_SAMPLE_FMT_S16P:
282 case AV_SAMPLE_FMT_S32P:
283 case AV_SAMPLE_FMT_FLTP:
284 encoder = std::make_unique<FltPAudioFrameEncoder>(nb_samples);
286 case AV_SAMPLE_FMT_DBLP:
287 case AV_SAMPLE_FMT_S64:
288 case AV_SAMPLE_FMT_S64P:
297 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100)
298 static AVFrame* alloc_audio_frame(
299 enum AVSampleFormat sample_fmt,
const AVChannelLayout* channel_layout,
300 int sample_rate,
int nb_samples)
302 AVFrame* frame = av_frame_alloc();
305 qDebug() <<
"Error allocating an audio frame";
309 frame->format = sample_fmt;
310 frame->ch_layout.order = channel_layout->order;
311 frame->ch_layout.nb_channels = channel_layout->nb_channels;
312 frame->sample_rate = sample_rate;
313 frame->nb_samples = nb_samples;
317 if(av_frame_get_buffer(frame, 0) < 0)
319 qDebug() <<
"Error allocating an audio buffer";
328 static AVFrame* alloc_video_frame(
enum AVPixelFormat pix_fmt,
int width,
int height)
330 auto frame = av_frame_alloc();
334 frame->format = pix_fmt;
335 frame->width = width;
336 frame->height = height;
339 const int ret = av_frame_get_buffer(frame, 0);
342 qDebug() <<
"Could not allocate frame data.";
351 AVDictionary* opt_arg)
353 AVCodecContext* c = this->enc;
354 AVDictionary* opt =
nullptr;
356 av_dict_copy(&opt, opt_arg, 0);
359 int err = av_opt_set_double(this->enc->priv_data,
"crf", 0.0, 0);
362 qDebug() <<
"failed to initialize encoder: " << av_to_string(err);
366 SCORE_ASSERT(this->enc->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
367 int ret = avcodec_open2(this->enc, codec, &opt);
371 qDebug() <<
"Could not open video codec: " << av_to_string(ret);
376 this->cache_input_frame = alloc_video_frame(AV_PIX_FMT_RGBA, c->width, c->height);
377 if(!this->cache_input_frame)
379 qDebug() <<
"Could not allocate video frame";
383 this->tmp_frame =
nullptr;
387 auto input_fmt = av_get_pix_fmt(set.video_render_pixfmt.toStdString().c_str());
388 auto conv_fmt = av_get_pix_fmt(set.video_converted_pixfmt.toStdString().c_str());
389 SCORE_ASSERT(input_fmt != -1);
390 SCORE_ASSERT(conv_fmt != -1);
391 sws_ctx = sws_getContext(
392 set.width, set.height, input_fmt, set.width, set.height, conv_fmt, 1,
nullptr,
394 SCORE_ASSERT(sws_ctx);
395 this->tmp_frame = alloc_video_frame(conv_fmt, c->width, c->height);
398 qDebug() <<
"Could not allocate temporary video frame";
404 ret = avcodec_parameters_from_context(this->st->codecpar, c);
407 qDebug() <<
"Could not copy the stream parameters";
414 AVDictionary* opt_arg)
418 SCORE_ASSERT(opt_arg);
419 if(codec->type == AVMEDIA_TYPE_AUDIO)
421 open_audio(set, oc, codec, opt_arg);
423 else if(codec->type == AVMEDIA_TYPE_VIDEO)
425 open_video(set, oc, codec, opt_arg);
429 void close(AVFormatContext* oc)
431 avcodec_free_context(&enc);
432 av_frame_free(&cache_input_frame);
433 av_frame_free(&tmp_frame);
434 av_packet_free(&tmp_pkt);
435 sws_freeContext(sws_ctx);
439 AVFrame* get_video_frame()
443 if(av_frame_make_writable(this->cache_input_frame) < 0)
446 this->cache_input_frame->pts = this->next_pts++;
448 return this->cache_input_frame;
451 AVFrame* get_audio_frame()
455 if(av_frame_make_writable(this->cache_input_frame) < 0)
458 this->cache_input_frame->pts = this->next_pts;
459 this->next_pts += this->enc->frame_size;
461 return this->cache_input_frame;
464 int write_video_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
466 #if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(7, 5, 100)
468 int ret = sws_scale_frame(sws_ctx, tmp_frame, input_frame);
471 qDebug() <<
"Error during sws_scale_frame: " << av_to_string(ret);
475 tmp_frame->quality = FF_LAMBDA_MAX;
476 tmp_frame->pict_type = AV_PICTURE_TYPE_I;
480 ret = avcodec_send_frame(enc, tmp_frame);
483 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
489 ret = avcodec_receive_packet(enc, tmp_pkt);
490 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
494 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
499 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
500 tmp_pkt->stream_index = st->index;
501 tmp_pkt->flags |= AV_PKT_FLAG_KEY;
503 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
506 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
511 return ret == AVERROR_EOF ? 1 : 0;
533 int write_audio_frame(AVFormatContext* fmt_ctx, AVFrame* input_frame)
536 int ret = avcodec_send_frame(enc, input_frame);
539 qDebug() <<
"Error sending a frame to the encoder: " << av_to_string(ret);
545 ret = avcodec_receive_packet(enc, tmp_pkt);
546 if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
550 qDebug() <<
"Error encoding a frame: " << av_to_string(ret);
555 av_packet_rescale_ts(tmp_pkt, enc->time_base, st->time_base);
556 tmp_pkt->stream_index = st->index;
558 ret = av_interleaved_write_frame(fmt_ctx, tmp_pkt);
561 qDebug() <<
"Error while writing output packet: " << av_to_string(ret);
566 return ret == AVERROR_EOF ? 1 : 0;
Definition: score-plugin-audio/Audio/Settings/Model.hpp:22
Binds the rendering pipeline to ossia processes.
Definition: CameraDevice.cpp:28
Definition: LibavOutputSettings.hpp:16
Definition: LibavOutputStream.hpp:39
Definition: LibavOutputStream.hpp:32
T & settings() const
Access a specific Settings model instance.
Definition: ApplicationContext.hpp:40