31 #include "../include/FFmpegWriter.h"
33 using namespace openshot;
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)
45 info.has_audio =
false;
46 info.has_video =
false;
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);
79 oc = avformat_alloc_context();
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 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();
118 if (codec.length() > 0)
120 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
121 if (new_codec == NULL)
122 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
125 info.vcodec = new_codec->name;
128 fmt->video_codec = new_codec->id;
134 info.fps.num = fps.num;
135 info.fps.den = fps.den;
138 info.video_timebase.num = info.fps.den;
139 info.video_timebase.den = info.fps.num;
144 info.height = height;
145 if (pixel_ratio.num > 0)
147 info.pixel_ratio.num = pixel_ratio.num;
148 info.pixel_ratio.den = pixel_ratio.den;
150 if (bit_rate >= 1000)
151 info.video_bit_rate = bit_rate;
153 info.interlaced_frame = interlaced;
154 info.top_field_first = top_field_first;
157 Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den);
163 info.display_ratio.num = size.
num;
164 info.display_ratio.den = size.
den;
166 AppendDebugMethod(
"FFmpegWriter::SetVideoOptions (" + codec +
")",
"width", width,
"height", height,
"size.num", size.
num,
"size.den", size.
den,
"fps.num", fps.num,
"fps.den", fps.den);
169 info.has_video = has_video;
177 if (codec.length() > 0)
179 AVCodec *new_codec = avcodec_find_encoder_by_name(codec.c_str());
180 if (new_codec == NULL)
181 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
185 info.acodec = new_codec->name;
188 fmt->audio_codec = new_codec->id;
191 if (sample_rate > 7999)
192 info.sample_rate = sample_rate;
194 info.channels = channels;
196 info.audio_bit_rate = bit_rate;
197 info.channel_layout = channel_layout;
200 if (original_sample_rate == 0)
201 original_sample_rate = info.sample_rate;
202 if (original_channels == 0)
203 original_channels = info.channels;
205 AppendDebugMethod(
"FFmpegWriter::SetAudioOptions (" + codec +
")",
"sample_rate", sample_rate,
"channels", channels,
"bit_rate", bit_rate,
"", -1,
"", -1,
"", -1);
208 info.has_audio = has_audio;
215 AVCodecContext *c = NULL;
216 stringstream convert(value);
218 if (info.has_video && stream ==
VIDEO_STREAM && video_st)
220 else if (info.has_audio && stream ==
AUDIO_STREAM && audio_st)
223 throw NoStreamsFound(
"The stream was not found. Be sure to call PrepareStreams() first.", path);
226 const AVOption *option = NULL;
231 #if LIBAVFORMAT_VERSION_MAJOR <= 53
232 option = av_find_opt(c->priv_data, name.c_str(), NULL, NULL, NULL);
234 option = av_opt_find(c->priv_data, name.c_str(), NULL, 0, 0);
238 if (option || (name ==
"g" || name ==
"qmin" || name ==
"qmax" || name ==
"max_b_frames" || name ==
"mb_decision" ||
239 name ==
"level" || name ==
"profile" || name ==
"slices" || name ==
"rc_min_rate" || name ==
"rc_max_rate"))
244 convert >> c->gop_size;
246 else if (name ==
"qmin")
250 else if (name ==
"qmax")
254 else if (name ==
"max_b_frames")
256 convert >> c->max_b_frames;
258 else if (name ==
"mb_decision")
260 convert >> c->mb_decision;
262 else if (name ==
"level")
266 else if (name ==
"profile")
268 convert >> c->profile;
270 else if (name ==
"slices")
272 convert >> c->slices;
274 else if (name ==
"rc_min_rate")
276 convert >> c->rc_min_rate;
278 else if (name ==
"rc_max_rate")
280 convert >> c->rc_max_rate;
282 else if (name ==
"rc_buffer_size")
284 convert >> c->rc_buffer_size;
288 #if LIBAVFORMAT_VERSION_MAJOR <= 53
289 av_set_string3 (c->priv_data, name.c_str(), value.c_str(), 0, NULL);
291 av_opt_set (c->priv_data, name.c_str(), value.c_str(), 0);
294 AppendDebugMethod(
"FFmpegWriter::SetOption (" + (
string)name +
")",
"stream == VIDEO_STREAM", stream ==
VIDEO_STREAM,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
298 throw InvalidOptions(
"The option is not valid for this codec.", path);
306 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
308 AppendDebugMethod(
"FFmpegWriter::PrepareStreams [" + path +
"]",
"info.has_audio",
info.
has_audio,
"info.has_video",
info.
has_video,
"", -1,
"", -1,
"", -1,
"", -1);
311 initialize_streams();
315 open_video(oc, video_st);
317 open_audio(oc, audio_st);
320 prepare_streams =
true;
327 throw InvalidOptions(
"No video or audio options have been set. You must set has_video or has_audio (or both).", path);
330 if (!(fmt->flags & AVFMT_NOFILE)) {
331 if (avio_open(&oc->pb, path.c_str(), AVIO_FLAG_WRITE) < 0)
332 throw InvalidFile(
"Could not open or write file.", path);
337 avformat_write_header(oc, NULL);
342 AppendDebugMethod(
"FFmpegWriter::WriteHeader",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
350 throw WriterClosed(
"The FFmpegWriter is closed. Call Open() before calling this method.", path);
354 if (info.has_video && video_st)
355 spooled_video_frames.push_back(frame);
357 if (info.has_audio && audio_st)
358 spooled_audio_frames.push_back(frame);
360 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);
363 if (spooled_video_frames.size() == cache_size || spooled_audio_frames.size() == cache_size)
368 write_queued_frames();
377 write_queued_frames();
388 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);
394 queued_video_frames = spooled_video_frames;
395 queued_audio_frames = spooled_audio_frames;
398 spooled_video_frames.clear();
399 spooled_audio_frames.clear();
404 omp_set_nested(
true);
407 bool has_error_encoding_video =
false;
414 if (
info.
has_audio && audio_st && !queued_audio_frames.empty())
415 write_audio_packets(
false);
418 while (!queued_video_frames.empty())
421 tr1::shared_ptr<Frame> frame = queued_video_frames.front();
424 processed_frames.push_back(frame);
428 process_video_packet(frame);
431 queued_video_frames.pop_front();
439 while (!processed_frames.empty())
442 tr1::shared_ptr<Frame> frame = processed_frames.front();
447 deallocate_frames.push_back(frame);
450 if (av_frames.count(frame))
453 AVFrame *frame_final = av_frames[frame];
456 bool success = write_video_packet(frame, frame_final);
458 has_error_encoding_video =
true;
463 processed_frames.pop_front();
467 while (!deallocate_frames.empty())
470 tr1::shared_ptr<Frame> frame = deallocate_frames.front();
473 if (av_frames.count(frame))
476 AVFrame *av_frame = av_frames[frame];
479 free(av_frame->data[0]);
481 av_frames.erase(frame);
485 deallocate_frames.pop_front();
495 if (has_error_encoding_video)
496 throw ErrorEncodingVideo(
"Error while writing raw video frame", -1);
502 AppendDebugMethod(
"FFmpegWriter::WriteFrame (from Reader)",
"start", start,
"length", length,
"", -1,
"", -1,
"", -1,
"", -1);
505 for (
long int number = start; number <= length; number++)
508 tr1::shared_ptr<Frame> f = reader->GetFrame(number);
519 write_queued_frames();
523 write_audio_packets(
true);
532 av_write_trailer(oc);
535 write_trailer =
true;
537 AppendDebugMethod(
"FFmpegWriter::WriteTrailer",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
541 void FFmpegWriter::flush_encoders()
543 if (
info.
has_audio && audio_codec && audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_codec->frame_size <= 1)
545 if (
info.
has_video && video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && video_codec->codec->id == AV_CODEC_ID_RAWVIDEO)
549 int stop_encoding = 1;
556 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
559 av_init_packet(&pkt);
564 uint8_t *video_outbuf = NULL;
570 #if LIBAVFORMAT_VERSION_MAJOR >= 54
572 error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
578 int video_outbuf_size = 0;
582 int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
586 if(video_codec->coded_frame->key_frame)
587 pkt.flags |= AV_PKT_FLAG_KEY;
588 pkt.data= video_outbuf;
596 if (error_code < 0) {
597 AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
608 if (pkt.pts != AV_NOPTS_VALUE)
609 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
610 if (pkt.dts != AV_NOPTS_VALUE)
611 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
612 if (pkt.duration > 0)
613 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
614 pkt.stream_index = video_st->index;
617 error_code = av_interleaved_write_frame(oc, &pkt);
618 if (error_code < 0) {
619 AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
624 delete[] video_outbuf;
632 #if LIBAVFORMAT_VERSION_MAJOR >= 54
634 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);
636 write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1,
info.
sample_rate}, audio_codec->time_base);
640 av_init_packet(&pkt);
643 pkt.pts = pkt.dts = write_audio_count;
647 error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet);
648 if (error_code < 0) {
649 AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
658 pkt.pts = pkt.dts = write_audio_count;
661 if (pkt.pts != AV_NOPTS_VALUE)
662 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
663 if (pkt.dts != AV_NOPTS_VALUE)
664 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
665 if (pkt.duration > 0)
666 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
669 pkt.stream_index = audio_st->index;
670 pkt.flags |= AV_PKT_FLAG_KEY;
673 error_code = av_interleaved_write_frame(oc, &pkt);
674 if (error_code < 0) {
675 AppendDebugMethod(
"FFmpegWriter::flush_encoders ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
679 av_free_packet(&pkt);
686 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
688 avcodec_close(st->codec);
693 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
695 avcodec_close(st->codec);
700 delete[] audio_outbuf;
701 delete[] audio_encoder_buffer;
704 audio_encoder_buffer = NULL;
708 avresample_close(avr);
709 avresample_free(&avr);
714 avresample_close(avr_planar);
715 avresample_free(&avr_planar);
729 close_video(oc, video_st);
731 close_audio(oc, audio_st);
734 if (image_rescalers.size() > 0)
738 for (
int i = 0; i < oc->nb_streams; i++) {
739 av_freep(&oc->streams[i]->codec);
740 av_freep(&oc->streams[i]);
743 if (!(fmt->flags & AVFMT_NOFILE)) {
749 write_video_count = 0;
750 write_audio_count = 0;
757 prepare_streams =
false;
758 write_header =
false;
759 write_trailer =
false;
761 AppendDebugMethod(
"FFmpegWriter::Close",
"", -1,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
765 void FFmpegWriter::add_avframe(tr1::shared_ptr<Frame> frame, AVFrame* av_frame)
768 if (!av_frames.count(frame))
771 av_frames[frame] = av_frame;
781 AVStream* FFmpegWriter::add_audio_stream()
787 AVCodec *codec = avcodec_find_encoder_by_name(
info.
acodec.c_str());
789 throw InvalidCodec(
"A valid audio codec could not be found for this file.", path);
792 st = avformat_new_stream(oc, codec);
794 throw OutOfMemory(
"Could not allocate memory for the audio stream.", path);
797 avcodec_get_context_defaults3(st->codec, codec);
800 c->codec_id = codec->id;
801 #if LIBAVFORMAT_VERSION_MAJOR >= 53
802 c->codec_type = AVMEDIA_TYPE_AUDIO;
804 c->codec_type = CODEC_TYPE_AUDIO;
812 if (codec->supported_samplerates) {
814 for (i = 0; codec->supported_samplerates[i] != 0; i++)
821 if (codec->supported_samplerates[i] == 0)
822 throw InvalidSampleRate(
"An invalid sample rate was detected for this codec.", path);
830 if (codec->channel_layouts) {
832 for (i = 0; codec->channel_layouts[i] != 0; i++)
833 if (channel_layout == codec->channel_layouts[i])
836 c->channel_layout = channel_layout;
839 if (codec->channel_layouts[i] == 0)
840 throw InvalidChannels(
"An invalid channel layout was detected (i.e. MONO / STEREO).", path);
843 c->channel_layout = channel_layout;
846 if (codec->sample_fmts) {
847 for (
int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++)
850 c->sample_fmt = codec->sample_fmts[i];
854 if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
856 c->sample_fmt = AV_SAMPLE_FMT_S16;
860 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
861 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
863 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);
869 AVStream* FFmpegWriter::add_video_stream()
875 AVCodec *codec = avcodec_find_encoder_by_name(
info.
vcodec.c_str());
877 throw InvalidCodec(
"A valid video codec could not be found for this file.", path);
880 st = avformat_new_stream(oc, codec);
882 throw OutOfMemory(
"Could not allocate memory for the video stream.", path);
885 avcodec_get_context_defaults3(st->codec, codec);
888 c->codec_id = codec->id;
889 #if LIBAVFORMAT_VERSION_MAJOR >= 53
890 c->codec_type = AVMEDIA_TYPE_VIDEO;
892 c->codec_type = CODEC_TYPE_VIDEO;
899 c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384;
915 c->max_b_frames = 10;
916 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
919 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
925 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
926 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
929 const PixelFormat* supported_pixel_formats = codec->pix_fmts;
930 while (supported_pixel_formats != NULL && *supported_pixel_formats !=
PIX_FMT_NONE) {
933 c->pix_fmt = *supported_pixel_formats;
934 ++supported_pixel_formats;
939 if(fmt->video_codec == AV_CODEC_ID_RAWVIDEO) {
943 if (strcmp(fmt->name,
"gif") != 0)
946 oc->oformat->flags |= AVFMT_RAWPICTURE;
953 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);
959 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
962 audio_codec = st->codec;
968 codec = avcodec_find_encoder(audio_codec->codec_id);
973 if (avcodec_open2(audio_codec, codec, NULL) < 0)
978 if (audio_codec->frame_size <= 1) {
982 switch (st->codec->codec_id) {
983 case AV_CODEC_ID_PCM_S16LE:
984 case AV_CODEC_ID_PCM_S16BE:
985 case AV_CODEC_ID_PCM_U16LE:
986 case AV_CODEC_ID_PCM_U16BE:
987 audio_input_frame_size >>= 1;
994 audio_input_frame_size = audio_codec->frame_size;
998 initial_audio_input_frame_size = audio_input_frame_size;
1005 audio_outbuf =
new uint8_t[audio_outbuf_size];
1009 audio_encoder_buffer =
new uint8_t[audio_encoder_buffer_size];
1011 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 + FF_INPUT_BUFFER_PADDING_SIZE,
"", -1,
"", -1,
"", -1);
1016 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
1019 video_codec = st->codec;
1025 codec = avcodec_find_encoder(video_codec->codec_id);
1030 if (avcodec_open2(video_codec, codec, NULL) < 0)
1033 AppendDebugMethod(
"FFmpegWriter::open_video",
"video_codec->thread_count", video_codec->thread_count,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1038 void FFmpegWriter::write_audio_packets(
bool final)
1040 #pragma omp task firstprivate(final)
1043 int total_frame_samples = 0;
1044 int frame_position = 0;
1045 int channels_in_frame = 0;
1046 int sample_rate_in_frame = 0;
1047 int samples_in_frame = 0;
1052 int16_t* all_resampled_samples = NULL;
1053 int16_t* final_samples_planar = NULL;
1054 int16_t* final_samples = NULL;
1057 while (!queued_audio_frames.empty())
1060 tr1::shared_ptr<Frame> frame = queued_audio_frames.front();
1063 sample_rate_in_frame = frame->SampleRate();
1064 samples_in_frame = frame->GetAudioSamplesCount();
1065 channels_in_frame = frame->GetAudioChannelsCount();
1066 channel_layout_in_frame = frame->ChannelsLayout();
1070 float* frame_samples_float = NULL;
1072 frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
1076 total_frame_samples = samples_in_frame * channels_in_frame;
1079 for (
int s = 0; s < total_frame_samples; s++, frame_position++)
1081 all_queued_samples[frame_position] =
int(frame_samples_float[s] * (1 << 15));
1085 delete[] frame_samples_float;
1088 queued_audio_frames.pop_front();
1094 total_frame_samples = frame_position;
1095 int remaining_frame_samples = total_frame_samples;
1096 int samples_position = 0;
1099 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);
1102 AVSampleFormat output_sample_fmt = audio_codec->sample_fmt;
1104 AVFrame *audio_frame = NULL;
1109 audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1112 avcodec_fill_audio_frame(audio_frame, channels_in_frame, AV_SAMPLE_FMT_S16, (uint8_t *) all_queued_samples,
1113 audio_encoder_buffer_size, 0);
1116 switch (audio_codec->sample_fmt)
1118 case AV_SAMPLE_FMT_FLTP:
1120 output_sample_fmt = AV_SAMPLE_FMT_FLT;
1123 case AV_SAMPLE_FMT_S32P:
1125 output_sample_fmt = AV_SAMPLE_FMT_S32;
1128 case AV_SAMPLE_FMT_S16P:
1130 output_sample_fmt = AV_SAMPLE_FMT_S16;
1133 case AV_SAMPLE_FMT_U8P:
1135 output_sample_fmt = AV_SAMPLE_FMT_U8;
1141 total_frame_samples *= (float(
info.
sample_rate) / sample_rate_in_frame);
1142 total_frame_samples *= (float(
info.
channels) / channels_in_frame);
1145 remaining_frame_samples = total_frame_samples;
1150 audio_converted->nb_samples = total_frame_samples / channels_in_frame;
1151 av_samples_alloc(audio_converted->data, audio_converted->linesize,
info.
channels, audio_converted->nb_samples, output_sample_fmt, 0);
1153 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);
1157 avr = avresample_alloc_context();
1158 av_opt_set_int(avr,
"in_channel_layout", channel_layout_in_frame, 0);
1160 av_opt_set_int(avr,
"in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
1161 av_opt_set_int(avr,
"out_sample_fmt", output_sample_fmt, 0);
1162 av_opt_set_int(avr,
"in_sample_rate", sample_rate_in_frame, 0);
1164 av_opt_set_int(avr,
"in_channels", channels_in_frame, 0);
1166 avresample_open(avr);
1171 nb_samples = avresample_convert(avr,
1172 audio_converted->data,
1173 audio_converted->linesize[0],
1174 audio_converted->nb_samples,
1176 audio_frame->linesize[0],
1177 audio_frame->nb_samples);
1180 all_resampled_samples =
new int16_t[nb_samples *
info.
channels * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16))];
1183 memcpy(all_resampled_samples, audio_converted->data[0], nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1186 free(audio_frame->data[0]);
1188 av_free(audio_converted->data[0]);
1190 all_queued_samples = NULL;
1192 AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)",
"nb_samples", nb_samples,
"remaining_frame_samples", remaining_frame_samples,
"", -1,
"", -1,
"", -1,
"", -1);
1196 while (remaining_frame_samples > 0 ||
final) {
1198 int remaining_packet_samples = (audio_input_frame_size *
info.
channels) - audio_input_position;
1202 if (remaining_frame_samples >= remaining_packet_samples)
1203 diff = remaining_packet_samples;
1204 else if (remaining_frame_samples < remaining_packet_samples)
1205 diff = remaining_frame_samples;
1210 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));
1213 audio_input_position += diff;
1214 samples_position += diff * (av_get_bytes_per_sample(output_sample_fmt) / av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
1215 remaining_frame_samples -= diff;
1216 remaining_packet_samples -= diff;
1219 if (audio_input_position < (audio_input_frame_size *
info.
channels) && !
final)
1226 if (av_sample_fmt_is_planar(audio_codec->sample_fmt))
1228 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);
1232 avr_planar = avresample_alloc_context();
1235 av_opt_set_int(avr_planar,
"in_sample_fmt", output_sample_fmt, 0);
1236 av_opt_set_int(avr_planar,
"out_sample_fmt", audio_codec->sample_fmt, 0);
1239 av_opt_set_int(avr_planar,
"in_channels",
info.
channels, 0);
1240 av_opt_set_int(avr_planar,
"out_channels",
info.
channels, 0);
1241 avresample_open(avr_planar);
1247 audio_frame->nb_samples = audio_input_position /
info.
channels;
1250 final_samples_planar =
new 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))];
1253 memcpy(final_samples_planar, samples, audio_frame->nb_samples *
info.
channels * av_get_bytes_per_sample(output_sample_fmt));
1256 avcodec_fill_audio_frame(audio_frame,
info.
channels, output_sample_fmt, (uint8_t *) final_samples_planar,
1257 audio_encoder_buffer_size, 0);
1260 frame_final->nb_samples = audio_input_frame_size;
1261 av_samples_alloc(frame_final->data, frame_final->linesize,
info.
channels, frame_final->nb_samples, audio_codec->sample_fmt, 0);
1264 int nb_samples = avresample_convert(avr_planar,
1266 frame_final->linesize[0],
1267 frame_final->nb_samples,
1269 audio_frame->linesize[0],
1270 audio_frame->nb_samples);
1274 memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) *
info.
channels);
1277 free(audio_frame->data[0]);
1280 AppendDebugMethod(
"FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)",
"nb_samples", nb_samples,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1284 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))];
1287 memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1290 frame_final->nb_samples = audio_input_frame_size;
1293 avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1294 audio_encoder_buffer_size, 0);
1298 write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1299 frame_final->pts = write_audio_count;
1303 av_init_packet(&pkt);
1304 pkt.data = audio_encoder_buffer;
1305 pkt.size = audio_encoder_buffer_size;
1308 pkt.pts = pkt.dts = write_audio_count;
1311 int got_packet_ptr = 0;
1312 int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1315 if (error_code == 0 && got_packet_ptr) {
1319 pkt.pts = pkt.dts = write_audio_count;
1322 if (pkt.pts != AV_NOPTS_VALUE)
1323 pkt.pts = av_rescale_q(pkt.pts, audio_codec->time_base, audio_st->time_base);
1324 if (pkt.dts != AV_NOPTS_VALUE)
1325 pkt.dts = av_rescale_q(pkt.dts, audio_codec->time_base, audio_st->time_base);
1326 if (pkt.duration > 0)
1327 pkt.duration = av_rescale_q(pkt.duration, audio_codec->time_base, audio_st->time_base);
1330 pkt.stream_index = audio_st->index;
1331 pkt.flags |= AV_PKT_FLAG_KEY;
1334 int error_code = av_interleaved_write_frame(oc, &pkt);
1337 AppendDebugMethod(
"FFmpegWriter::write_audio_packets ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1343 AppendDebugMethod(
"FFmpegWriter::write_audio_packets ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1351 av_free_packet(&pkt);
1354 audio_input_position = 0;
1359 if (all_resampled_samples) {
1360 delete[] all_resampled_samples;
1361 all_resampled_samples = NULL;
1363 if (all_queued_samples) {
1364 delete[] all_queued_samples;
1365 all_queued_samples = NULL;
1372 AVFrame* FFmpegWriter::allocate_avframe(
PixelFormat pix_fmt,
int width,
int height,
int *buffer_size, uint8_t *new_buffer)
1375 AVFrame *new_av_frame = NULL;
1379 if (new_av_frame == NULL)
1380 throw OutOfMemory(
"Could not allocate AVFrame", path);
1383 *buffer_size = avpicture_get_size(pix_fmt, width, height);
1389 new_buffer =
new uint8_t[*buffer_size];
1391 avpicture_fill((AVPicture *)new_av_frame, new_buffer, pix_fmt, width, height);
1392 new_av_frame->width = width;
1393 new_av_frame->height = height;
1394 new_av_frame->format = pix_fmt;
1398 return new_av_frame;
1402 void FFmpegWriter::process_video_packet(tr1::shared_ptr<Frame> frame)
1405 int source_image_width = frame->GetWidth();
1406 int source_image_height = frame->GetHeight();
1409 if (source_image_height == 1 && source_image_width == 1)
1413 if (image_rescalers.size() == 0)
1414 InitScalers(source_image_width, source_image_height);
1417 SwsContext *scaler = image_rescalers[rescaler_position];
1418 rescaler_position++;
1419 if (rescaler_position == num_of_rescalers)
1420 rescaler_position = 0;
1422 #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1425 int bytes_source = 0;
1426 int bytes_final = 0;
1427 AVFrame *frame_source = NULL;
1428 const uchar *pixels = NULL;
1431 pixels = frame->GetPixels();
1434 frame_source = allocate_avframe(
PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t*) pixels);
1435 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt,
info.
width,
info.
height, &bytes_final, NULL);
1438 avpicture_fill((AVPicture *) frame_source, (uint8_t*)pixels,
PIX_FMT_RGBA, source_image_width, source_image_height);
1439 AppendDebugMethod(
"FFmpegWriter::process_video_packet",
"frame->number", frame->number,
"bytes_source", bytes_source,
"bytes_final", bytes_final,
"", -1,
"", -1,
"", -1);
1442 sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1443 source_image_height, frame_final->data, frame_final->linesize);
1446 #pragma omp critical (av_frames_section)
1447 add_avframe(frame, frame_final);
1457 bool FFmpegWriter::write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* frame_final)
1459 AppendDebugMethod(
"FFmpegWriter::write_video_packet",
"frame->number", frame->number,
"oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE,
"", -1,
"", -1,
"", -1,
"", -1);
1461 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1464 av_init_packet(&pkt);
1466 pkt.flags |= AV_PKT_FLAG_KEY;
1467 pkt.stream_index= video_st->index;
1468 pkt.data= (uint8_t*)frame_final->data;
1469 pkt.size=
sizeof(AVPicture);
1472 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1473 pkt.pts = write_video_count;
1476 int error_code = av_interleaved_write_frame(oc, &pkt);
1479 AppendDebugMethod(
"FFmpegWriter::write_video_packet ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1484 av_free_packet(&pkt);
1489 av_init_packet(&pkt);
1492 pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1495 uint8_t *video_outbuf = NULL;
1498 write_video_count += av_rescale_q(1, (AVRational){
info.
fps.
den,
info.
fps.
num}, video_codec->time_base);
1501 frame_final->pts = write_video_count;
1504 int got_packet_ptr = 0;
1506 #if LIBAVFORMAT_VERSION_MAJOR >= 54
1508 error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
1514 int video_outbuf_size = 200000;
1515 video_outbuf =
new uint8_t[200000];
1518 int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
1522 if(video_codec->coded_frame->key_frame)
1523 pkt.flags |= AV_PKT_FLAG_KEY;
1524 pkt.data= video_outbuf;
1533 if (error_code == 0 && got_packet_ptr) {
1540 if (pkt.pts != AV_NOPTS_VALUE)
1541 pkt.pts = av_rescale_q(pkt.pts, video_codec->time_base, video_st->time_base);
1542 if (pkt.dts != AV_NOPTS_VALUE)
1543 pkt.dts = av_rescale_q(pkt.dts, video_codec->time_base, video_st->time_base);
1544 if (pkt.duration > 0)
1545 pkt.duration = av_rescale_q(pkt.duration, video_codec->time_base, video_st->time_base);
1546 pkt.stream_index = video_st->index;
1549 int error_code = av_interleaved_write_frame(oc, &pkt);
1552 AppendDebugMethod(
"FFmpegWriter::write_video_packet ERROR [" + (
string)
av_err2str(error_code) +
"]",
"error_code", error_code,
"", -1,
"", -1,
"", -1,
"", -1,
"", -1);
1559 delete[] video_outbuf;
1562 av_free_packet(&pkt);
1573 av_dump_format(oc, 0, path.c_str(), 1);
1577 void FFmpegWriter::InitScalers(
int source_width,
int source_height)
1581 c = video_st->codec;
1584 for (
int x = 0; x < num_of_rescalers; x++)
1587 img_convert_ctx = sws_getContext(source_width, source_height,
PIX_FMT_RGBA,
info.
width,
info.
height, c->pix_fmt, SWS_FAST_BILINEAR, NULL, NULL, NULL);
1590 image_rescalers.push_back(img_convert_ctx);
1596 original_sample_rate = sample_rate;
1597 original_channels = channels;
1604 for (
int x = 0; x < num_of_rescalers; x++)
1605 sws_freeContext(image_rescalers[x]);
1608 image_rescalers.clear();
#define AV_RESET_FRAME(av_frame)
int channels
The number of audio channels used in the audio stream.
A video stream (used to determine which type of stream)
void AppendDebugMethod(string method_name, string arg1_name, float arg1_value, string arg2_name, float arg2_value, string arg3_name, float arg3_value, string arg4_name, float arg4_value, string arg5_name, float arg5_value, string arg6_name, float arg6_value)
Append debug information as JSON.
#define AV_FREE_FRAME(av_frame)
void SetOption(StreamType stream, string name, string value)
Set custom options (some codecs accept additional params). This must be called after the PrepareStrea...
int num
Numerator for the fraction.
WriterInfo info
Information about the current media file.
void OutputStreamInfo()
Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
An audio stream (used to determine which type of stream)
int video_bit_rate
The bit rate of the video stream (in bytes)
Exception when an invalid # of audio channels are detected.
string acodec
The name of the audio codec used to encode / decode the video stream.
string vcodec
The name of the video codec used to encode / decode the video stream.
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
This abstract class is the base class, used by all readers in libopenshot.
int width
The width of the video (in pixels)
int audio_bit_rate
The bit rate of the audio stream (in bytes)
#define OPEN_MP_NUM_PROCESSORS
Exception when encoding audio packet.
Exception when invalid sample rate is detected during encoding.
Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
void SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
Set video export options.
void WriteFrame(tr1::shared_ptr< Frame > frame)
Add a frame to the stack waiting to be encoded.
Exception when no valid codec is found for a file.
Exception when memory could not be allocated.
Exception when invalid encoding options are used.
Exception when no streams are found in the file.
void RemoveScalers()
Remove & deallocate all software scalers.
#define AV_ALLOCATE_FRAME()
Exception for files that can not be found or opened.
FFmpegWriter(string path)
Constructor for FFmpegWriter. Throws one of the following exceptions.
This class represents a fraction.
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround...
void WriteTrailer()
Write the file trailer (after all frames are written). This is called automatically by the Close() me...
#define av_err2str(errnum)
void WriteHeader()
Write the file header (after the options are set). This method is called automatically by the Open() ...
void Close()
Close the writer.
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
bool has_video
Determines if this file has a video stream.
Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
bool has_audio
Determines if this file has an audio stream.
void SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate)
Set audio export options.
Exception when a writer is closed, and a frame is requested.
ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
void PrepareStreams()
Prepare & initialize streams and open codecs. This method is called automatically by the Open() metho...
int height
The height of the video (in pixels)
int den
Denominator for the fraction.
#define AUDIO_PACKET_ENCODING_SIZE
StreamType
This enumeration designates the type of stream when encoding (video or audio)