OpenShot Library | libopenshot  0.1.1
FFmpegWriter.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Source file for FFmpegWriter class
4  * @author Jonathan Thomas <jonathan@openshot.org>, Fabrice Bellard
5  *
6  * @section LICENSE
7  *
8  * Copyright (c) 2008-2013 OpenShot Studios, LLC, Fabrice Bellard
9  * (http://www.openshotstudios.com). This file is part of
10  * OpenShot Library (http://www.openshot.org), an open-source project
11  * dedicated to delivering high quality video editing and animation solutions
12  * to the world.
13  *
14  * This file is originally based on the Libavformat API example, and then modified
15  * by the libopenshot project.
16  *
17  * OpenShot Library (libopenshot) is free software: you can redistribute it
18  * and/or modify it under the terms of the GNU Lesser General Public License
19  * as published by the Free Software Foundation, either version 3 of the
20  * License, or (at your option) any later version.
21  *
22  * OpenShot Library (libopenshot) is distributed in the hope that it will be
23  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public License
28  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include "../include/FFmpegWriter.h"
32 
33 using namespace openshot;
34 
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)
42 {
43 
44  // Disable audio & video (so they can be independently enabled)
45  info.has_audio = false;
46  info.has_video = false;
47 
48  // Initialize FFMpeg, and register all formats and codecs
49  av_register_all();
50 
51  // auto detect format
52  auto_detect_format();
53 }
54 
55 // Open the writer
57 {
58  // Open the writer
59  is_open = true;
60 
61  // Prepare streams (if needed)
62  if (!prepare_streams)
64 
65  // Write header (if needed)
66  if (!write_header)
67  WriteHeader();
68 }
69 
70 // auto detect format (from path)
71 void FFmpegWriter::auto_detect_format()
72 {
73  // Auto detect the output format from the name. default is mpeg.
74  fmt = av_guess_format(NULL, path.c_str(), NULL);
75  if (!fmt)
76  throw InvalidFormat("Could not deduce output format from file extension.", path);
77 
78  // Allocate the output media context
79  oc = avformat_alloc_context();
80  if (!oc)
81  throw OutOfMemory("Could not allocate memory for AVFormatContext.", path);
82 
83  // Set the AVOutputFormat for the current AVFormatContext
84  oc->oformat = fmt;
85 
86  // Update codec names
87  if (fmt->video_codec != AV_CODEC_ID_NONE && info.has_video)
88  // Update video codec name
89  info.vcodec = avcodec_find_encoder(fmt->video_codec)->name;
90 
91  if (fmt->audio_codec != AV_CODEC_ID_NONE && info.has_audio)
92  // Update audio codec name
93  info.acodec = avcodec_find_encoder(fmt->audio_codec)->name;
94 }
95 
96 // initialize streams
97 void FFmpegWriter::initialize_streams()
98 {
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);
100 
101  // Add the audio and video streams using the default format codecs and initialize the codecs
102  video_st = NULL;
103  audio_st = NULL;
104  if (fmt->video_codec != AV_CODEC_ID_NONE && info.has_video)
105  // Add video stream
106  video_st = add_video_stream();
107 
108  if (fmt->audio_codec != AV_CODEC_ID_NONE && info.has_audio)
109  // Add audio stream
110  audio_st = add_audio_stream();
111 }
112 
113 // Set video export options
114 void FFmpegWriter::SetVideoOptions(bool has_video, string codec, Fraction fps, int width, int height, Fraction pixel_ratio, bool interlaced, bool top_field_first, int bit_rate)
116 {
117  // Set the video options
118  if (codec.length() > 0)
119  {
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);
123  else {
124  // Set video codec
125  info.vcodec = new_codec->name;
126 
127  // Update video codec in fmt
128  fmt->video_codec = new_codec->id;
129  }
130  }
131  if (fps.num > 0)
132  {
133  // Set frames per second (if provided)
134  info.fps.num = fps.num;
135  info.fps.den = fps.den;
136 
137  // Set the timebase (inverse of fps)
138  info.video_timebase.num = info.fps.den;
139  info.video_timebase.den = info.fps.num;
140  }
141  if (width >= 1)
142  info.width = width;
143  if (height >= 1)
144  info.height = height;
145  if (pixel_ratio.num > 0)
146  {
147  info.pixel_ratio.num = pixel_ratio.num;
148  info.pixel_ratio.den = pixel_ratio.den;
149  }
150  if (bit_rate >= 1000)
151  info.video_bit_rate = bit_rate;
152 
153  info.interlaced_frame = interlaced;
154  info.top_field_first = top_field_first;
155 
156  // Calculate the DAR (display aspect ratio)
157  Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den);
158 
159  // Reduce size fraction
160  size.Reduce();
161 
162  // Set the ratio based on the reduced fraction
163  info.display_ratio.num = size.num;
164  info.display_ratio.den = size.den;
165 
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);
167 
168  // Enable / Disable video
169  info.has_video = has_video;
170 }
171 
172 // Set audio export options
173 void FFmpegWriter::SetAudioOptions(bool has_audio, string codec, int sample_rate, int channels, ChannelLayout channel_layout, int bit_rate)
175 {
176  // Set audio options
177  if (codec.length() > 0)
178  {
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);
182  else
183  {
184  // Set audio codec
185  info.acodec = new_codec->name;
186 
187  // Update audio codec in fmt
188  fmt->audio_codec = new_codec->id;
189  }
190  }
191  if (sample_rate > 7999)
192  info.sample_rate = sample_rate;
193  if (channels > 0)
194  info.channels = channels;
195  if (bit_rate > 999)
196  info.audio_bit_rate = bit_rate;
197  info.channel_layout = channel_layout;
198 
199  // init resample options (if zero)
200  if (original_sample_rate == 0)
201  original_sample_rate = info.sample_rate;
202  if (original_channels == 0)
203  original_channels = info.channels;
204 
205  AppendDebugMethod("FFmpegWriter::SetAudioOptions (" + codec + ")", "sample_rate", sample_rate, "channels", channels, "bit_rate", bit_rate, "", -1, "", -1, "", -1);
206 
207  // Enable / Disable audio
208  info.has_audio = has_audio;
209 }
210 
211 // Set custom options (some codecs accept additional params)
212 void FFmpegWriter::SetOption(StreamType stream, string name, string value) throw(NoStreamsFound, InvalidOptions)
213 {
214  // Declare codec context
215  AVCodecContext *c = NULL;
216  stringstream convert(value);
217 
218  if (info.has_video && stream == VIDEO_STREAM && video_st)
219  c = video_st->codec;
220  else if (info.has_audio && stream == AUDIO_STREAM && audio_st)
221  c = audio_st->codec;
222  else
223  throw NoStreamsFound("The stream was not found. Be sure to call PrepareStreams() first.", path);
224 
225  // Init AVOption
226  const AVOption *option = NULL;
227 
228  // Was a codec / stream found?
229  if (c)
230  // Find AVOption (if it exists)
231  #if LIBAVFORMAT_VERSION_MAJOR <= 53
232  option = av_find_opt(c->priv_data, name.c_str(), NULL, NULL, NULL);
233  #else
234  option = av_opt_find(c->priv_data, name.c_str(), NULL, 0, 0);
235  #endif
236 
237  // Was option found?
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"))
240  {
241  // Check for specific named options
242  if (name == "g")
243  // Set gop_size
244  convert >> c->gop_size;
245 
246  else if (name == "qmin")
247  // Minimum quantizer
248  convert >> c->qmin;
249 
250  else if (name == "qmax")
251  // Maximum quantizer
252  convert >> c->qmax;
253 
254  else if (name == "max_b_frames")
255  // Maximum number of B-frames between non-B-frames
256  convert >> c->max_b_frames;
257 
258  else if (name == "mb_decision")
259  // Macroblock decision mode
260  convert >> c->mb_decision;
261 
262  else if (name == "level")
263  // Set codec level
264  convert >> c->level;
265 
266  else if (name == "profile")
267  // Set codec profile
268  convert >> c->profile;
269 
270  else if (name == "slices")
271  // Indicates number of picture subdivisions
272  convert >> c->slices;
273 
274  else if (name == "rc_min_rate")
275  // Minimum bitrate
276  convert >> c->rc_min_rate;
277 
278  else if (name == "rc_max_rate")
279  // Maximum bitrate
280  convert >> c->rc_max_rate;
281 
282  else if (name == "rc_buffer_size")
283  // Buffer size
284  convert >> c->rc_buffer_size;
285 
286  else
287  // Set AVOption
288  #if LIBAVFORMAT_VERSION_MAJOR <= 53
289  av_set_string3 (c->priv_data, name.c_str(), value.c_str(), 0, NULL);
290  #else
291  av_opt_set (c->priv_data, name.c_str(), value.c_str(), 0);
292  #endif
293 
294  AppendDebugMethod("FFmpegWriter::SetOption (" + (string)name + ")", "stream == VIDEO_STREAM", stream == VIDEO_STREAM, "", -1, "", -1, "", -1, "", -1, "", -1);
295 
296  }
297  else
298  throw InvalidOptions("The option is not valid for this codec.", path);
299 
300 }
301 
302 // Prepare & initialize streams and open codecs
304 {
305  if (!info.has_audio && !info.has_video)
306  throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
307 
308  AppendDebugMethod("FFmpegWriter::PrepareStreams [" + path + "]", "info.has_audio", info.has_audio, "info.has_video", info.has_video, "", -1, "", -1, "", -1, "", -1);
309 
310  // Initialize the streams (i.e. add the streams)
311  initialize_streams();
312 
313  // Now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers
314  if (info.has_video && video_st)
315  open_video(oc, video_st);
316  if (info.has_audio && audio_st)
317  open_audio(oc, audio_st);
318 
319  // Mark as 'prepared'
320  prepare_streams = true;
321 }
322 
323 // Write the file header (after the options are set)
325 {
326  if (!info.has_audio && !info.has_video)
327  throw InvalidOptions("No video or audio options have been set. You must set has_video or has_audio (or both).", path);
328 
329  // Open the output file, if needed
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);
333  }
334 
335  // Write the stream header, if any
336  // TODO: add avoptions / parameters instead of NULL
337  avformat_write_header(oc, NULL);
338 
339  // Mark as 'written'
340  write_header = true;
341 
342  AppendDebugMethod("FFmpegWriter::WriteHeader", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
343 }
344 
345 // Add a frame to the queue waiting to be encoded.
346 void FFmpegWriter::WriteFrame(tr1::shared_ptr<Frame> frame) throw(ErrorEncodingVideo, WriterClosed)
347 {
348  // Check for open reader (or throw exception)
349  if (!is_open)
350  throw WriterClosed("The FFmpegWriter is closed. Call Open() before calling this method.", path);
351 
352  // Add frame pointer to "queue", waiting to be processed the next
353  // time the WriteFrames() method is called.
354  if (info.has_video && video_st)
355  spooled_video_frames.push_back(frame);
356 
357  if (info.has_audio && audio_st)
358  spooled_audio_frames.push_back(frame);
359 
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);
361 
362  // Write the frames once it reaches the correct cache size
363  if (spooled_video_frames.size() == cache_size || spooled_audio_frames.size() == cache_size)
364  {
365  // Is writer currently writing?
366  if (!is_writing)
367  // Write frames to video file
368  write_queued_frames();
369 
370  else
371  {
372  // YES, WRITING... so wait until it finishes, before writing again
373  while (is_writing)
374  usleep(250000); // sleep for 250 milliseconds
375 
376  // Write frames to video file
377  write_queued_frames();
378  }
379  }
380 
381  // Keep track of the last frame added
382  last_frame = frame;
383 }
384 
385 // Write all frames in the queue to the video file.
386 void FFmpegWriter::write_queued_frames() throw (ErrorEncodingVideo)
387 {
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);
389 
390  // Flip writing flag
391  is_writing = true;
392 
393  // Transfer spool to queue
394  queued_video_frames = spooled_video_frames;
395  queued_audio_frames = spooled_audio_frames;
396 
397  // Empty spool
398  spooled_video_frames.clear();
399  spooled_audio_frames.clear();
400 
401  // Set the number of threads in OpenMP
402  omp_set_num_threads(OPEN_MP_NUM_PROCESSORS);
403  // Allow nested OpenMP sections
404  omp_set_nested(true);
405 
406  // Create blank exception
407  bool has_error_encoding_video = false;
408 
409  #pragma omp parallel
410  {
411  #pragma omp single
412  {
413  // Process all audio frames (in a separate thread)
414  if (info.has_audio && audio_st && !queued_audio_frames.empty())
415  write_audio_packets(false);
416 
417  // Loop through each queued image frame
418  while (!queued_video_frames.empty())
419  {
420  // Get front frame (from the queue)
421  tr1::shared_ptr<Frame> frame = queued_video_frames.front();
422 
423  // Add to processed queue
424  processed_frames.push_back(frame);
425 
426  // Encode and add the frame to the output file
427  if (info.has_video && video_st)
428  process_video_packet(frame);
429 
430  // Remove front item
431  queued_video_frames.pop_front();
432 
433  } // end while
434  } // end omp single
435 
436  #pragma omp single
437  {
438  // Loop back through the frames (in order), and write them to the video file
439  while (!processed_frames.empty())
440  {
441  // Get front frame (from the queue)
442  tr1::shared_ptr<Frame> frame = processed_frames.front();
443 
444  if (info.has_video && video_st)
445  {
446  // Add to deallocate queue (so we can remove the AVFrames when we are done)
447  deallocate_frames.push_back(frame);
448 
449  // Does this frame's AVFrame still exist
450  if (av_frames.count(frame))
451  {
452  // Get AVFrame
453  AVFrame *frame_final = av_frames[frame];
454 
455  // Write frame to video file
456  bool success = write_video_packet(frame, frame_final);
457  if (!success)
458  has_error_encoding_video = true;
459  }
460  }
461 
462  // Remove front item
463  processed_frames.pop_front();
464  }
465 
466  // Loop through, and deallocate AVFrames
467  while (!deallocate_frames.empty())
468  {
469  // Get front frame (from the queue)
470  tr1::shared_ptr<Frame> frame = deallocate_frames.front();
471 
472  // Does this frame's AVFrame still exist
473  if (av_frames.count(frame))
474  {
475  // Get AVFrame
476  AVFrame *av_frame = av_frames[frame];
477 
478  // Deallocate AVPicture and AVFrame
479  free(av_frame->data[0]); // TODO: Determine why av_free crashes on Windows
480  AV_FREE_FRAME(&av_frame);
481  av_frames.erase(frame);
482  }
483 
484  // Remove front item
485  deallocate_frames.pop_front();
486  }
487 
488  // Done writing
489  is_writing = false;
490 
491  } // end omp single
492  } // end omp parallel
493 
494  // Raise exception from main thread
495  if (has_error_encoding_video)
496  throw ErrorEncodingVideo("Error while writing raw video frame", -1);
497 }
498 
499 // Write a block of frames from a reader
500 void FFmpegWriter::WriteFrame(ReaderBase* reader, long int start, long int length) throw(ErrorEncodingVideo, WriterClosed)
501 {
502  AppendDebugMethod("FFmpegWriter::WriteFrame (from Reader)", "start", start, "length", length, "", -1, "", -1, "", -1, "", -1);
503 
504  // Loop through each frame (and encoded it)
505  for (long int number = start; number <= length; number++)
506  {
507  // Get the frame
508  tr1::shared_ptr<Frame> f = reader->GetFrame(number);
509 
510  // Encode frame
511  WriteFrame(f);
512  }
513 }
514 
515 // Write the file trailer (after all frames are written)
517 {
518  // Write any remaining queued frames to video file
519  write_queued_frames();
520 
521  // Process final audio frame (if any)
522  if (info.has_audio && audio_st)
523  write_audio_packets(true);
524 
525  // Flush encoders (who sometimes hold on to frames)
526  flush_encoders();
527 
528  /* write the trailer, if any. The trailer must be written
529  * before you close the CodecContexts open when you wrote the
530  * header; otherwise write_trailer may try to use memory that
531  * was freed on av_codec_close() */
532  av_write_trailer(oc);
533 
534  // Mark as 'written'
535  write_trailer = true;
536 
537  AppendDebugMethod("FFmpegWriter::WriteTrailer", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
538 }
539 
540 // Flush encoders
541 void FFmpegWriter::flush_encoders()
542 {
543  if (info.has_audio && audio_codec && audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_codec->frame_size <= 1)
544  return;
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)
546  return;
547 
548  int error_code = 0;
549  int stop_encoding = 1;
550 
551  // FLUSH VIDEO ENCODER
552  if (info.has_video)
553  for (;;) {
554 
555  // Increment PTS (in frames and scaled to the codec's timebase)
556  write_video_count += av_rescale_q(1, (AVRational){info.fps.den, info.fps.num}, video_codec->time_base);
557 
558  AVPacket pkt;
559  av_init_packet(&pkt);
560  pkt.data = NULL;
561  pkt.size = 0;
562 
563  // Pointer for video buffer (if using old FFmpeg version)
564  uint8_t *video_outbuf = NULL;
565 
566  /* encode the image */
567  int got_packet = 0;
568  int error_code = 0;
569 
570  #if LIBAVFORMAT_VERSION_MAJOR >= 54
571  // Newer versions of FFMpeg
572  error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
573 
574  #else
575  // Older versions of FFmpeg (much sloppier)
576 
577  // Encode Picture and Write Frame
578  int video_outbuf_size = 0;
579  //video_outbuf = new uint8_t[200000];
580 
581  /* encode the image */
582  int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
583 
584  /* if zero size, it means the image was buffered */
585  if (out_size > 0) {
586  if(video_codec->coded_frame->key_frame)
587  pkt.flags |= AV_PKT_FLAG_KEY;
588  pkt.data= video_outbuf;
589  pkt.size= out_size;
590 
591  // got data back (so encode this frame)
592  got_packet = 1;
593  }
594  #endif
595 
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);
598  }
599  if (!got_packet) {
600  stop_encoding = 1;
601  break;
602  }
603 
604  // Override PTS (in frames and scaled to the codec's timebase)
605  //pkt.pts = write_video_count;
606 
607  // set the timestamp
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;
615 
616  // Write packet
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);
620  }
621 
622  // Deallocate memory (if needed)
623  if (video_outbuf)
624  delete[] video_outbuf;
625  }
626 
627  // FLUSH AUDIO ENCODER
628  if (info.has_audio)
629  for (;;) {
630 
631  // Increment PTS (in samples and scaled to the codec's timebase)
632 #if LIBAVFORMAT_VERSION_MAJOR >= 54
633  // for some reason, it requires me to multiply channels X 2
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);
635 #else
636  write_audio_count += av_rescale_q(audio_input_position / audio_codec->channels, (AVRational){1, info.sample_rate}, audio_codec->time_base);
637 #endif
638 
639  AVPacket pkt;
640  av_init_packet(&pkt);
641  pkt.data = NULL;
642  pkt.size = 0;
643  pkt.pts = pkt.dts = write_audio_count;
644 
645  /* encode the image */
646  int got_packet = 0;
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);
650  }
651  if (!got_packet) {
652  stop_encoding = 1;
653  break;
654  }
655 
656  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
657  // but it fixes lots of PTS related issues when I do this.
658  pkt.pts = pkt.dts = write_audio_count;
659 
660  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
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);
667 
668  // set stream
669  pkt.stream_index = audio_st->index;
670  pkt.flags |= AV_PKT_FLAG_KEY;
671 
672  // Write packet
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);
676  }
677 
678  // deallocate memory for packet
679  av_free_packet(&pkt);
680  }
681 
682 
683 }
684 
685 // Close the video codec
686 void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
687 {
688  avcodec_close(st->codec);
689  video_codec = NULL;
690 }
691 
692 // Close the audio codec
693 void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
694 {
695  avcodec_close(st->codec);
696  audio_codec = NULL;
697 
698  // Clear buffers
699  delete[] samples;
700  delete[] audio_outbuf;
701  delete[] audio_encoder_buffer;
702  samples = NULL;
703  audio_outbuf = NULL;
704  audio_encoder_buffer = NULL;
705 
706  // Deallocate resample buffer
707  if (avr) {
708  avresample_close(avr);
709  avresample_free(&avr);
710  avr = NULL;
711  }
712 
713  if (avr_planar) {
714  avresample_close(avr_planar);
715  avresample_free(&avr_planar);
716  avr_planar = NULL;
717  }
718 }
719 
720 // Close the writer
722 {
723  // Write trailer (if needed)
724  if (!write_trailer)
725  WriteTrailer();
726 
727  // Close each codec
728  if (video_st)
729  close_video(oc, video_st);
730  if (audio_st)
731  close_audio(oc, audio_st);
732 
733  // Deallocate image scalers
734  if (image_rescalers.size() > 0)
735  RemoveScalers();
736 
737  // Free the streams
738  for (int i = 0; i < oc->nb_streams; i++) {
739  av_freep(&oc->streams[i]->codec);
740  av_freep(&oc->streams[i]);
741  }
742 
743  if (!(fmt->flags & AVFMT_NOFILE)) {
744  /* close the output file */
745  avio_close(oc->pb);
746  }
747 
748  // Reset frame counters
749  write_video_count = 0;
750  write_audio_count = 0;
751 
752  // Free the context
753  av_freep(&oc);
754 
755  // Close writer
756  is_open = false;
757  prepare_streams = false;
758  write_header = false;
759  write_trailer = false;
760 
761  AppendDebugMethod("FFmpegWriter::Close", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
762 }
763 
764 // Add an AVFrame to the cache
765 void FFmpegWriter::add_avframe(tr1::shared_ptr<Frame> frame, AVFrame* av_frame)
766 {
767  // Add AVFrame to map (if it does not already exist)
768  if (!av_frames.count(frame))
769  {
770  // Add av_frame
771  av_frames[frame] = av_frame;
772  }
773  else
774  {
775  // Do not add, and deallocate this AVFrame
776  AV_FREE_FRAME(&av_frame);
777  }
778 }
779 
780 // Add an audio output stream
781 AVStream* FFmpegWriter::add_audio_stream()
782 {
783  AVCodecContext *c;
784  AVStream *st;
785 
786  // Find the audio codec
787  AVCodec *codec = avcodec_find_encoder_by_name(info.acodec.c_str());
788  if (codec == NULL)
789  throw InvalidCodec("A valid audio codec could not be found for this file.", path);
790 
791  // Create a new audio stream
792  st = avformat_new_stream(oc, codec);
793  if (!st)
794  throw OutOfMemory("Could not allocate memory for the audio stream.", path);
795 
796  // Set default values
797  avcodec_get_context_defaults3(st->codec, codec);
798 
799  c = st->codec;
800  c->codec_id = codec->id;
801 #if LIBAVFORMAT_VERSION_MAJOR >= 53
802  c->codec_type = AVMEDIA_TYPE_AUDIO;
803 #else
804  c->codec_type = CODEC_TYPE_AUDIO;
805 #endif
806 
807  // Set the sample parameters
808  c->bit_rate = info.audio_bit_rate;
809  c->channels = info.channels;
810 
811  // Set valid sample rate (or throw error)
812  if (codec->supported_samplerates) {
813  int i;
814  for (i = 0; codec->supported_samplerates[i] != 0; i++)
815  if (info.sample_rate == codec->supported_samplerates[i])
816  {
817  // Set the valid sample rate
818  c->sample_rate = info.sample_rate;
819  break;
820  }
821  if (codec->supported_samplerates[i] == 0)
822  throw InvalidSampleRate("An invalid sample rate was detected for this codec.", path);
823  } else
824  // Set sample rate
825  c->sample_rate = info.sample_rate;
826 
827 
828  // Set a valid number of channels (or throw error)
829  int channel_layout = info.channel_layout;
830  if (codec->channel_layouts) {
831  int i;
832  for (i = 0; codec->channel_layouts[i] != 0; i++)
833  if (channel_layout == codec->channel_layouts[i])
834  {
835  // Set valid channel layout
836  c->channel_layout = channel_layout;
837  break;
838  }
839  if (codec->channel_layouts[i] == 0)
840  throw InvalidChannels("An invalid channel layout was detected (i.e. MONO / STEREO).", path);
841  } else
842  // Set valid channel layout
843  c->channel_layout = channel_layout;
844 
845  // Choose a valid sample_fmt
846  if (codec->sample_fmts) {
847  for (int i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++)
848  {
849  // Set sample format to 1st valid format (and then exit loop)
850  c->sample_fmt = codec->sample_fmts[i];
851  break;
852  }
853  }
854  if (c->sample_fmt == AV_SAMPLE_FMT_NONE) {
855  // Default if no sample formats found
856  c->sample_fmt = AV_SAMPLE_FMT_S16;
857  }
858 
859  // some formats want stream headers to be separate
860  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
861  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
862 
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);
864 
865  return st;
866 }
867 
868 // Add a video output stream
869 AVStream* FFmpegWriter::add_video_stream()
870 {
871  AVCodecContext *c;
872  AVStream *st;
873 
874  // Find the audio codec
875  AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
876  if (codec == NULL)
877  throw InvalidCodec("A valid video codec could not be found for this file.", path);
878 
879  // Create a new stream
880  st = avformat_new_stream(oc, codec);
881  if (!st)
882  throw OutOfMemory("Could not allocate memory for the video stream.", path);
883 
884  // Set default values
885  avcodec_get_context_defaults3(st->codec, codec);
886 
887  c = st->codec;
888  c->codec_id = codec->id;
889 #if LIBAVFORMAT_VERSION_MAJOR >= 53
890  c->codec_type = AVMEDIA_TYPE_VIDEO;
891 #else
892  c->codec_type = CODEC_TYPE_VIDEO;
893 #endif
894 
895  /* Init video encoder options */
896  c->bit_rate = info.video_bit_rate;
897  c->rc_min_rate = info.video_bit_rate - (info.video_bit_rate / 6);
898  c->rc_max_rate = info.video_bit_rate;
899  c->rc_buffer_size = FFMAX(c->rc_max_rate, 15000000) * 112L / 15000000 * 16384;
900  c->qmin = 2;
901  c->qmax = 30;
902 
903  /* resolution must be a multiple of two */
904  // TODO: require /2 height and width
905  c->width = info.width;
906  c->height = info.height;
907 
908  /* time base: this is the fundamental unit of time (in seconds) in terms
909  of which frame timestamps are represented. for fixed-fps content,
910  timebase should be 1/framerate and timestamp increments should be
911  identically 1. */
912  c->time_base.num = info.video_timebase.num;
913  c->time_base.den = info.video_timebase.den;
914  c->gop_size = 12; /* TODO: add this to "info"... emit one intra frame every twelve frames at most */
915  c->max_b_frames = 10;
916  if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
917  /* just for testing, we also add B frames */
918  c->max_b_frames = 2;
919  if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
920  /* Needed to avoid using macroblocks in which some coeffs overflow.
921  This does not happen with normal video, it just happens here as
922  the motion of the chroma plane does not match the luma plane. */
923  c->mb_decision = 2;
924  // some formats want stream headers to be separate
925  if (oc->oformat->flags & AVFMT_GLOBALHEADER)
926  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
927 
928  // Find all supported pixel formats for this codec
929  const PixelFormat* supported_pixel_formats = codec->pix_fmts;
930  while (supported_pixel_formats != NULL && *supported_pixel_formats != PIX_FMT_NONE) {
931  // Assign the 1st valid pixel format (if one is missing)
932  if (c->pix_fmt == PIX_FMT_NONE)
933  c->pix_fmt = *supported_pixel_formats;
934  ++supported_pixel_formats;
935  }
936 
937  // Codec doesn't have any pix formats?
938  if (c->pix_fmt == PIX_FMT_NONE) {
939  if(fmt->video_codec == AV_CODEC_ID_RAWVIDEO) {
940  // Raw video should use RGB24
941  c->pix_fmt = PIX_FMT_RGB24;
942 
943  if (strcmp(fmt->name, "gif") != 0)
944  // If not GIF format, skip the encoding process
945  // Set raw picture flag (so we don't encode this video)
946  oc->oformat->flags |= AVFMT_RAWPICTURE;
947  } else {
948  // Set the default codec
949  c->pix_fmt = PIX_FMT_YUV420P;
950  }
951  }
952 
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);
954 
955  return st;
956 }
957 
958 // open audio codec
959 void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
960 {
961  AVCodec *codec;
962  audio_codec = st->codec;
963 
964  // Set number of threads equal to number of processors + 1
965  audio_codec->thread_count = OPEN_MP_NUM_PROCESSORS;
966 
967  // Find the audio encoder
968  codec = avcodec_find_encoder(audio_codec->codec_id);
969  if (!codec)
970  throw InvalidCodec("Could not find codec", path);
971 
972  // Open the codec
973  if (avcodec_open2(audio_codec, codec, NULL) < 0)
974  throw InvalidCodec("Could not open codec", path);
975 
976  // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer
977  // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples
978  if (audio_codec->frame_size <= 1) {
979  // No frame size found... so calculate
980  audio_input_frame_size = 50000 / info.channels;
981 
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;
988  break;
989  default:
990  break;
991  }
992  } else {
993  // Set frame size based on the codec
994  audio_input_frame_size = audio_codec->frame_size;
995  }
996 
997  // Set the initial frame size (since it might change during resampling)
998  initial_audio_input_frame_size = audio_input_frame_size;
999 
1000  // Allocate array for samples
1001  samples = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE];
1002 
1003  // Set audio output buffer (used to store the encoded audio)
1004  audio_outbuf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1005  audio_outbuf = new uint8_t[audio_outbuf_size];
1006 
1007  // Set audio packet encoding buffer
1008  audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
1009  audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
1010 
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);
1012 
1013 }
1014 
1015 // open video codec
1016 void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
1017 {
1018  AVCodec *codec;
1019  video_codec = st->codec;
1020 
1021  // Set number of threads equal to number of processors + 1
1022  video_codec->thread_count = OPEN_MP_NUM_PROCESSORS;
1023 
1024  /* find the video encoder */
1025  codec = avcodec_find_encoder(video_codec->codec_id);
1026  if (!codec)
1027  throw InvalidCodec("Could not find codec", path);
1028 
1029  /* open the codec */
1030  if (avcodec_open2(video_codec, codec, NULL) < 0)
1031  throw InvalidCodec("Could not open codec", path);
1032 
1033  AppendDebugMethod("FFmpegWriter::open_video", "video_codec->thread_count", video_codec->thread_count, "", -1, "", -1, "", -1, "", -1, "", -1);
1034 
1035 }
1036 
1037 // write all queued frames' audio to the video file
1038 void FFmpegWriter::write_audio_packets(bool final)
1039 {
1040  #pragma omp task firstprivate(final)
1041  {
1042  // Init audio buffers / variables
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;
1048  ChannelLayout channel_layout_in_frame = LAYOUT_MONO; // default channel layout
1049 
1050  // Create a new array (to hold all S16 audio samples, for the current queued frames
1051  int16_t* all_queued_samples = new int16_t[(queued_audio_frames.size() * AVCODEC_MAX_AUDIO_FRAME_SIZE)];
1052  int16_t* all_resampled_samples = NULL;
1053  int16_t* final_samples_planar = NULL;
1054  int16_t* final_samples = NULL;
1055 
1056  // Loop through each queued audio frame
1057  while (!queued_audio_frames.empty())
1058  {
1059  // Get front frame (from the queue)
1060  tr1::shared_ptr<Frame> frame = queued_audio_frames.front();
1061 
1062  // Get the audio details from this frame
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();
1067 
1068 
1069  // Get audio sample array
1070  float* frame_samples_float = NULL;
1071  // Get samples interleaved together (c1 c2 c1 c2 c1 c2)
1072  frame_samples_float = frame->GetInterleavedAudioSamples(sample_rate_in_frame, NULL, &samples_in_frame);
1073 
1074 
1075  // Calculate total samples
1076  total_frame_samples = samples_in_frame * channels_in_frame;
1077 
1078  // Translate audio sample values back to 16 bit integers
1079  for (int s = 0; s < total_frame_samples; s++, frame_position++)
1080  // Translate sample value and copy into buffer
1081  all_queued_samples[frame_position] = int(frame_samples_float[s] * (1 << 15));
1082 
1083 
1084  // Deallocate float array
1085  delete[] frame_samples_float;
1086 
1087  // Remove front item
1088  queued_audio_frames.pop_front();
1089 
1090  } // end while
1091 
1092 
1093  // Update total samples (since we've combined all queued frames)
1094  total_frame_samples = frame_position;
1095  int remaining_frame_samples = total_frame_samples;
1096  int samples_position = 0;
1097 
1098 
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);
1100 
1101  // Keep track of the original sample format
1102  AVSampleFormat output_sample_fmt = audio_codec->sample_fmt;
1103 
1104  AVFrame *audio_frame = NULL;
1105  if (!final) {
1106  // Create input frame (and allocate arrays)
1107  audio_frame = AV_ALLOCATE_FRAME();
1108  AV_RESET_FRAME(audio_frame);
1109  audio_frame->nb_samples = total_frame_samples / channels_in_frame;
1110 
1111  // Fill input frame with sample data
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);
1114 
1115  // Do not convert audio to planar format (yet). We need to keep everything interleaved at this point.
1116  switch (audio_codec->sample_fmt)
1117  {
1118  case AV_SAMPLE_FMT_FLTP:
1119  {
1120  output_sample_fmt = AV_SAMPLE_FMT_FLT;
1121  break;
1122  }
1123  case AV_SAMPLE_FMT_S32P:
1124  {
1125  output_sample_fmt = AV_SAMPLE_FMT_S32;
1126  break;
1127  }
1128  case AV_SAMPLE_FMT_S16P:
1129  {
1130  output_sample_fmt = AV_SAMPLE_FMT_S16;
1131  break;
1132  }
1133  case AV_SAMPLE_FMT_U8P:
1134  {
1135  output_sample_fmt = AV_SAMPLE_FMT_U8;
1136  break;
1137  }
1138  }
1139 
1140  // Update total samples & input frame size (due to bigger or smaller data types)
1141  total_frame_samples *= (float(info.sample_rate) / sample_rate_in_frame); // adjust for different byte sizes
1142  total_frame_samples *= (float(info.channels) / channels_in_frame); // adjust for different # of channels
1143 
1144  // Set remaining samples
1145  remaining_frame_samples = total_frame_samples;
1146 
1147  // Create output frame (and allocate arrays)
1148  AVFrame *audio_converted = AV_ALLOCATE_FRAME();
1149  AV_RESET_FRAME(audio_converted);
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);
1152 
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);
1154 
1155  // setup resample context
1156  if (!avr) {
1157  avr = avresample_alloc_context();
1158  av_opt_set_int(avr, "in_channel_layout", channel_layout_in_frame, 0);
1159  av_opt_set_int(avr, "out_channel_layout", info.channel_layout, 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); // planar not allowed here
1162  av_opt_set_int(avr, "in_sample_rate", sample_rate_in_frame, 0);
1163  av_opt_set_int(avr, "out_sample_rate", info.sample_rate, 0);
1164  av_opt_set_int(avr, "in_channels", channels_in_frame, 0);
1165  av_opt_set_int(avr, "out_channels", info.channels, 0);
1166  avresample_open(avr);
1167  }
1168  int nb_samples = 0;
1169 
1170  // Convert audio samples
1171  nb_samples = avresample_convert(avr, // audio resample context
1172  audio_converted->data, // output data pointers
1173  audio_converted->linesize[0], // output plane size, in bytes. (0 if unknown)
1174  audio_converted->nb_samples, // maximum number of samples that the output buffer can hold
1175  audio_frame->data, // input data pointers
1176  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1177  audio_frame->nb_samples); // number of input samples to convert
1178 
1179  // Create a new array (to hold all resampled S16 audio 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))];
1181 
1182  // Copy audio samples over original samples
1183  memcpy(all_resampled_samples, audio_converted->data[0], nb_samples * info.channels * av_get_bytes_per_sample(output_sample_fmt));
1184 
1185  // Remove converted audio
1186  free(audio_frame->data[0]); // TODO: Determine why av_free crashes on Windows
1187  AV_FREE_FRAME(&audio_frame);
1188  av_free(audio_converted->data[0]);
1189  AV_FREE_FRAME(&audio_converted);
1190  all_queued_samples = NULL; // this array cleared with above call
1191 
1192  AppendDebugMethod("FFmpegWriter::write_audio_packets (Successfully completed 1st resampling)", "nb_samples", nb_samples, "remaining_frame_samples", remaining_frame_samples, "", -1, "", -1, "", -1, "", -1);
1193  }
1194 
1195  // Loop until no more samples
1196  while (remaining_frame_samples > 0 || final) {
1197  // Get remaining samples needed for this packet
1198  int remaining_packet_samples = (audio_input_frame_size * info.channels) - audio_input_position;
1199 
1200  // Determine how many samples we need
1201  int diff = 0;
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;
1206 
1207  // Copy frame samples into the packet samples array
1208  if (!final)
1209  //TODO: Make this more sane
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));
1211 
1212  // Increment counters
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;
1217 
1218  // Do we have enough samples to proceed?
1219  if (audio_input_position < (audio_input_frame_size * info.channels) && !final)
1220  // Not enough samples to encode... so wait until the next frame
1221  break;
1222 
1223  // Convert to planar (if needed by audio codec)
1224  AVFrame *frame_final = AV_ALLOCATE_FRAME();
1225  AV_RESET_FRAME(frame_final);
1226  if (av_sample_fmt_is_planar(audio_codec->sample_fmt))
1227  {
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);
1229 
1230  // setup resample context
1231  if (!avr_planar) {
1232  avr_planar = avresample_alloc_context();
1233  av_opt_set_int(avr_planar, "in_channel_layout", info.channel_layout, 0);
1234  av_opt_set_int(avr_planar, "out_channel_layout", info.channel_layout, 0);
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); // planar not allowed here
1237  av_opt_set_int(avr_planar, "in_sample_rate", info.sample_rate, 0);
1238  av_opt_set_int(avr_planar, "out_sample_rate", info.sample_rate, 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);
1242  }
1243 
1244  // Create input frame (and allocate arrays)
1245  audio_frame = AV_ALLOCATE_FRAME();
1246  AV_RESET_FRAME(audio_frame);
1247  audio_frame->nb_samples = audio_input_position / info.channels;
1248 
1249  // Create a new array
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))];
1251 
1252  // Copy audio into buffer for frame
1253  memcpy(final_samples_planar, samples, audio_frame->nb_samples * info.channels * av_get_bytes_per_sample(output_sample_fmt));
1254 
1255  // Fill input frame with sample data
1256  avcodec_fill_audio_frame(audio_frame, info.channels, output_sample_fmt, (uint8_t *) final_samples_planar,
1257  audio_encoder_buffer_size, 0);
1258 
1259  // Create output frame (and allocate arrays)
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);
1262 
1263  // Convert audio samples
1264  int nb_samples = avresample_convert(avr_planar, // audio resample context
1265  frame_final->data, // output data pointers
1266  frame_final->linesize[0], // output plane size, in bytes. (0 if unknown)
1267  frame_final->nb_samples, // maximum number of samples that the output buffer can hold
1268  audio_frame->data, // input data pointers
1269  audio_frame->linesize[0], // input plane size, in bytes (0 if unknown)
1270  audio_frame->nb_samples); // number of input samples to convert
1271 
1272  // Copy audio samples over original samples
1273  if (nb_samples > 0)
1274  memcpy(samples, frame_final->data[0], nb_samples * av_get_bytes_per_sample(audio_codec->sample_fmt) * info.channels);
1275 
1276  // deallocate AVFrame
1277  free(audio_frame->data[0]); // TODO: Determine why av_free crashes on Windows
1278  AV_FREE_FRAME(&audio_frame);
1279 
1280  AppendDebugMethod("FFmpegWriter::write_audio_packets (Successfully completed 2nd resampling for Planar formats)", "nb_samples", nb_samples, "", -1, "", -1, "", -1, "", -1, "", -1);
1281 
1282  } else {
1283  // Create a new array
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))];
1285 
1286  // Copy audio into buffer for frame
1287  memcpy(final_samples, samples, audio_input_position * av_get_bytes_per_sample(audio_codec->sample_fmt));
1288 
1289  // Init the nb_samples property
1290  frame_final->nb_samples = audio_input_frame_size;
1291 
1292  // Fill the final_frame AVFrame with audio (non planar)
1293  avcodec_fill_audio_frame(frame_final, audio_codec->channels, audio_codec->sample_fmt, (uint8_t *) final_samples,
1294  audio_encoder_buffer_size, 0);
1295  }
1296 
1297  // Increment PTS (in samples)
1298  write_audio_count += FFMIN(audio_input_frame_size, audio_input_position);
1299  frame_final->pts = write_audio_count; // Set the AVFrame's PTS
1300 
1301  // Init the packet
1302  AVPacket pkt;
1303  av_init_packet(&pkt);
1304  pkt.data = audio_encoder_buffer;
1305  pkt.size = audio_encoder_buffer_size;
1306 
1307  // Set the packet's PTS prior to encoding
1308  pkt.pts = pkt.dts = write_audio_count;
1309 
1310  /* encode the audio samples */
1311  int got_packet_ptr = 0;
1312  int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
1313 
1314  /* if zero size, it means the image was buffered */
1315  if (error_code == 0 && got_packet_ptr) {
1316 
1317  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
1318  // but it fixes lots of PTS related issues when I do this.
1319  pkt.pts = pkt.dts = write_audio_count;
1320 
1321  // Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
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);
1328 
1329  // set stream
1330  pkt.stream_index = audio_st->index;
1331  pkt.flags |= AV_PKT_FLAG_KEY;
1332 
1333  /* write the compressed frame in the media file */
1334  int error_code = av_interleaved_write_frame(oc, &pkt);
1335  if (error_code < 0)
1336  {
1337  AppendDebugMethod("FFmpegWriter::write_audio_packets ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
1338  }
1339  }
1340 
1341  if (error_code < 0)
1342  {
1343  AppendDebugMethod("FFmpegWriter::write_audio_packets ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
1344  }
1345 
1346  // deallocate AVFrame
1347  //free(frame_final->data[0]); // TODO: Determine why av_free crashes on Windows
1348  AV_FREE_FRAME(&frame_final);
1349 
1350  // deallocate memory for packet
1351  av_free_packet(&pkt);
1352 
1353  // Reset position
1354  audio_input_position = 0;
1355  final = false;
1356  }
1357 
1358  // Delete arrays (if needed)
1359  if (all_resampled_samples) {
1360  delete[] all_resampled_samples;
1361  all_resampled_samples = NULL;
1362  }
1363  if (all_queued_samples) {
1364  delete[] all_queued_samples;
1365  all_queued_samples = NULL;
1366  }
1367 
1368  } // end task
1369 }
1370 
1371 // Allocate an AVFrame object
1372 AVFrame* FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int height, int *buffer_size, uint8_t *new_buffer)
1373 {
1374  // Create an RGB AVFrame
1375  AVFrame *new_av_frame = NULL;
1376 
1377  // Allocate an AVFrame structure
1378  new_av_frame = AV_ALLOCATE_FRAME();
1379  if (new_av_frame == NULL)
1380  throw OutOfMemory("Could not allocate AVFrame", path);
1381 
1382  // Determine required buffer size and allocate buffer
1383  *buffer_size = avpicture_get_size(pix_fmt, width, height);
1384 
1385  // Create buffer (if not provided)
1386  if (!new_buffer)
1387  {
1388  // New Buffer
1389  new_buffer = new uint8_t[*buffer_size];
1390  // Attach buffer to AVFrame
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;
1395  }
1396 
1397  // return AVFrame
1398  return new_av_frame;
1399 }
1400 
1401 // process video frame
1402 void FFmpegWriter::process_video_packet(tr1::shared_ptr<Frame> frame)
1403 {
1404  // Determine the height & width of the source image
1405  int source_image_width = frame->GetWidth();
1406  int source_image_height = frame->GetHeight();
1407 
1408  // Do nothing if size is 1x1 (i.e. no image in this frame)
1409  if (source_image_height == 1 && source_image_width == 1)
1410  return;
1411 
1412  // Init rescalers (if not initialized yet)
1413  if (image_rescalers.size() == 0)
1414  InitScalers(source_image_width, source_image_height);
1415 
1416  // Get a unique rescaler (for this thread)
1417  SwsContext *scaler = image_rescalers[rescaler_position];
1418  rescaler_position++;
1419  if (rescaler_position == num_of_rescalers)
1420  rescaler_position = 0;
1421 
1422  #pragma omp task firstprivate(frame, scaler, source_image_width, source_image_height)
1423  {
1424  // Allocate an RGB frame & final output frame
1425  int bytes_source = 0;
1426  int bytes_final = 0;
1427  AVFrame *frame_source = NULL;
1428  const uchar *pixels = NULL;
1429 
1430  // Get a list of pixels from source image
1431  pixels = frame->GetPixels();
1432 
1433  // Init AVFrame for source image & final (converted image)
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);
1436 
1437  // Fill with data
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);
1440 
1441  // Resize & convert pixel format
1442  sws_scale(scaler, frame_source->data, frame_source->linesize, 0,
1443  source_image_height, frame_final->data, frame_final->linesize);
1444 
1445  // Add resized AVFrame to av_frames map
1446  #pragma omp critical (av_frames_section)
1447  add_avframe(frame, frame_final);
1448 
1449  // Deallocate memory
1450  AV_FREE_FRAME(&frame_source);
1451 
1452  } // end task
1453 
1454 }
1455 
1456 // write video frame
1457 bool FFmpegWriter::write_video_packet(tr1::shared_ptr<Frame> frame, AVFrame* frame_final)
1458 {
1459  AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", oc->oformat->flags & AVFMT_RAWPICTURE, "", -1, "", -1, "", -1, "", -1);
1460 
1461  if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1462  // Raw video case.
1463  AVPacket pkt;
1464  av_init_packet(&pkt);
1465 
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);
1470 
1471  // Increment PTS (in frames and scaled to the codec's timebase)
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;
1474 
1475  /* write the compressed frame in the media file */
1476  int error_code = av_interleaved_write_frame(oc, &pkt);
1477  if (error_code < 0)
1478  {
1479  AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
1480  return false;
1481  }
1482 
1483  // Deallocate packet
1484  av_free_packet(&pkt);
1485 
1486  } else {
1487 
1488  AVPacket pkt;
1489  av_init_packet(&pkt);
1490  pkt.data = NULL;
1491  pkt.size = 0;
1492  pkt.pts = pkt.dts = AV_NOPTS_VALUE;
1493 
1494  // Pointer for video buffer (if using old FFmpeg version)
1495  uint8_t *video_outbuf = NULL;
1496 
1497  // Increment PTS (in frames and scaled to the codec's timebase)
1498  write_video_count += av_rescale_q(1, (AVRational){info.fps.den, info.fps.num}, video_codec->time_base);
1499 
1500  // Assign the initial AVFrame PTS from the frame counter
1501  frame_final->pts = write_video_count;
1502 
1503  /* encode the image */
1504  int got_packet_ptr = 0;
1505  int error_code = 0;
1506  #if LIBAVFORMAT_VERSION_MAJOR >= 54
1507  // Newer versions of FFMpeg
1508  error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
1509 
1510  #else
1511  // Older versions of FFmpeg (much sloppier)
1512 
1513  // Encode Picture and Write Frame
1514  int video_outbuf_size = 200000;
1515  video_outbuf = new uint8_t[200000];
1516 
1517  /* encode the image */
1518  int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
1519 
1520  /* if zero size, it means the image was buffered */
1521  if (out_size > 0) {
1522  if(video_codec->coded_frame->key_frame)
1523  pkt.flags |= AV_PKT_FLAG_KEY;
1524  pkt.data= video_outbuf;
1525  pkt.size= out_size;
1526 
1527  // got data back (so encode this frame)
1528  got_packet_ptr = 1;
1529  }
1530  #endif
1531 
1532  /* if zero size, it means the image was buffered */
1533  if (error_code == 0 && got_packet_ptr) {
1534 
1535  // Since the PTS can change during encoding, set the value again. This seems like a huge hack,
1536  // but it fixes lots of PTS related issues when I do this.
1537  //pkt.pts = pkt.dts = write_video_count;
1538 
1539  // set the timestamp
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;
1547 
1548  /* write the compressed frame in the media file */
1549  int error_code = av_interleaved_write_frame(oc, &pkt);
1550  if (error_code < 0)
1551  {
1552  AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
1553  return false;
1554  }
1555  }
1556 
1557  // Deallocate memory (if needed)
1558  if (video_outbuf)
1559  delete[] video_outbuf;
1560 
1561  // Deallocate packet
1562  av_free_packet(&pkt);
1563  }
1564 
1565  // Success
1566  return true;
1567 }
1568 
1569 // Output the ffmpeg info about this format, streams, and codecs (i.e. dump format)
1571 {
1572  // output debug info
1573  av_dump_format(oc, 0, path.c_str(), 1);
1574 }
1575 
1576 // Init a collection of software rescalers (thread safe)
1577 void FFmpegWriter::InitScalers(int source_width, int source_height)
1578 {
1579  // Get the codec
1580  AVCodecContext *c;
1581  c = video_st->codec;
1582 
1583  // Init software rescalers vector (many of them, one for each thread)
1584  for (int x = 0; x < num_of_rescalers; x++)
1585  {
1586  // Init the software scaler from FFMpeg
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);
1588 
1589  // Add rescaler to vector
1590  image_rescalers.push_back(img_convert_ctx);
1591  }
1592 }
1593 
1594 // Set audio resample options
1595 void FFmpegWriter::ResampleAudio(int sample_rate, int channels) {
1596  original_sample_rate = sample_rate;
1597  original_channels = channels;
1598 }
1599 
1600 // Remove & deallocate all software scalers
1602 {
1603  // Close all rescalers
1604  for (int x = 0; x < num_of_rescalers; x++)
1605  sws_freeContext(image_rescalers[x]);
1606 
1607  // Clear vector
1608  image_rescalers.clear();
1609 }
#define AV_RESET_FRAME(av_frame)
int channels
The number of audio channels used in the audio stream.
Definition: WriterBase.h:72
A video stream (used to determine which type of stream)
Definition: FFmpegWriter.h:63
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.
Definition: WriterBase.cpp:67
#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.
Definition: Fraction.h:44
WriterInfo info
Information about the current media file.
Definition: WriterBase.h:106
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)
Definition: FFmpegWriter.h:64
int video_bit_rate
The bit rate of the video stream (in bytes)
Definition: WriterBase.h:60
Exception when an invalid # of audio channels are detected.
Definition: Exceptions.h:112
#define PIX_FMT_RGB24
string acodec
The name of the audio codec used to encode / decode the video stream.
Definition: WriterBase.h:69
string vcodec
The name of the video codec used to encode / decode the video stream.
Definition: WriterBase.h:63
void Reduce()
Reduce this fraction (i.e. 640/480 = 4/3)
Definition: Fraction.cpp:71
#define AVCODEC_MAX_AUDIO_FRAME_SIZE
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:95
int width
The width of the video (in pixels)
Definition: WriterBase.h:57
int audio_bit_rate
The bit rate of the audio stream (in bytes)
Definition: WriterBase.h:70
#define OPEN_MP_NUM_PROCESSORS
Exception when encoding audio packet.
Definition: Exceptions.h:101
Exception when invalid sample rate is detected during encoding.
Definition: Exceptions.h:172
Fraction video_timebase
The video timebase determines how long each frame stays on the screen.
Definition: WriterBase.h:66
void Open()
Open writer.
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.
Definition: Exceptions.h:122
Exception when memory could not be allocated.
Definition: Exceptions.h:224
Exception when invalid encoding options are used.
Definition: Exceptions.h:162
Exception when no streams are found in the file.
Definition: Exceptions.h:192
void RemoveScalers()
Remove & deallocate all software scalers.
#define AV_ALLOCATE_FRAME()
Exception for files that can not be found or opened.
Definition: Exceptions.h:132
FFmpegWriter(string path)
Constructor for FFmpegWriter. Throws one of the following exceptions.
This class represents a fraction.
Definition: Fraction.h:42
void ResampleAudio(int sample_rate, int channels)
Set audio resample options.
#define PIX_FMT_YUV420P
ChannelLayout
This enumeration determines the audio channel layout (such as stereo, mono, 5 point surround...
#define PixelFormat
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)
Definition: WriterBase.h:71
bool has_video
Determines if this file has a video stream.
Definition: WriterBase.h:51
Fraction fps
Frames per second, as a fraction (i.e. 24/1 = 24 fps)
Definition: WriterBase.h:59
bool has_audio
Determines if this file has an audio stream.
Definition: WriterBase.h:52
#define PIX_FMT_RGBA
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.
Definition: Exceptions.h:264
ChannelLayout channel_layout
The channel layout (mono, stereo, 5 point surround, etc...)
Definition: WriterBase.h:73
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)
Definition: WriterBase.h:56
#define PIX_FMT_NONE
int den
Denominator for the fraction.
Definition: Fraction.h:45
Exception when no valid format is found for a file.
Definition: Exceptions.h:142
#define AUDIO_PACKET_ENCODING_SIZE
StreamType
This enumeration designates the type of stream when encoding (video or audio)
Definition: FFmpegWriter.h:61