37 #include "libavutil/opt.h"
38 #include "libavutil/samplefmt.h"
39 #include "libavutil/imgutils.h"
42 #define LOC QString("AVFW(%1): ").arg(m_filename)
43 #define LOC_ERR QString("AVFW(%1) Error: ").arg(m_filename)
44 #define LOC_WARN QString("AVFW(%1) Warning: ").arg(m_filename)
60 const AVOutputFormat *fmt = av_guess_format(
m_container.toLatin1().constData(),
nullptr,
nullptr);
63 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"Init(): Unable to guess AVOutputFormat from container %1")
75 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"Init(): Unable to find video codec %1")
83 m_fmt.video_codec = AV_CODEC_ID_NONE;
89 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"Init(): Unable to find audio codec %1")
96 m_ctx = avformat_alloc_context();
99 LOG(VB_RECORD, LOG_ERR,
LOC +
"Init(): Unable to allocate AVFormatContext");
106 m_ctx->packet_size = 2324;
109 auto size =
static_cast<size_t>(
filename.size());
110 m_ctx->url =
static_cast<char*
>(av_malloc(size));
113 if (
m_fmt.video_codec != AV_CODEC_ID_NONE)
115 if (
m_fmt.audio_codec != AV_CODEC_ID_NONE)
120 LOG(VB_RECORD, LOG_ERR,
LOC +
"Init(): OpenVideo() failed");
126 LOG(VB_RECORD, LOG_ERR,
LOC +
"Init(): OpenAudio() failed");
150 LOG(VB_RECORD, LOG_ERR,
LOC + QString(
"OpenFile(): RingBuffer::Create() failed: '%1'")
158 if (!(
m_fmt.flags & AVFMT_NOFILE))
162 if (
m_ctx->pb ==
nullptr)
164 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenFile(): failed to allocate AVIOContext");
169 if (avformat_write_header(
m_ctx,
nullptr) < 0)
189 av_write_trailer(
m_ctx);
193 for(
uint i = 0; i <
m_ctx->nb_streams; i++)
194 av_freep(
reinterpret_cast<void*
>(&
m_ctx->streams[i]));
195 av_freep(
reinterpret_cast<void*
>(&
m_ctx));
218 AVPacket *pkt = av_packet_alloc();
221 LOG(VB_RECORD, LOG_ERR,
"packet allocation failed");
222 return AVERROR(ENOMEM);
231 bool got_packet =
false;
232 int ret = avcodec_receive_packet(avctx, pkt);
235 if (ret == AVERROR(EAGAIN))
238 ret = avcodec_send_frame(avctx,
m_picture);
246 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"video encode error: %1 (%2)")
248 av_packet_free(&pkt);
254 av_packet_free(&pkt);
258 std::chrono::milliseconds tc =
Frame->m_timecode;
266 if (pict_type == AV_PICTURE_TYPE_I)
267 pkt->flags |= AV_PKT_FLAG_KEY;
275 pkt->dts = AV_NOPTS_VALUE;
278 ret = av_interleaved_write_frame(
m_ctx, pkt);
280 LOG(VB_RECORD, LOG_ERR,
LOC +
"WriteVideoFrame(): av_interleaved_write_frame couldn't write Video");
284 av_packet_unref(pkt);
285 av_packet_free(&pkt);
291 #if (Q_BYTE_ORDER == Q_BIG_ENDIAN)
294 buf16[i] = qFromLittleEndian<quint16>(buf16[i]);
303 AVPacket *pkt = av_packet_alloc();
306 LOG(VB_RECORD, LOG_ERR,
"packet allocation failed");
307 return AVERROR(ENOMEM);
310 if (av_get_packed_sample_fmt(avctx->sample_fmt) == AV_SAMPLE_FMT_FLT)
313 static_cast<void*
>(
Buffer), samples_per_avframe * sampleSizeIn);
316 if (av_sample_fmt_is_planar(avctx->sample_fmt))
320 samples_per_avframe * sampleSizeOut);
341 bool got_packet =
false;
342 int ret = avcodec_receive_packet(avctx, pkt);
345 if (ret == AVERROR(EAGAIN))
356 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"audio encode error: %1 (%2)")
358 av_packet_free(&pkt);
364 av_packet_free(&pkt);
368 std::chrono::milliseconds tc = Timecode;
382 pkt->dts = AV_NOPTS_VALUE;
383 pkt->flags |= AV_PKT_FLAG_KEY;
386 ret = av_interleaved_write_frame(
m_ctx, pkt);
388 LOG(VB_RECORD, LOG_ERR,
LOC +
"WriteAudioFrame(): av_interleaved_write_frame couldn't write Audio");
391 av_packet_unref(pkt);
392 av_packet_free(&pkt);
397 std::chrono::milliseconds ,
int )
422 AVStream *stream = avformat_new_stream(
m_ctx,
nullptr);
425 LOG(VB_RECORD, LOG_ERR,
LOC +
"AddVideoStream(): avformat_new_stream() failed");
430 stream->time_base.den = 90000;
431 stream->time_base.num = 1;
432 stream->r_frame_rate.num = 0;
433 stream->r_frame_rate.den = 0;
435 const AVCodec *codec = avcodec_find_encoder(
m_ctx->oformat->video_codec);
438 LOG(VB_RECORD, LOG_ERR,
LOC +
"AddVideoStream(): avcodec_find_encoder() failed");
444 context->codec = codec;
445 context->codec_id =
m_ctx->oformat->video_codec;
446 context->codec_type = AVMEDIA_TYPE_VIDEO;
456 context->pix_fmt = AV_PIX_FMT_YUV420P;
458 context->thread_type = FF_THREAD_SLICE;
460 if (context->codec_id == AV_CODEC_ID_MPEG2VIDEO)
462 context->max_b_frames = 2;
464 else if (context->codec_id == AV_CODEC_ID_MPEG1VIDEO)
466 context->mb_decision = 2;
468 else if (context->codec_id == AV_CODEC_ID_H264)
474 if ((context->height > 720) ||
475 (context->bit_rate > 1400000))
479 av_opt_set(context->priv_data,
"profile",
"main", 0);
481 else if ((context->height > 576) ||
482 (context->bit_rate > 1000000))
486 av_opt_set(context->priv_data,
"profile",
"baseline", 0);
492 av_opt_set(context->priv_data,
"profile",
"baseline", 0);
496 context->max_b_frames = 0;
498 context->flags |= AV_CODEC_FLAG_LOOP_FILTER;
499 context->me_cmp |= 1;
502 av_opt_set(context,
"me_method",
"hex", 0);
503 context->me_subpel_quality = 6;
504 context->me_range = 16;
505 context->keyint_min = 25;
507 av_opt_set_int(context,
"sc_threshold", 40, 0);
508 context->i_quant_factor = 0.71F;
510 av_opt_set_int(context,
"b_strategy", 1, 0);
511 context->qcompress = 0.6F;
514 context->max_qdiff = 4;
516 context->trellis = 0;
519 av_opt_set(context,
"partitions",
"i8x8,i4x4,p8x8,b8x8", 0);
520 av_opt_set_int(context,
"direct-pred", 1, 0);
521 av_opt_set_int(context,
"rc-lookahead", 0, 0);
522 av_opt_set_int(context,
"fast-pskip", 1, 0);
523 av_opt_set_int(context,
"mixed-refs", 1, 0);
524 av_opt_set_int(context,
"8x8dct", 0, 0);
525 av_opt_set_int(context,
"weightb", 0, 0);
528 av_opt_set(context->priv_data,
"preset",
m_encodingPreset.toLatin1().constData(), 0);
529 av_opt_set(context->priv_data,
"tune",
m_encodingTune.toLatin1().constData(), 0);
532 if(
m_ctx->oformat->flags & AVFMT_GLOBALHEADER)
533 context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
544 if (avcodec_open2(context,
nullptr,
nullptr) < 0)
546 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenVideo(): avcodec_open() failed");
555 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenVideo(): AllocPicture() failed");
569 AVStream *stream = avformat_new_stream(
m_ctx,
nullptr);
572 LOG(VB_RECORD, LOG_ERR,
LOC +
"AddAudioStream(): avformat_new_stream() failed");
579 context->codec_id =
m_ctx->oformat->audio_codec;
580 context->codec_type = AVMEDIA_TYPE_AUDIO;
591 stream->time_base.den = 90000;
592 stream->time_base.num = 1;
595 if (
m_ctx->oformat->flags & AVFMT_GLOBALHEADER)
596 context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
603 const AVSampleFormat *sample_fmts =
nullptr;
604 int out_num_configs = 0;
605 int ret = avcodec_get_supported_config(
nullptr, Codec, AV_CODEC_CONFIG_SAMPLE_FORMAT,
606 0, (
const void **) &sample_fmts, &out_num_configs);
612 for (
int i = 0; i < out_num_configs; i++)
614 if (av_get_packed_sample_fmt(sample_fmts[i]) ==
Format)
616 Ctx->sample_fmt = sample_fmts[i];
627 context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
629 const AVCodec *codec = avcodec_find_encoder(context->codec_id);
632 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenAudio(): avcodec_find_encoder() failed");
642 if (avcodec_open2(context, codec,
nullptr) < 0)
644 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenAudio(): avcodec_open() failed");
653 LOG(VB_RECORD, LOG_ERR,
LOC +
"OpenAudio(): alloc_frame() failed");
658 av_get_bytes_per_sample(context->sample_fmt);
659 if (av_get_packed_sample_fmt(context->sample_fmt) == AV_SAMPLE_FMT_FLT)
662 m_audioInBuf =
static_cast<unsigned char*
>(av_malloc(size));
667 if (av_sample_fmt_is_planar(context->sample_fmt))
670 m_audioInPBuf =
static_cast<unsigned char*
>(av_malloc(size));
679 AVFrame *picture = av_frame_alloc();
682 LOG(VB_RECORD, LOG_ERR,
LOC +
"AllocPicture failed");
686 int size = av_image_get_buffer_size(PixFmt,
m_width,
m_height, IMAGE_ALIGN);
687 auto *buffer =
static_cast<unsigned char*
>(av_malloc(
static_cast<size_t>(size)));
690 LOG(VB_RECORD, LOG_ERR,
LOC +
"AllocPicture(): av_malloc() failed");
691 av_frame_free(&picture);
695 av_image_fill_arrays(picture->data, picture->linesize, buffer, PixFmt,
m_width,
m_height, IMAGE_ALIGN);
702 result.den =
static_cast<int>(floor(
m_frameRate * 100));
707 const AVRational *supported_framerates =
nullptr;
708 int out_num_configs = 0;
709 int ret = avcodec_get_supported_config(
nullptr,
m_avVideoCodec, AV_CODEC_CONFIG_FRAME_RATE,
710 0, (
const void **) &supported_framerates, &out_num_configs);
713 const AVRational *best =
nullptr;
714 AVRational best_error = { INT_MAX, 1 };
715 for (
int i = 0; i < out_num_configs; i++)
717 AVRational
error = av_sub_q(result, supported_framerates[i]);
720 if (av_cmp_q(
error, best_error) < 0)
723 best = supported_framerates + i;
727 if (best && best->num && best->den)
729 result.den = best->num;
730 result.num = best->den;
735 if (result.den == 2997)
740 else if (result.den == 5994)