31 #include "../include/FFmpegWriter.h"
36 path(path), fmt(NULL), oc(NULL), audio_st(NULL), video_st(NULL), audio_pts(0), video_pts(0), samples(NULL),
37 audio_outbuf(NULL), audio_outbuf_size(0), audio_input_frame_size(0), audio_input_position(0),
38 initial_audio_input_frame_size(0), img_convert_ctx(NULL), cache_size(8), num_of_rescalers(32),
39 rescaler_position(0), video_codec(NULL), audio_codec(NULL), is_writing(false), write_video_count(0), write_audio_count(0),
40 original_sample_rate(0), original_channels(0), avr(NULL), avr_planar(NULL), is_open(false), prepare_streams(false),
41 write_header(false), write_trailer(false), audio_encoder_buffer_size(0), audio_encoder_buffer(NULL)
71 void FFmpegWriter::auto_detect_format()
74 fmt = av_guess_format(NULL, path.c_str(), NULL);
76 throw InvalidFormat(
"Could not deduce output format from file extension.", path);
81 throw OutOfMemory(
"Could not allocate memory for AVFormatContext.", path);
89 info.
vcodec = avcodec_find_encoder(fmt->video_codec)->name;
93 info.
acodec = avcodec_find_encoder(fmt->audio_codec)->name;
97 void FFmpegWriter::initialize_streams()
99 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::initialize_streams",
"fmt->video_codec", fmt->video_codec,
"fmt->audio_codec", fmt->audio_codec,
"AV_CODEC_ID_NONE", AV_CODEC_ID_NONE,
"", -1,
"", -1,
"", -1);
106 video_st = add_video_stream();
110 audio_st = add_audio_stream();
117 if (codec.length() > 0)
119 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
120 if (new_codec == NULL)
121 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
127 fmt->video_codec = new_codec->id;
144 if (pixel_ratio.
num > 0)
149 if (bit_rate >= 1000)
165 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::SetVideoOptions (" + codec +
")",
"width", width,
"height", height,
"size.num", size.
num,
"size.den", size.
den,
"fps.num", fps.
num,
"fps.den", fps.
den);
175 if (codec.length() > 0)
177 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
178 if (new_codec == NULL)
179 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
186 fmt->audio_codec = new_codec->id;
189 if (sample_rate > 7999)
198 if (original_sample_rate == 0)
200 if (original_channels == 0)
203 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::SetAudioOptions (" + codec +
")",
"sample_rate", sample_rate,
"channels", channels,
"bit_rate", bit_rate,
"", -1,
"", -1,
"", -1);
213 AVCodecContext *c = NULL;
215 stringstream convert(value);
228 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
231 const AVOption *option = NULL;
239 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
240 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate"))
245 convert >> c->gop_size;
247 else if (name ==
"qmin")
251 else if (name ==
"qmax")
255 else if (name ==
"max_b_frames")
257 convert >> c->max_b_frames;
259 else if (name ==
"mb_decision")
261 convert >> c->mb_decision;
263 else if (name ==
"level")
267 else if (name ==
"profile")
269 convert >> c->profile;
271 else if (name ==
"slices")
273 convert >> c->slices;
275 else if (name ==
"rc_min_rate")
277 convert >> c->rc_min_rate;
279 else if (name ==
"rc_max_rate")
281 convert >> c->rc_max_rate;
283 else if (name ==
"rc_buffer_size")
285 convert >> c->rc_buffer_size;
289 AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
291 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::SetOption (" + (
string)name +
")",
"stream == VIDEO_STREAM", stream ==
VIDEO_STREAM,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
295 throw InvalidOptions(
"The option is not valid for this codec.", path);
305 if (avcodec_find_encoder_by_name(codec_name.c_str()) == NULL)
315 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
317 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::PrepareStreams [" + path +
"]",
"info.has_audio",
info.
has_audio,
"info.has_video",
info.
has_video,
"", -1,
"", -1,
"", -1,
"", -1);
320 initialize_streams();
324 open_video(oc, video_st);
326 open_audio(oc, audio_st);
329 prepare_streams =
true;
336 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
339 if (!(fmt->flags & AVFMT_NOFILE)) {
340 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
341 throw InvalidFile(
"Could not open or write file.", path);
345 snprintf(oc->AV_FILENAME,
sizeof(oc->AV_FILENAME),
"%s", path.c_str());
353 av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
356 if (avformat_write_header(oc, NULL) != 0) {
357 throw InvalidFile(
"Could not write header to file.", path);
363 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteHeader",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
371 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
376 spooled_video_frames.push_back(frame);
379 spooled_audio_frames.push_back(frame);
381 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteFrame",
"frame->number", frame->number,
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size(),
"cache_size", cache_size,
"is_writing", is_writing,
"", -1);
384 if (spooled_video_frames.size() == cache_size || spooled_audio_frames.size() == cache_size)
389 write_queued_frames();
394 write_queued_frames();
403 void FFmpegWriter::write_queued_frames()
405 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_queued_frames",
"spooled_video_frames.size()", spooled_video_frames.size(),
"spooled_audio_frames.size()", spooled_audio_frames.size(),
"", -1,
"", -1,
"", -1,
"", -1);
411 queued_video_frames = spooled_video_frames;
412 queued_audio_frames = spooled_audio_frames;
415 spooled_video_frames.clear();
416 spooled_audio_frames.clear();
421 omp_set_nested(
true);
424 bool has_error_encoding_video =
false;
431 if (
info.
has_audio && audio_st && !queued_audio_frames.empty())
432 write_audio_packets(
false);
435 while (!queued_video_frames.empty())
438 std::shared_ptr<Frame> frame = queued_video_frames.front();
441 processed_frames.push_back(frame);
445 process_video_packet(frame);
448 queued_video_frames.pop_front();
456 while (!processed_frames.empty())
459 std::shared_ptr<Frame> frame = processed_frames.front();
464 deallocate_frames.push_back(frame);
467 if (av_frames.count(frame))
470 AVFrame *frame_final = av_frames[frame];
473 bool success = write_video_packet(frame, frame_final);
475 has_error_encoding_video =
true;
480 processed_frames.pop_front();
484 while (!deallocate_frames.empty())
487 std::shared_ptr<Frame> frame = deallocate_frames.front();
490 if (av_frames.count(frame))
493 AVFrame *av_frame = av_frames[frame];
496 av_freep(&(av_frame->data[0]));
498 av_frames.erase(frame);
502 deallocate_frames.pop_front();
512 if (has_error_encoding_video)
519 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteFrame (from Reader)",
"start", start,
"length", length,
"", -1,
"", -1,
"", -1,
"", -1);
522 for (int64_t number = start; number <= length; number++)
525 std::shared_ptr<Frame> f = reader->
GetFrame(number);
536 write_queued_frames();
540 write_audio_packets(
true);
549 av_write_trailer(oc);
552 write_trailer =
true;
554 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::WriteTrailer",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
558 void FFmpegWriter::flush_encoders()
562 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
568 int stop_encoding = 1;
575 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
578 av_init_packet(&pkt);
583 uint8_t *video_outbuf = NULL;
590 #pragma omp critical (write_video_packet)
593 error_code = avcodec_send_frame(video_codec, NULL);
595 while (error_code >= 0) {
596 error_code = avcodec_receive_packet(video_codec, &pkt);
597 if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
600 avcodec_flush_buffers(video_codec);
603 if (pkt.pts != AV_NOPTS_VALUE)
604 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
605 if (pkt.dts != AV_NOPTS_VALUE)
606 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
607 if (pkt.duration > 0)
608 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
609 pkt.stream_index = video_st->index;
610 error_code = av_interleaved_write_frame(oc, &pkt);
615 #if LIBAVFORMAT_VERSION_MAJOR >= 54
617 error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
621 int video_outbuf_size = 0;
624 int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
628 if(video_codec->coded_frame->key_frame)
629 pkt.flags |= AV_PKT_FLAG_KEY;
630 pkt.data= video_outbuf;
639 if (error_code < 0) {
640 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
651 if (pkt.pts != AV_NOPTS_VALUE)
652 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
653 if (pkt.dts != AV_NOPTS_VALUE)
654 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
655 if (pkt.duration > 0)
656 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
657 pkt.stream_index = video_st->index;
660 error_code = av_interleaved_write_frame(oc, &pkt);
661 if (error_code < 0) {
662 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
667 av_freep(&video_outbuf);
675 #if LIBAVFORMAT_VERSION_MAJOR >= 54
677 write_audio_count += av_rescale_q(audio_input_position / (audio_codec->channels * av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)), (AVRational){1,
info.
sample_rate}, audio_codec->time_base);
679 write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base);
683 av_init_packet(&pkt);
686 pkt.pts = pkt.dts = write_audio_count;
691 avcodec_send_frame(audio_codec, NULL);
694 error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet);
696 if (error_code < 0) {
697 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
706 pkt.pts = pkt.dts = write_audio_count;
709 if (pkt.pts != AV_NOPTS_VALUE)
710 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
711 if (pkt.dts != AV_NOPTS_VALUE)
712 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
713 if (pkt.duration > 0)
714 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
717 pkt.stream_index = audio_st->index;
718 pkt.flags |= AV_PKT_FLAG_KEY;
721 error_code = av_interleaved_write_frame(oc, &pkt);
722 if (error_code < 0) {
723 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
734 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
741 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
748 delete[] audio_outbuf;
749 delete[] audio_encoder_buffer;
752 audio_encoder_buffer = NULL;
777 close_video(oc, video_st);
779 close_audio(oc, audio_st);
782 if (image_rescalers.size() > 0)
786 for (
int i = 0; i < oc->nb_streams; i++) {
788 av_freep(&oc->streams[i]);
791 if (!(fmt->flags & AVFMT_NOFILE)) {
797 write_video_count = 0;
798 write_audio_count = 0;
805 prepare_streams =
false;
806 write_header =
false;
807 write_trailer =
false;
809 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::Close",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
813 void FFmpegWriter::add_avframe(std::shared_ptr<Frame> frame, AVFrame* av_frame)
816 if (!av_frames.count(frame))
819 av_frames[frame] = av_frame;
829 AVStream* FFmpegWriter::add_audio_stream()
835 AVCodec *codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
837 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
842 c->codec_id = codec->id;
843 #if LIBAVFORMAT_VERSION_MAJOR >= 53
844 c->codec_type = AVMEDIA_TYPE_AUDIO;
846 c->codec_type = CODEC_TYPE_AUDIO;
854 if (codec->supported_samplerates) {
856 for (i = 0; codec->supported_samplerates[i] != 0; i++)
863 if (codec->supported_samplerates[i] == 0)
864 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
872 if (codec->channel_layouts) {
874 for (i = 0; codec->channel_layouts[i] != 0; i++)
875 if (channel_layout == codec->channel_layouts[i])
878 c->channel_layout = channel_layout;
881 if (codec->channel_layouts[i] == 0)
882 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
885 c->channel_layout = channel_layout;
888 if (codec->sample_fmts) {
889 for (
int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++)
892 c->sample_fmt = codec->sample_fmts[i];
896 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
898 c->sample_fmt = AV_SAMPLE_FMT_S16;
902 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
903 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
904 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
906 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
910 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_audio_stream",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->channels", c->channels,
"c->sample_fmt", c->sample_fmt,
"c->channel_layout", c->channel_layout,
"c->sample_rate", c->sample_rate);
916 AVStream* FFmpegWriter::add_video_stream()
922 AVCodec *codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
924 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
929 c->codec_id = codec->id;
930 #if LIBAVFORMAT_VERSION_MAJOR >= 53
931 c->codec_type = AVMEDIA_TYPE_VIDEO;
933 c->codec_type = CODEC_TYPE_VIDEO;
960 #if LIBAVFORMAT_VERSION_MAJOR >= 56
961 c->framerate = av_inv_q(c->time_base);
963 st->avg_frame_rate = av_inv_q(c->time_base);
968 c->max_b_frames = 10;
969 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
972 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
978 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
979 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
980 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
982 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
986 const PixelFormat* supported_pixel_formats = codec->pix_fmts;
987 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
990 c->pix_fmt = *supported_pixel_formats;
991 ++supported_pixel_formats;
996 if(fmt->video_codec == AV_CODEC_ID_RAWVIDEO) {
1000 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1001 if (strcmp(fmt->name,
"gif") != 0)
1004 oc->oformat->flags |= AVFMT_RAWPICTURE;
1013 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1014 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (
string)fmt->name +
" : " + (
string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags,
"AVFMT_RAWPICTURE", AVFMT_RAWPICTURE,
"", -1);
1016 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::add_video_stream (" + (
string)fmt->name +
" : " + (
string)av_get_pix_fmt_name(c->pix_fmt) +
")",
"c->codec_id", c->codec_id,
"c->bit_rate", c->bit_rate,
"c->pix_fmt", c->pix_fmt,
"oc->oformat->flags", oc->oformat->flags,
"", -1,
"", -1);
1023 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
1032 codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
1034 codec = avcodec_find_encoder(audio_codec->codec_id);
1039 AVDictionary *opts = NULL;
1040 av_dict_set(&opts,
"strict",
"experimental", 0);
1043 if (avcodec_open2(audio_codec, codec, &opts) < 0)
1048 av_dict_free(&opts);
1052 if (audio_codec->frame_size <= 1) {
1058 case AV_CODEC_ID_PCM_S16LE:
1059 case AV_CODEC_ID_PCM_S16BE:
1060 case AV_CODEC_ID_PCM_U16LE:
1061 case AV_CODEC_ID_PCM_U16BE:
1062 audio_input_frame_size >>= 1;
1069 audio_input_frame_size = audio_codec->frame_size;
1073 initial_audio_input_frame_size = audio_input_frame_size;
1080 audio_outbuf =
new uint8_t[audio_outbuf_size];
1084 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1089 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1092 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::open_audio",
"audio_codec->thread_count", audio_codec->thread_count,
"audio_input_frame_size", audio_input_frame_size,
"buffer_size",
AVCODEC_MAX_AUDIO_FRAME_SIZE +
MY_INPUT_BUFFER_PADDING_SIZE,
"", -1,
"", -1,
"", -1);
1097 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
1106 codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
1113 if(video_codec->max_b_frames && video_codec->codec_id != AV_CODEC_ID_MPEG4 && video_codec->codec_id != AV_CODEC_ID_MPEG1VIDEO && video_codec->codec_id != AV_CODEC_ID_MPEG2VIDEO)
1114 video_codec->max_b_frames = 0;
1117 AVDictionary *opts = NULL;
1118 av_dict_set(&opts,
"strict",
"experimental", 0);
1121 if (avcodec_open2(video_codec, codec, &opts) < 0)
1126 av_dict_free(&opts);
1131 av_dict_set(&st->metadata, iter->first.c_str(), iter->second.c_str(), 0);
1134 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::open_video",
"video_codec->thread_count", video_codec->thread_count,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1139 void FFmpegWriter::write_audio_packets(
bool final)
1141 #pragma omp task firstprivate(final)
1144 int total_frame_samples = 0;
1145 int frame_position = 0;
1146 int channels_in_frame = 0;
1147 int sample_rate_in_frame = 0;
1148 int samples_in_frame = 0;
1153 int16_t* all_resampled_samples = NULL;
1154 int16_t* final_samples_planar = NULL;
1155 int16_t* final_samples = NULL;
1158 while (!queued_audio_frames.empty())
1161 std::shared_ptr<Frame> frame = queued_audio_frames.front();
1164 sample_rate_in_frame = frame->SampleRate();
1165 samples_in_frame = frame->GetAudioSamplesCount();
1166 channels_in_frame = frame->GetAudioChannelsCount();
1167 channel_layout_in_frame = frame->ChannelsLayout();
1171 float* frame_samples_float = NULL;
1173 frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
1177 total_frame_samples = samples_in_frame * channels_in_frame;
1180 for (
int s = 0; s < total_frame_samples; s++, frame_position++)
1182 all_queued_samples[frame_position] =
int(frame_samples_float[s] * (1 << 15));
1186 delete[] frame_samples_float;
1189 queued_audio_frames.pop_front();
1195 total_frame_samples = frame_position;
1196 int remaining_frame_samples = total_frame_samples;
1197 int samples_position = 0;
1200 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets",
"final",
final,
"total_frame_samples", total_frame_samples,
"channel_layout_in_frame", channel_layout_in_frame,
"channels_in_frame", channels_in_frame,
"samples_in_frame", samples_in_frame,
"LAYOUT_MONO",
LAYOUT_MONO);
1203 AVSampleFormat output_sample_fmt = audio_codec->sample_fmt;
1205 AVFrame *audio_frame = NULL;
1210 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1213 avcodec_fill_audio_frame(audio_frame, channels_in_frame, AV_SAMPLE_FMT_S16, (uint8_t *) all_queued_samples,
1214 audio_encoder_buffer_size, 0);
1217 switch (audio_codec->sample_fmt)
1219 case AV_SAMPLE_FMT_FLTP:
1221 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1224 case AV_SAMPLE_FMT_S32P:
1226 output_sample_fmt = AV_SAMPLE_FMT_S32;
1229 case AV_SAMPLE_FMT_S16P:
1231 output_sample_fmt = AV_SAMPLE_FMT_S16;
1234 case AV_SAMPLE_FMT_U8P:
1236 output_sample_fmt = AV_SAMPLE_FMT_U8;
1242 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1243 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1246 remaining_frame_samples = total_frame_samples;
1251 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1252 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1254 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (1st resampling)",
"in_sample_fmt", AV_SAMPLE_FMT_S16,
"out_sample_fmt", output_sample_fmt,
"in_sample_rate", sample_rate_in_frame,
"out_sample_rate",
info.
sample_rate,
"in_channels", channels_in_frame,
"out_channels",
info.
channels);
1259 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1261 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1262 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1263 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1265 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1273 audio_converted->data,
1274 audio_converted->linesize[0],
1275 audio_converted->nb_samples,
1277 audio_frame->linesize[0],
1278 audio_frame->nb_samples);
1281 all_resampled_samples = (int16_t*)av_malloc(
sizeof(int16_t) * nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1284 memcpy(all_resampled_samples, audio_converted->data[0], nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1287 av_freep(&(audio_frame->data[0]));
1289 av_freep(&audio_converted->data[0]);
1291 all_queued_samples = NULL;
1293 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
"nb_samples", nb_samples,
"remaining_frame_samples", remaining_frame_samples,
"", -1,
"", -1,
"", -1,
"", -1);
1297 while (remaining_frame_samples > 0 ||
final) {
1299 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1303 if (remaining_frame_samples >= remaining_packet_samples)
1304 diff = remaining_packet_samples;
1305 else if (remaining_frame_samples < remaining_packet_samples)
1306 diff = remaining_frame_samples;
1311 memcpy(samples + (audio_input_position * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))), all_resampled_samples + samples_position, diff * av_get_bytes_per_sample(output_sample_fmt));
1314 audio_input_position += diff;
1315 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1316 remaining_frame_samples -= diff;
1317 remaining_packet_samples -= diff;
1320 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !
final)
1327 if (av_sample_fmt_is_planar(audio_codec->sample_fmt))
1329 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (2nd resampling for Planar formats)",
"in_sample_fmt", output_sample_fmt,
"out_sample_fmt", audio_codec->sample_fmt,
"in_sample_rate",
info.
sample_rate,
"out_sample_rate",
info.
sample_rate,
"in_channels",
info.
channels,
"out_channels",
info.
channels);
1336 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1337 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec->sample_fmt, 0);
1340 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1341 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1348 audio_frame->nb_samples = audio_input_position /
info.
channels;
1351 final_samples_planar = (int16_t*)av_malloc(
sizeof(int16_t) * audio_frame->nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
1354 memcpy(final_samples_planar, samples, audio_frame->nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1357 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt, (uint8_t *) final_samples_planar,
1358 audio_encoder_buffer_size, 0);
1361 frame_final->nb_samples = audio_input_frame_size;
1362 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1367 frame_final->linesize[0],
1368 frame_final->nb_samples,
1370 audio_frame->linesize[0],
1371 audio_frame->nb_samples);
1375 memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) *
info.
channels);
1378 av_freep(&(audio_frame->data[0]));
1380 all_queued_samples = NULL;
1382 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
"nb_samples", nb_samples,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1386 final_samples =
new int16_t[audio_input_position * (av_get_bytes_per_sample(audio_codec->sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))];
1389 memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1392 frame_final->nb_samples = audio_input_frame_size;
1395 avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1396 audio_encoder_buffer_size, 0);
1400 write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1401 frame_final->pts = write_audio_count;
1405 av_init_packet(&pkt);
1406 pkt.data = audio_encoder_buffer;
1407 pkt.size = audio_encoder_buffer_size;
1410 pkt.pts = pkt.dts = write_audio_count;
1413 int got_packet_ptr = 0;
1419 int frame_finished = 0;
1420 error_code = ret = avcodec_send_frame(audio_codec, frame_final);
1421 if (ret < 0 && ret != AVERROR(EINVAL) && ret != AVERROR_EOF) {
1422 avcodec_send_frame(audio_codec, NULL);
1427 ret = avcodec_receive_packet(audio_codec, &pkt);
1430 if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
1431 avcodec_flush_buffers(audio_codec);
1435 ret = frame_finished;
1438 if (!pkt.data && !frame_finished)
1442 got_packet_ptr = ret;
1445 int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1448 if (error_code == 0 && got_packet_ptr) {
1452 pkt.pts = pkt.dts = write_audio_count;
1455 if (pkt.pts != AV_NOPTS_VALUE)
1456 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1457 if (pkt.dts != AV_NOPTS_VALUE)
1458 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1459 if (pkt.duration > 0)
1460 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1463 pkt.stream_index = audio_st->index;
1464 pkt.flags |= AV_PKT_FLAG_KEY;
1467 int error_code = av_interleaved_write_frame(oc, &pkt);
1470 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1476 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_audio_packets ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1480 av_freep(&(frame_final->data[0]));
1487 audio_input_position = 0;
1492 if (all_resampled_samples) {
1493 av_freep(&all_resampled_samples);
1494 all_resampled_samples = NULL;
1496 if (all_queued_samples) {
1497 av_freep(&all_queued_samples);
1498 all_queued_samples = NULL;
1505 AVFrame* FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer)
1508 AVFrame *new_av_frame = NULL;
1512 if (new_av_frame == NULL)
1513 throw OutOfMemory(
"Could not allocate AVFrame", path);
1522 new_buffer = (uint8_t*)av_malloc(*buffer_size *
sizeof(uint8_t));
1525 new_av_frame->width = width;
1526 new_av_frame->height = height;
1527 new_av_frame->format = pix_fmt;
1531 return new_av_frame;
1535 void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame)
1538 int source_image_width = frame->GetWidth();
1539 int source_image_height = frame->GetHeight();
1542 if (source_image_height == 1 && source_image_width == 1)
1546 if (image_rescalers.size() == 0)
1547 InitScalers(source_image_width, source_image_height);
1550 SwsContext *scaler = image_rescalers[rescaler_position];
1551 rescaler_position++;
1552 if (rescaler_position == num_of_rescalers)
1553 rescaler_position = 0;
1555 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1558 int bytes_source = 0;
1559 int bytes_final = 0;
1560 AVFrame *frame_source = NULL;
1561 const uchar *pixels = NULL;
1564 pixels = frame->GetPixels();
1567 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t*) pixels);
1569 AVFrame *frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format),
info.
width,
info.
height, &bytes_final, NULL);
1571 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
1576 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::process_video_packet",
"frame->number", frame->number,
"bytes_source", bytes_source,
"bytes_final", bytes_final,
"", -1,
"", -1,
"", -1);
1579 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1580 source_image_height, frame_final->data, frame_final->linesize);
1583 #pragma omp critical (av_frames_section)
1584 add_avframe(frame, frame_final);
1594 bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame* frame_final)
1596 #if (LIBAVFORMAT_VERSION_MAJOR >= 58)
1597 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags", oc->oformat->flags,
"", -1,
"", -1,
"", -1,
"", -1);
1599 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE,
"", -1,
"", -1,
"", -1,
"", -1);
1601 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1604 av_init_packet(&pkt);
1606 pkt.flags |= AV_PKT_FLAG_KEY;
1607 pkt.stream_index= video_st->index;
1608 pkt.data= (uint8_t*)frame_final->data;
1609 pkt.size=
sizeof(AVPicture);
1612 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1613 pkt.pts = write_video_count;
1616 int error_code = av_interleaved_write_frame(oc, &pkt);
1619 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1631 av_init_packet(&pkt);
1634 pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1637 uint8_t *video_outbuf = NULL;
1640 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1643 frame_final->pts = write_video_count;
1646 int got_packet_ptr = 0;
1650 int frameFinished = 0;
1651 int ret = avcodec_send_frame(video_codec, frame_final);
1654 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet (Frame not sent)",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1655 if (ret == AVERROR(EAGAIN) )
1656 cerr <<
"Frame EAGAIN" <<
"\n";
1657 if (ret == AVERROR_EOF )
1658 cerr <<
"Frame AVERROR_EOF" <<
"\n";
1659 avcodec_send_frame(video_codec, NULL);
1663 ret = avcodec_receive_packet(video_codec, &pkt);
1664 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
1665 avcodec_flush_buffers(video_codec);
1676 #if LIBAVFORMAT_VERSION_MAJOR >= 54
1678 error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
1679 if (error_code != 0 )
1680 cerr <<
"Frame AVERROR_EOF" <<
"\n";
1681 if (got_packet_ptr == 0 )
1682 cerr <<
"Frame gotpacket error" <<
"\n";
1685 int video_outbuf_size = 200000;
1686 video_outbuf = (uint8_t*) av_malloc(200000);
1689 int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
1693 if(video_codec->coded_frame->key_frame)
1694 pkt.flags |= AV_PKT_FLAG_KEY;
1695 pkt.data= video_outbuf;
1705 if (error_code == 0 && got_packet_ptr) {
1712 if (pkt.pts != AV_NOPTS_VALUE)
1713 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
1714 if (pkt.dts != AV_NOPTS_VALUE)
1715 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
1716 if (pkt.duration > 0)
1717 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
1718 pkt.stream_index = video_st->index;
1721 int error_code = av_interleaved_write_frame(oc, &pkt);
1724 ZmqLogger::Instance()->
AppendDebugMethod(
"FFmpegWriter::write_video_packet ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1731 delete[] video_outbuf;
1745 av_dump_format(oc, 0, path.c_str(), 1);
1749 void FFmpegWriter::InitScalers(
int source_width,
int source_height)
1752 for (
int x = 0; x < num_of_rescalers; x++)
1755 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
info.
width,
info.
height,
AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec), SWS_LANCZOS, NULL, NULL, NULL);
1758 image_rescalers.push_back(img_convert_ctx);
1764 original_sample_rate = sample_rate;
1765 original_channels = channels;
1772 for (
int x = 0; x < num_of_rescalers; x++)
1773 sws_freeContext(image_rescalers[x]);
1776 image_rescalers.clear();