commit c2d45ab56ef71c224fb59a5875b978d62f400d42
Author: Arkadiusz Miƛkiewicz <[email protected]>
Date:   Sun Apr 29 22:26:13 2018 +0200

    - up to 0.1.9 + ffmpeg hacky patch

 libopenshot-ffmpeg.patch | 1238 ++++++++++++++++++++++++++++++++++++++++++++++
 libopenshot.spec         |   10 +-
 2 files changed, 1244 insertions(+), 4 deletions(-)
---
diff --git a/libopenshot.spec b/libopenshot.spec
index 7ae7c5f..58ff063 100644
--- a/libopenshot.spec
+++ b/libopenshot.spec
@@ -1,12 +1,13 @@
 Summary:       Library for creating and editing videos
 Name:          libopenshot
-Version:       0.1.8
-Release:       3
+Version:       0.1.9
+Release:       1
 License:       LGPL-3.0+
 Group:         Libraries
 Source0:       
https://github.com/OpenShot/libopenshot/archive/v%{version}.tar.gz
-# Source0-md5: 70930d0c973dac2ab5468175224f142b
+# Source0-md5: 74012e7260c91c3413b45401c46bfcc0
 Patch0:                imagemagick7.patch
+Patch1:                %{name}-ffmpeg.patch
 Group:         Development/Libraries
 URL:           http://www.openshot.org/
 BuildRequires: ImageMagick-c++-devel
@@ -55,6 +56,7 @@ that use %{name}.
 %prep
 %setup -q
 %patch0 -p1
+%patch1 -p1
 
 sed -i -e 's#${_REL_PYTHON_MODULE_PATH}#%{py3_sitedir}#g' 
src/bindings/python/CMakeLists.txt
 
@@ -80,7 +82,7 @@ rm -rf $RPM_BUILD_ROOT
 %files
 %defattr(644,root,root,755)
 %attr(755,root,root) %{_libdir}/libopenshot.so.*.*
-%attr(755,root,root) %ghost %{_libdir}/libopenshot.so.13
+%attr(755,root,root) %ghost %{_libdir}/libopenshot.so.14
 
 %files devel
 %defattr(644,root,root,755)
diff --git a/libopenshot-ffmpeg.patch b/libopenshot-ffmpeg.patch
new file mode 100644
index 0000000..82569fb
--- /dev/null
+++ b/libopenshot-ffmpeg.patch
@@ -0,0 +1,1238 @@
+From 774eb365b3f663b1f53dd24c1650fafb3c445ea6 Mon Sep 17 00:00:00 2001
+From: Jonathan Thomas <[email protected]>
+Date: Wed, 21 Mar 2018 02:10:46 -0500
+Subject: [PATCH] FFMPEG 3.2 support for FFmpegReader (writer support coming
+ soon)
+
+---
+ include/FFmpegReader.h       |   7 +-
+ include/FFmpegUtilities.h    |  49 ++++++++++-
+ src/FFmpegReader.cpp         | 195 +++++++++++++++++++++++++++++--------------
+ tests/FFmpegReader_Tests.cpp |   4 +-
+ 4 files changed, 183 insertions(+), 72 deletions(-)
+
+diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h
+index beed9bc..6072756 100644
+--- a/include/FFmpegReader.h
++++ b/include/FFmpegReader.h
+@@ -99,7 +99,7 @@ namespace openshot
+               AVCodecContext *pCodecCtx, *aCodecCtx;
+               AVStream *pStream, *aStream;
+               AVPacket *packet;
+-              AVPicture *pFrame;
++              AVFrame *pFrame;
+               bool is_open;
+               bool is_duration_known;
+               bool check_interlace;
+@@ -154,9 +154,6 @@ namespace openshot
+               /// Check the working queue, and move finished frames to the 
finished queue
+               void CheckWorkingFrames(bool end_of_stream, int64_t 
requested_frame);
+ 
+-              /// Convert image to RGB format
+-              void convert_image(int64_t current_frame, AVPicture *copyFrame, 
int width, int height, PixelFormat pix_fmt);
+-
+               /// Convert Frame Number into Audio PTS
+               int64_t ConvertFrameToAudioPTS(int64_t frame_number);
+ 
+@@ -200,7 +197,7 @@ namespace openshot
+               std::shared_ptr<Frame> ReadStream(int64_t requested_frame);
+ 
+               /// Remove AVFrame from cache (and deallocate it's memory)
+-              void RemoveAVFrame(AVPicture*);
++              void RemoveAVFrame(AVFrame*);
+ 
+               /// Remove AVPacket from cache (and deallocate it's memory)
+               void RemoveAVPacket(AVPacket*);
+diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
+index 103aceb..b38132f 100644
+--- a/include/FFmpegUtilities.h
++++ b/include/FFmpegUtilities.h
+@@ -34,6 +34,10 @@
+       #define UINT64_C(c) (c ## ULL)
+       #endif
+ 
++      #ifndef IS_FFMPEG_3_2
++      #define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 
101))
++      #endif
++
+       // Include the FFmpeg headers
+       extern "C" {
+               #include <libavcodec/avcodec.h>
+@@ -55,6 +59,10 @@
+               #if LIBAVFORMAT_VERSION_MAJOR >= 54
+                       #include <libavutil/channel_layout.h>
+               #endif
++
++              #if IS_FFMPEG_3_2
++                      #include "libavutil/imgutils.h"
++              #endif
+       }
+ 
+       // This was removed from newer versions of FFmpeg (but still used in 
libopenshot)
+@@ -98,16 +106,55 @@
+               #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
+       #endif
+ 
+-      #if LIBAVFORMAT_VERSION_MAJOR >= 55
++      #if IS_FFMPEG_3_2
++              #define AV_ALLOCATE_FRAME() av_frame_alloc()
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1);
++              #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
++      #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
++              #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
++              #define AV_FREE_CONTEXT(av_context) 
avcodec_free_context(&av_context);
++              #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codecpar->codec_type
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codecpar->codec_id;
++              auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* 
av_codec) { \
++                      AVCodecContext *context = 
avcodec_alloc_context3(av_codec); \
++                      avcodec_parameters_to_context(context, 
av_stream->codecpar); \
++                      return context; \
++              };
++              #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_stream->codecpar
++              #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
(AVPixelFormat) av_stream->codecpar->format
++              #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_stream->codecpar->format
++              #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
av_image_get_buffer_size(pix_fmt, width, height, 1)
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, 
pix_fmt, width, height, 1);
++      #elif LIBAVFORMAT_VERSION_MAJOR >= 55
+               #define AV_ALLOCATE_FRAME() av_frame_alloc()
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
+               #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
+       #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
+               #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
++              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
++              #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codec->codec_type
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id;
++              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec;
++              #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_context
++              #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
av_context->pix_fmt
++              #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_context->sample_fmt
++              #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
avpicture_get_size(pix_fmt, width, height)
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
+       #else
+               #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
+               #define AV_RESET_FRAME(av_frame) 
avcodec_get_frame_defaults(av_frame)
+               #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
+               #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
++              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
++              #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codec->codec_type
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id;
++              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec;
++              #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_context
++              #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
av_context->pix_fmt
++              #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_context->sample_fmt
++              #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
avpicture_get_size(pix_fmt, width, height)
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
+       #endif
+ 
+ 
+diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp
+index f803c86..57dffc2 100644
+--- a/src/FFmpegReader.cpp
++++ b/src/FFmpegReader.cpp
+@@ -123,11 +123,11 @@ void FFmpegReader::Open()
+               for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
+               {
+                       // Is this a video stream?
+-                      if (pFormatCtx->streams[i]->codec->codec_type == 
AVMEDIA_TYPE_VIDEO && videoStream < 0) {
++                      if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == 
AVMEDIA_TYPE_VIDEO && videoStream < 0) {
+                               videoStream = i;
+                       }
+                       // Is this an audio stream?
+-                      if (pFormatCtx->streams[i]->codec->codec_type == 
AVMEDIA_TYPE_AUDIO && audioStream < 0) {
++                      if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == 
AVMEDIA_TYPE_AUDIO && audioStream < 0) {
+                               audioStream = i;
+                       }
+               }
+@@ -142,13 +142,17 @@ void FFmpegReader::Open()
+ 
+                       // Set the codec and codec context pointers
+                       pStream = pFormatCtx->streams[videoStream];
+-                      pCodecCtx = pFormatCtx->streams[videoStream]->codec;
++
++                      // Find the codec ID from stream
++                      AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(pStream);
++
++                      // Get codec and codec context from stream
++                      AVCodec *pCodec = avcodec_find_decoder(codecId);
++                      pCodecCtx = AV_GET_CODEC_CONTEXT(pStream, pCodec);
+ 
+                       // Set number of threads equal to number of processors 
(not to exceed 16)
+                       pCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 
16);
+ 
+-                      // Find the decoder for the video stream
+-                      AVCodec *pCodec = 
avcodec_find_decoder(pCodecCtx->codec_id);
+                       if (pCodec == NULL) {
+                               throw InvalidCodec("A valid video codec could 
not be found for this file.", path);
+                       }
+@@ -168,13 +172,17 @@ void FFmpegReader::Open()
+ 
+                       // Get a pointer to the codec context for the audio 
stream
+                       aStream = pFormatCtx->streams[audioStream];
+-                      aCodecCtx = pFormatCtx->streams[audioStream]->codec;
++
++                      // Find the codec ID from stream
++                      AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(aStream);
++
++                      // Get codec and codec context from stream
++                      AVCodec *aCodec = avcodec_find_decoder(codecId);
++                      aCodecCtx = AV_GET_CODEC_CONTEXT(aStream, aCodec);
+ 
+                       // Set number of threads equal to number of processors 
(not to exceed 16)
+                       aCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 
16);
+ 
+-                      // Find the decoder for the audio stream
+-                      AVCodec *aCodec = 
avcodec_find_decoder(aCodecCtx->codec_id);
+                       if (aCodec == NULL) {
+                               throw InvalidCodec("A valid audio codec could 
not be found for this file.", path);
+                       }
+@@ -222,12 +230,12 @@ void FFmpegReader::Close()
+               if (info.has_video)
+               {
+                       avcodec_flush_buffers(pCodecCtx);
+-                      avcodec_close(pCodecCtx);
++                      AV_FREE_CONTEXT(pCodecCtx);
+               }
+               if (info.has_audio)
+               {
+                       avcodec_flush_buffers(aCodecCtx);
+-                      avcodec_close(aCodecCtx);
++                      AV_FREE_CONTEXT(aCodecCtx);
+               }
+ 
+               // Clear final cache
+@@ -269,12 +277,12 @@ void FFmpegReader::UpdateAudioInfo()
+       info.has_audio = true;
+       info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
+       info.acodec = aCodecCtx->codec->name;
+-      info.channels = aCodecCtx->channels;
+-      if (aCodecCtx->channel_layout == 0)
+-              aCodecCtx->channel_layout = av_get_default_channel_layout( 
aCodecCtx->channels );
+-      info.channel_layout = (ChannelLayout) aCodecCtx->channel_layout;
+-      info.sample_rate = aCodecCtx->sample_rate;
+-      info.audio_bit_rate = aCodecCtx->bit_rate;
++      info.channels = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
++      if (AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout == 0)
++              AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout = 
av_get_default_channel_layout( AV_GET_CODEC_ATTRIBUTES(aStream, 
aCodecCtx)->channels );
++      info.channel_layout = (ChannelLayout) AV_GET_CODEC_ATTRIBUTES(aStream, 
aCodecCtx)->channel_layout;
++      info.sample_rate = AV_GET_CODEC_ATTRIBUTES(aStream, 
aCodecCtx)->sample_rate;
++      info.audio_bit_rate = AV_GET_CODEC_ATTRIBUTES(aStream, 
aCodecCtx)->bit_rate;
+ 
+       // Set audio timebase
+       info.audio_timebase.num = aStream->time_base.num;
+@@ -318,8 +326,8 @@ void FFmpegReader::UpdateVideoInfo()
+       // Set values of FileInfo struct
+       info.has_video = true;
+       info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
+-      info.height = pCodecCtx->height;
+-      info.width = pCodecCtx->width;
++      info.height = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->height;
++      info.width = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->width;
+       info.vcodec = pCodecCtx->codec->name;
+       info.video_bit_rate = pFormatCtx->bit_rate;
+       if (!check_fps)
+@@ -334,18 +342,17 @@ void FFmpegReader::UpdateVideoInfo()
+               info.pixel_ratio.num = pStream->sample_aspect_ratio.num;
+               info.pixel_ratio.den = pStream->sample_aspect_ratio.den;
+       }
+-      else if (pCodecCtx->sample_aspect_ratio.num != 0)
++      else if (AV_GET_CODEC_ATTRIBUTES(pStream, 
pCodecCtx)->sample_aspect_ratio.num != 0)
+       {
+-              info.pixel_ratio.num = pCodecCtx->sample_aspect_ratio.num;
+-              info.pixel_ratio.den = pCodecCtx->sample_aspect_ratio.den;
++              info.pixel_ratio.num = AV_GET_CODEC_ATTRIBUTES(pStream, 
pCodecCtx)->sample_aspect_ratio.num;
++              info.pixel_ratio.den = AV_GET_CODEC_ATTRIBUTES(pStream, 
pCodecCtx)->sample_aspect_ratio.den;
+       }
+       else
+       {
+               info.pixel_ratio.num = 1;
+               info.pixel_ratio.den = 1;
+       }
+-
+-      info.pixel_format = pCodecCtx->pix_fmt;
++      info.pixel_format = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
+ 
+       // Calculate the DAR (display aspect ratio)
+       Fraction size(info.width * info.pixel_ratio.num, info.height * 
info.pixel_ratio.den);
+@@ -697,28 +704,60 @@ int FFmpegReader::GetNextPacket()
+ bool FFmpegReader::GetAVFrame()
+ {
+       int frameFinished = -1;
++      int ret = 0;
+ 
+       // Decode video frame
+       AVFrame *next_frame = AV_ALLOCATE_FRAME();
+       #pragma omp critical (packet_cache)
+-      avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
+-
+-      // is frame finished
+-      if (frameFinished)
+       {
+-              // AVFrames are clobbered on the each call to 
avcodec_decode_video, so we
+-              // must make a copy of the image data before this method is 
called again.
+-              pFrame = new AVPicture();
+-              avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, 
info.height);
+-              av_picture_copy(pFrame, (AVPicture *) next_frame, 
pCodecCtx->pix_fmt, info.width, info.height);
+-
+-              // Detect interlaced frame (only once)
+-              if (!check_interlace)
+-              {
+-                      check_interlace = true;
+-                      info.interlaced_frame = next_frame->interlaced_frame;
+-                      info.top_field_first = next_frame->top_field_first;
++      #if IS_FFMPEG_3_2
++              frameFinished = 0;
++              ret = avcodec_send_packet(pCodecCtx, packet);
++              if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
++                      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not 
sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
++              }
++              else {
++                      pFrame = new AVFrame();
++                      while (ret >= 0) {
++                              ret =  avcodec_receive_frame(pCodecCtx, 
next_frame);
++                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
++                break;
++                              }
++                              // TODO also handle possible further frames
++                              // Use only the first frame like 
avcodec_decode_video2
++                              if (frameFinished == 0 ) {
++                                      frameFinished = 1;
++                                      av_image_alloc(pFrame->data, 
pFrame->linesize, info.width, info.height, 
(AVPixelFormat)(pStream->codecpar->format), 1);
++                                      av_image_copy(pFrame->data, 
pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize,
++                                                                              
                (AVPixelFormat)(pStream->codecpar->format), info.width, 
info.height);
++                                      if (!check_interlace)   {
++                                              check_interlace = true;
++                                              info.interlaced_frame = 
next_frame->interlaced_frame;
++                                              info.top_field_first = 
next_frame->top_field_first;
++                                      }
++                              }
++                      }
++              }
++      #else
++              avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, 
packet);
++
++              // is frame finished
++              if (frameFinished) {
++                      // AVFrames are clobbered on the each call to 
avcodec_decode_video, so we
++                      // must make a copy of the image data before this 
method is called again.
++                      pFrame = AV_ALLOCATE_FRAME();
++                      avpicture_alloc((AVPicture *) pFrame, 
pCodecCtx->pix_fmt, info.width, info.height);
++                      av_picture_copy((AVPicture *) pFrame, (AVPicture *) 
next_frame, pCodecCtx->pix_fmt, info.width,
++                                                      info.height);
++
++                      // Detect interlaced frame (only once)
++                      if (!check_interlace) {
++                              check_interlace = true;
++                              info.interlaced_frame = 
next_frame->interlaced_frame;
++                              info.top_field_first = 
next_frame->top_field_first;
++                      }
+               }
++      #endif
+       }
+ 
+       // deallocate the frame
+@@ -800,11 +839,11 @@ void FFmpegReader::ProcessVideoPacket(int64_t 
requested_frame)
+       
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessVideoPacket 
(Before)", "requested_frame", requested_frame, "current_frame", current_frame, 
"", -1, "", -1, "", -1, "", -1);
+ 
+       // Init some things local (for OpenMP)
+-      PixelFormat pix_fmt = pCodecCtx->pix_fmt;
++      PixelFormat pix_fmt = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
+       int height = info.height;
+       int width = info.width;
+       int64_t video_length = info.video_length;
+-    AVPicture *my_frame = pFrame;
++      AVFrame *my_frame = pFrame;
+ 
+       // Add video frame to list of processing video frames
+       const GenericScopedLock<CriticalSection> 
lock(processingCriticalSection);
+@@ -844,17 +883,16 @@ void FFmpegReader::ProcessVideoPacket(int64_t 
requested_frame)
+               }
+ 
+               // Determine required buffer size and allocate buffer
+-              numBytes = avpicture_get_size(PIX_FMT_RGBA, width, height);
++              numBytes = AV_GET_IMAGE_SIZE(PIX_FMT_RGBA, width, height);
++
+               #pragma omp critical (video_buffer)
+               buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
+ 
+-              // Assign appropriate parts of buffer to image planes in 
pFrameRGB
+-              // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
+-              // of AVPicture
+-              avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGBA, 
width, height);
++              // Copy picture data from one AVFrame (or AVPicture) to another 
one.
++              AV_COPY_PICTURE_DATA(pFrameRGB, buffer, PIX_FMT_RGBA, width, 
height);
+ 
+-              SwsContext *img_convert_ctx = sws_getContext(info.width, 
info.height, pCodecCtx->pix_fmt, width,
+-                                                                              
                          height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
++              SwsContext *img_convert_ctx = sws_getContext(info.width, 
info.height, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), width,
++                                                                              
                                          height, PIX_FMT_RGBA, SWS_BILINEAR, 
NULL, NULL, NULL);
+ 
+               // Resize / Convert to RGB
+               sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 
0,
+@@ -925,20 +963,52 @@ void FFmpegReader::ProcessAudioPacket(int64_t 
requested_frame, int64_t target_fr
+ 
+       // re-initialize buffer size (it gets changed in the 
avcodec_decode_audio2 method call)
+       int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE;
+-      int used = avcodec_decode_audio4(aCodecCtx, audio_frame, 
&frame_finished, packet);
++      #pragma omp critical (ProcessAudioPacket)
++      {
++      #if IS_FFMPEG_3_2
++              int ret = 0;
++              frame_finished = 1;
++              while((packet->size > 0 || (!packet->data && frame_finished)) 
&& ret >= 0) {
++                      frame_finished = 0;
++                      ret =  avcodec_send_packet(aCodecCtx, packet);
++                      if (ret < 0 && ret !=  AVERROR(EINVAL) && ret != 
AVERROR_EOF) {
++                              avcodec_send_packet(aCodecCtx, NULL);
++                              break;
++                      }
++                      if (ret >= 0)
++                              packet->size = 0;
++                      ret =  avcodec_receive_frame(aCodecCtx, audio_frame);
++                      if (ret >= 0)
++                              frame_finished = 1;
++                      if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
++                              avcodec_flush_buffers(aCodecCtx);
++                              ret = 0;
++                      }
++                      if (ret >= 0) {
++                              ret = frame_finished;
++                      }
++              }
++              if (!packet->data && !frame_finished)
++              {
++                      ret = -1;
++              }
++      #else
++              int used = avcodec_decode_audio4(aCodecCtx, audio_frame, 
&frame_finished, packet);
++#endif
++      }
+ 
+       if (frame_finished) {
+ 
+               // determine how many samples were decoded
+-              int planar = av_sample_fmt_is_planar(aCodecCtx->sample_fmt);
++              int planar = 
av_sample_fmt_is_planar((AVSampleFormat)AV_GET_CODEC_PIXEL_FORMAT(aStream, 
aCodecCtx));
+               int plane_size = -1;
+               data_size = av_samples_get_buffer_size(&plane_size,
+-                              aCodecCtx->channels,
++                              AV_GET_CODEC_ATTRIBUTES(aStream, 
aCodecCtx)->channels,
+                               audio_frame->nb_samples,
+-                              aCodecCtx->sample_fmt, 1);
++                              (AVSampleFormat)(AV_GET_SAMPLE_FORMAT(aStream, 
aCodecCtx)), 1);
+ 
+               // Calculate total number of samples
+-              packet_samples = audio_frame->nb_samples * aCodecCtx->channels;
++              packet_samples = audio_frame->nb_samples * 
AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
+       }
+ 
+       // Estimate the # of samples and the end of this packet's location (to 
prevent GAPS for the next timestamp)
+@@ -999,7 +1069,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t 
requested_frame, int64_t target_fr
+       // Allocate audio buffer
+       int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE];
+ 
+-      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket 
(ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, 
"info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", 
aCodecCtx->sample_fmt, "AV_SAMPLE_FMT_S16", AV_SAMPLE_FMT_S16, "", -1);
++      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket 
(ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, 
"info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", 
AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), "AV_SAMPLE_FMT_S16", 
AV_SAMPLE_FMT_S16, "", -1);
+ 
+       // Create output frame
+       AVFrame *audio_converted = AV_ALLOCATE_FRAME();
+@@ -1012,9 +1082,9 @@ void FFmpegReader::ProcessAudioPacket(int64_t 
requested_frame, int64_t target_fr
+ 
+       // setup resample context
+       avr = avresample_alloc_context();
+-      av_opt_set_int(avr,  "in_channel_layout", aCodecCtx->channel_layout, 0);
+-      av_opt_set_int(avr, "out_channel_layout", aCodecCtx->channel_layout, 0);
+-      av_opt_set_int(avr,  "in_sample_fmt",     aCodecCtx->sample_fmt,     0);
++      av_opt_set_int(avr,  "in_channel_layout", 
AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
++      av_opt_set_int(avr, "out_channel_layout", 
AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
++      av_opt_set_int(avr,  "in_sample_fmt",     AV_GET_SAMPLE_FORMAT(aStream, 
aCodecCtx), 0);
+       av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_S16,     0);
+       av_opt_set_int(avr,  "in_sample_rate",    info.sample_rate,    0);
+       av_opt_set_int(avr, "out_sample_rate",    info.sample_rate,    0);
+@@ -1767,7 +1837,7 @@ void FFmpegReader::CheckWorkingFrames(bool 
end_of_stream, int64_t requested_fram
+ void FFmpegReader::CheckFPS()
+ {
+       check_fps = true;
+-      avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, info.height);
++      AV_ALLOCATE_IMAGE(pFrame, AV_GET_CODEC_PIXEL_FORMAT(pStream, 
pCodecCtx), info.width, info.height);
+ 
+       int first_second_counter = 0;
+       int second_second_counter = 0;
+@@ -1878,17 +1948,14 @@ void FFmpegReader::CheckFPS()
+ }
+ 
+ // Remove AVFrame from cache (and deallocate it's memory)
+-void FFmpegReader::RemoveAVFrame(AVPicture* remove_frame)
++void FFmpegReader::RemoveAVFrame(AVFrame* remove_frame)
+ {
+     // Remove pFrame (if exists)
+     if (remove_frame)
+     {
+         // Free memory
+-        avpicture_free(remove_frame);
+-
+-        // Delete the object
+-        delete remove_frame;
+-    }
++              av_freep(&remove_frame->data[0]);
++      }
+ }
+ 
+ // Remove AVPacket from cache (and deallocate it's memory)
+diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp
+index 54017e8..82e8573 100644
+--- a/tests/FFmpegReader_Tests.cpp
++++ b/tests/FFmpegReader_Tests.cpp
+@@ -72,8 +72,8 @@ TEST(FFmpegReader_Check_Audio_File)
+       CHECK_CLOSE(0.0f, samples[50], 0.00001);
+       CHECK_CLOSE(0.0f, samples[100], 0.00001);
+       CHECK_CLOSE(0.0f, samples[200], 0.00001);
+-      CHECK_CLOSE(0.160781, samples[230], 0.00001);
+-      CHECK_CLOSE(-0.06125f, samples[300], 0.00001);
++      CHECK_CLOSE(0.164062f, samples[230], 0.00001);
++      CHECK_CLOSE(-0.0625f, samples[300], 0.00001);
+ 
+       // Close reader
+       r.Close();
+From 22384c770501b9d737501847400f571f67edf385 Mon Sep 17 00:00:00 2001
+From: Jonathan Thomas <[email protected]>
+Date: Wed, 28 Mar 2018 15:09:55 -0500
+Subject: [PATCH] FFMPEG 3.2 support for FFmpegWriter (Thanks Peter!)
+
+---
+ include/FFmpegUtilities.h |  62 +++++++++---
+ src/FFmpegWriter.cpp      | 252 +++++++++++++++++++++++++++++-----------------
+ 2 files changed, 210 insertions(+), 104 deletions(-)
+
+diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
+index b38132f..578c658 100644
+--- a/include/FFmpegUtilities.h
++++ b/include/FFmpegUtilities.h
+@@ -108,53 +108,87 @@
+ 
+       #if IS_FFMPEG_3_2
+               #define AV_ALLOCATE_FRAME() av_frame_alloc()
+-              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1);
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
+               #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
+       #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
+               #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
+-              #define AV_FREE_CONTEXT(av_context) 
avcodec_free_context(&av_context);
++              #define AV_FREE_CONTEXT(av_context) 
avcodec_free_context(&av_context)
+               #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codecpar->codec_type
+-              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codecpar->codec_id;
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codecpar->codec_id
+               auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* 
av_codec) { \
+                       AVCodecContext *context = 
avcodec_alloc_context3(av_codec); \
+                       avcodec_parameters_to_context(context, 
av_stream->codecpar); \
+                       return context; \
+               };
++              #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
++              #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
+               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_stream->codecpar
+               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
(AVPixelFormat) av_stream->codecpar->format
+               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_stream->codecpar->format
+               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
av_image_get_buffer_size(pix_fmt, width, height, 1)
+-              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, 
pix_fmt, width, height, 1);
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, 
pix_fmt, width, height, 1)
++              #define AV_OUTPUT_CONTEXT(output_context, path) 
avformat_alloc_output_context2( output_context, NULL, NULL, path)
++              #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, 
name, NULL, 0, 0)
++              #define AV_OPTION_SET( av_stream, priv_data, name, value, 
avcodec)      av_opt_set(priv_data, name, value, 0); 
avcodec_parameters_from_context(av_stream->codecpar, avcodec);
++              #define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st)     
av_st = avformat_new_stream(oc, NULL);\
++                      if (!av_st) \
++                              throw OutOfMemory("Could not allocate memory 
for the video stream.", path); \
++                      c = avcodec_alloc_context3(av_codec); \
++                      st_codec = c; \
++                      av_st->codecpar->codec_id = av_codec->id;
++              #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) 
avcodec_parameters_from_context(av_stream->codecpar, av_codec);
+       #elif LIBAVFORMAT_VERSION_MAJOR >= 55
+               #define AV_ALLOCATE_FRAME() av_frame_alloc()
+-              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
+               #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
+       #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
+               #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
+-              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
++              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
+               #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codec->codec_type
+-              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id;
+-              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec;
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id
++              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec
++              #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) 
av_stream->codec
++              #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in) codec_in 
= av_stream->codec;
+               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_context
+               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
av_context->pix_fmt
+               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_context->sample_fmt
+               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
avpicture_get_size(pix_fmt, width, height)
+-              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
++              #define AV_OUTPUT_CONTEXT(output_context, path) oc = 
avformat_alloc_context()
++              #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, 
name, NULL, 0, 0)
++              #define AV_OPTION_SET(av_stream, priv_data, name, value, 
avcodec) av_opt_set (priv_data, name, value, 0)
++              #define AV_FORMAT_NEW_STREAM( oc,  av_context,  av_codec, 
av_st) av_st = avformat_new_stream(oc, av_codec); \
++                      if (!av_st) \
++                              throw OutOfMemory("Could not allocate memory 
for the video stream.", path); \
++                      avcodec_get_context_defaults3(av_st->codec, av_codec); \
++                      c = av_st->codec;
++              #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
+       #else
+               #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
+-              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
++              #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) 
avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
+               #define AV_RESET_FRAME(av_frame) 
avcodec_get_frame_defaults(av_frame)
+               #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
+               #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
+-              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
++              #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
+               #define AV_GET_CODEC_TYPE(av_stream) 
av_stream->codec->codec_type
+-              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id;
+-              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec;
++              #define AV_FIND_DECODER_CODEC_ID(av_stream) 
av_stream->codec->codec_id
++              #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) 
av_stream->codec
++              #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) 
av_stream->codec
++              #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in ) codec_in 
= av_stream->codec;
+               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) 
av_context
+               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) 
av_context->pix_fmt
+               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) 
av_context->sample_fmt
+               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) 
avpicture_get_size(pix_fmt, width, height)
+-              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
++              #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, 
height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
++              #define AV_OUTPUT_CONTEXT(output_context, path) oc = 
avformat_alloc_context()
++              #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, 
name, NULL, 0, 0)
++              #define AV_OPTION_SET(av_stream, priv_data, name, value, 
avcodec) av_opt_set (priv_data, name, value, 0)
++              #define AV_FORMAT_NEW_STREAM( oc,  av_context,  av_codec, 
av_st) av_st = avformat_new_stream(oc, av_codec); \
++                      if (!av_st) \
++                              throw OutOfMemory("Could not allocate memory 
for the video stream.", path); \
++                      avcodec_get_context_defaults3(av_st->codec, av_codec); \
++                      c = av_st->codec;
++              #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
+       #endif
+ 
+ 
+diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp
+index e83e478..889e262 100644
+--- a/src/FFmpegWriter.cpp
++++ b/src/FFmpegWriter.cpp
+@@ -76,7 +76,7 @@ void FFmpegWriter::auto_detect_format()
+               throw InvalidFormat("Could not deduce output format from file 
extension.", path);
+ 
+       // Allocate the output media context
+-      oc = avformat_alloc_context();
++      AV_OUTPUT_CONTEXT(&oc, path.c_str());
+       if (!oc)
+               throw OutOfMemory("Could not allocate memory for 
AVFormatContext.", path);
+ 
+@@ -211,12 +211,19 @@ void FFmpegWriter::SetOption(StreamType stream, string 
name, string value)
+ {
+       // Declare codec context
+       AVCodecContext *c = NULL;
++      AVStream *st = NULL;
+       stringstream convert(value);
+ 
+-      if (info.has_video && stream == VIDEO_STREAM && video_st)
+-              c = video_st->codec;
+-      else if (info.has_audio && stream == AUDIO_STREAM && audio_st)
+-              c = audio_st->codec;
++      if (info.has_video && stream == VIDEO_STREAM && video_st) {
++              st = video_st;
++              // Get codec context
++              c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec);
++      }
++      else if (info.has_audio && stream == AUDIO_STREAM && audio_st) {
++              st = audio_st;
++              // Get codec context
++              c = AV_GET_CODEC_PAR_CONTEXT(st, audio_codec);
++      }
+       else
+               throw NoStreamsFound("The stream was not found. Be sure to call 
PrepareStreams() first.", path);
+ 
+@@ -226,11 +233,7 @@ void FFmpegWriter::SetOption(StreamType stream, string 
name, string value)
+       // Was a codec / stream found?
+       if (c)
+               // Find AVOption (if it exists)
+-              #if LIBAVFORMAT_VERSION_MAJOR <= 53
+-                      option = av_find_opt(c->priv_data, name.c_str(), NULL, 
NULL, NULL);
+-              #else
+-                      option = av_opt_find(c->priv_data, name.c_str(), NULL, 
0, 0);
+-              #endif
++              option = AV_OPTION_FIND(c->priv_data, name.c_str());
+ 
+       // Was option found?
+       if (option || (name == "g" || name == "qmin" || name == "qmax" || name 
== "max_b_frames" || name == "mb_decision" ||
+@@ -283,11 +286,7 @@ void FFmpegWriter::SetOption(StreamType stream, string 
name, string value)
+ 
+               else
+                       // Set AVOption
+-                      #if LIBAVFORMAT_VERSION_MAJOR <= 53
+-                              av_set_string3 (c->priv_data, name.c_str(), 
value.c_str(), 0, NULL);
+-                      #else
+-                              av_opt_set (c->priv_data, name.c_str(), 
value.c_str(), 0);
+-                      #endif
++                      AV_OPTION_SET(st, c->priv_data, name.c_str(), 
value.c_str(), c);
+ 
+               
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::SetOption (" + 
(string)name + ")", "stream == VIDEO_STREAM", stream == VIDEO_STREAM, "", -1, 
"", -1, "", -1, "", -1, "", -1);
+ 
+@@ -334,7 +333,9 @@ void FFmpegWriter::WriteHeader()
+ 
+       // Write the stream header, if any
+       // TODO: add avoptions / parameters instead of NULL
+-      avformat_write_header(oc, NULL);
++      if (avformat_write_header(oc, NULL) != 0) {
++          throw InvalidFile("Could not write header to file.", path);
++      }
+ 
+       // Mark as 'written'
+       write_header = true;
+@@ -548,10 +549,10 @@ void FFmpegWriter::WriteTrailer()
+ // Flush encoders
+ void FFmpegWriter::flush_encoders()
+ {
+-    if (info.has_audio && audio_codec && audio_st->codec->codec_type == 
AVMEDIA_TYPE_AUDIO && audio_codec->frame_size <= 1)
+-        return;
+-    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)
+-        return;
++      if (info.has_audio && audio_codec && AV_GET_CODEC_TYPE(audio_st) == 
AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, 
audio_codec)->frame_size <= 1)
++              return;
++      if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == 
AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && 
AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO)
++              return;
+ 
+     int error_code = 0;
+     int stop_encoding = 1;
+@@ -575,29 +576,37 @@ void FFmpegWriter::flush_encoders()
+                       int got_packet = 0;
+                       int error_code = 0;
+ 
+-                      #if LIBAVFORMAT_VERSION_MAJOR >= 54
+-                              // Newer versions of FFMpeg
+-                      error_code = avcodec_encode_video2(video_codec, &pkt, 
NULL, &got_packet);
+-
++                      #if IS_FFMPEG_3_2
++                      #pragma omp critical (write_video_packet)
++                      {
++                              // Encode video packet (latest version of 
FFmpeg)
++                              error_code = avcodec_send_frame(video_codec, 
NULL);
++                              got_packet = 0;
++                      }
+                       #else
+-                              // Older versions of FFmpeg (much sloppier)
+ 
+-                              // Encode Picture and Write Frame
+-                              int video_outbuf_size = 0;
++                              #if LIBAVFORMAT_VERSION_MAJOR >= 54
++                              // Encode video packet (older than FFmpeg 3.2)
++                              error_code = avcodec_encode_video2(video_codec, 
&pkt, NULL, &got_packet);
+ 
+-                              /* encode the image */
+-                              int out_size = 
avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
++                              #else
++                                      // Encode video packet (even older 
version of FFmpeg)
++                                      int video_outbuf_size = 0;
+ 
+-                              /* if zero size, it means the image was 
buffered */
+-                              if (out_size > 0) {
+-                                      if(video_codec->coded_frame->key_frame)
+-                                              pkt.flags |= AV_PKT_FLAG_KEY;
+-                                      pkt.data= video_outbuf;
+-                                      pkt.size= out_size;
++                                      /* encode the image */
++                                      int out_size = 
avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
+ 
+-                                      // got data back (so encode this frame)
+-                                      got_packet = 1;
+-                              }
++                                      /* if zero size, it means the image was 
buffered */
++                                      if (out_size > 0) {
++                                              
if(video_codec->coded_frame->key_frame)
++                                                      pkt.flags |= 
AV_PKT_FLAG_KEY;
++                                              pkt.data= video_outbuf;
++                                              pkt.size= out_size;
++
++                                              // got data back (so encode 
this frame)
++                                              got_packet = 1;
++                                      }
++                              #endif
+                       #endif
+ 
+                       if (error_code < 0) {
+@@ -651,7 +660,12 @@ void FFmpegWriter::flush_encoders()
+ 
+                       /* encode the image */
+                       int got_packet = 0;
++                      #if IS_FFMPEG_3_2
++                      avcodec_send_frame(audio_codec, NULL);
++                      got_packet = 0;
++                      #else
+                       error_code = avcodec_encode_audio2(audio_codec, &pkt, 
NULL, &got_packet);
++                      #endif
+                       if (error_code < 0) {
+                               
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" 
+ (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", 
-1, "", -1, "", -1, "", -1);
+                       }
+@@ -692,14 +706,14 @@ void FFmpegWriter::flush_encoders()
+ // Close the video codec
+ void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
+ {
+-      avcodec_close(st->codec);
++      AV_FREE_CONTEXT(video_codec);
+       video_codec = NULL;
+ }
+ 
+ // Close the audio codec
+ void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
+ {
+-      avcodec_close(st->codec);
++      AV_FREE_CONTEXT(audio_codec);
+       audio_codec = NULL;
+ 
+       // Clear buffers
+@@ -743,7 +757,7 @@ void FFmpegWriter::Close()
+ 
+       // Free the streams
+       for (int i = 0; i < oc->nb_streams; i++) {
+-              av_freep(&oc->streams[i]->codec);
++              av_freep(AV_GET_CODEC_ATTRIBUTES(&oc->streams[i], 
&oc->streams[i]));
+               av_freep(&oc->streams[i]);
+       }
+ 
+@@ -796,14 +810,8 @@ AVStream* FFmpegWriter::add_audio_stream()
+               throw InvalidCodec("A valid audio codec could not be found for 
this file.", path);
+ 
+       // Create a new audio stream
+-      st = avformat_new_stream(oc, codec);
+-      if (!st)
+-              throw OutOfMemory("Could not allocate memory for the audio 
stream.", path);
++      AV_FORMAT_NEW_STREAM(oc, audio_codec, codec, st)
+ 
+-      // Set default values
+-    avcodec_get_context_defaults3(st->codec, codec);
+-
+-      c = st->codec;
+       c->codec_id = codec->id;
+ #if LIBAVFORMAT_VERSION_MAJOR >= 53
+       c->codec_type = AVMEDIA_TYPE_AUDIO;
+@@ -867,6 +875,7 @@ AVStream* FFmpegWriter::add_audio_stream()
+       if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+               c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+ 
++      AV_COPY_PARAMS_FROM_CONTEXT(st, c);
+       
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_audio_stream", 
"c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->channels", 
c->channels, "c->sample_fmt", c->sample_fmt, "c->channel_layout", 
c->channel_layout, "c->sample_rate", c->sample_rate);
+ 
+       return st;
+@@ -878,20 +887,14 @@ AVStream* FFmpegWriter::add_video_stream()
+       AVCodecContext *c;
+       AVStream *st;
+ 
+-      // Find the audio codec
++      // Find the video codec
+       AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
+       if (codec == NULL)
+               throw InvalidCodec("A valid video codec could not be found for 
this file.", path);
+ 
+-      // Create a new stream
+-      st = avformat_new_stream(oc, codec);
+-      if (!st)
+-              throw OutOfMemory("Could not allocate memory for the video 
stream.", path);
++      // Create a new video stream
++      AV_FORMAT_NEW_STREAM(oc, video_codec, codec, st)
+ 
+-      // Set default values
+-    avcodec_get_context_defaults3(st->codec, codec);
+-
+-      c = st->codec;
+       c->codec_id = codec->id;
+ #if LIBAVFORMAT_VERSION_MAJOR >= 53
+       c->codec_type = AVMEDIA_TYPE_VIDEO;
+@@ -923,6 +926,10 @@ AVStream* FFmpegWriter::add_video_stream()
+        identically 1. */
+       c->time_base.num = info.video_timebase.num;
+       c->time_base.den = info.video_timebase.den;
++      #if LIBAVFORMAT_VERSION_MAJOR >= 55
++      c->framerate = av_inv_q(c->time_base);
++      #endif
++      st->avg_frame_rate = av_inv_q(c->time_base);
+       st->time_base.num = info.video_timebase.num;
+       st->time_base.den = info.video_timebase.den;
+ 
+@@ -965,6 +972,7 @@ AVStream* FFmpegWriter::add_video_stream()
+         }
+     }
+ 
++      AV_COPY_PARAMS_FROM_CONTEXT(st, c);
+       
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_video_stream (" + 
(string)fmt->name + " : " + (string)av_get_pix_fmt_name(c->pix_fmt) + ")", 
"c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->pix_fmt", 
c->pix_fmt, "oc->oformat->flags", oc->oformat->flags, "AVFMT_RAWPICTURE", 
AVFMT_RAWPICTURE, "", -1);
+ 
+       return st;
+@@ -974,7 +982,7 @@ AVStream* FFmpegWriter::add_video_stream()
+ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
+ {
+       AVCodec *codec;
+-      audio_codec = st->codec;
++      AV_GET_CODEC_FROM_STREAM(st, audio_codec)
+ 
+       // Set number of threads equal to number of processors (not to exceed 
16)
+       audio_codec->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
+@@ -989,6 +997,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, 
AVStream *st)
+       // Open the codec
+       if (avcodec_open2(audio_codec, codec, NULL) < 0)
+               throw InvalidCodec("Could not open codec", path);
++      AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec);
+ 
+       // Calculate the size of the input frame (i..e how many samples per 
packet), and the output buffer
+       // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM 
support to compute the input frame size in samples
+@@ -996,7 +1005,8 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, 
AVStream *st)
+               // No frame size found... so calculate
+               audio_input_frame_size = 50000 / info.channels;
+ 
+-              switch (st->codec->codec_id) {
++              int s = AV_FIND_DECODER_CODEC_ID(st);
++              switch (s) {
+               case AV_CODEC_ID_PCM_S16LE:
+               case AV_CODEC_ID_PCM_S16BE:
+               case AV_CODEC_ID_PCM_U16LE:
+@@ -1039,7 +1049,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, 
AVStream *st)
+ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
+ {
+       AVCodec *codec;
+-      video_codec = st->codec;
++      AV_GET_CODEC_FROM_STREAM(st, video_codec)
+ 
+       // Set number of threads equal to number of processors (not to exceed 
16)
+       video_codec->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
+@@ -1047,7 +1057,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, 
AVStream *st)
+       /* find the video encoder */
+       codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
+       if (!codec)
+-              codec = avcodec_find_encoder(video_codec->codec_id);
++              codec = avcodec_find_encoder(AV_FIND_DECODER_CODEC_ID(st));
+       if (!codec)
+               throw InvalidCodec("Could not find codec", path);
+ 
+@@ -1058,6 +1068,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, 
AVStream *st)
+       /* open the codec */
+       if (avcodec_open2(video_codec, codec, NULL) < 0)
+               throw InvalidCodec("Could not open codec", path);
++      AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec);
+ 
+       // Add video metadata (if any)
+       for(std::map<string, string>::iterator iter = info.metadata.begin(); 
iter != info.metadata.end(); ++iter)
+@@ -1345,8 +1356,39 @@ void FFmpegWriter::write_audio_packets(bool final)
+ 
+                       /* encode the audio samples */
+                       int got_packet_ptr = 0;
+-                      int error_code = avcodec_encode_audio2(audio_codec, 
&pkt, frame_final, &got_packet_ptr);
+ 
++                      #if IS_FFMPEG_3_2
++                      // Encode audio (latest version of FFmpeg)
++                      int error_code;
++                      int ret = 0;
++                      int frame_finished = 0;
++                      error_code = ret =  avcodec_send_frame(audio_codec, 
frame_final);
++                      if (ret < 0 && ret !=  AVERROR(EINVAL) && ret != 
AVERROR_EOF) {
++                              avcodec_send_frame(audio_codec, NULL);
++                      }
++                      else {
++                              if (ret >= 0)
++                                      pkt.size = 0;
++                              ret =  avcodec_receive_packet(audio_codec, 
&pkt);
++                              if (ret >= 0)
++                                      frame_finished = 1;
++                              if(ret == AVERROR(EINVAL) || ret == 
AVERROR_EOF) {
++                                      avcodec_flush_buffers(audio_codec);
++                                      ret = 0;
++                              }
++                              if (ret >= 0) {
++                                      ret = frame_finished;
++                              }
++                      }
++                      if (!pkt.data && !frame_finished)
++                      {
++                              ret = -1;
++                      }
++                      got_packet_ptr = ret;
++                      #else
++                      // Encode audio (older versions of FFmpeg)
++                      int error_code = avcodec_encode_audio2(audio_codec, 
&pkt, frame_final, &got_packet_ptr);
++                      #endif
+                       /* if zero size, it means the image was buffered */
+                       if (error_code == 0 && got_packet_ptr) {
+ 
+@@ -1416,7 +1458,7 @@ AVFrame* FFmpegWriter::allocate_avframe(PixelFormat 
pix_fmt, int width, int heig
+               throw OutOfMemory("Could not allocate AVFrame", path);
+ 
+       // Determine required buffer size and allocate buffer
+-      *buffer_size = avpicture_get_size(pix_fmt, width, height);
++      *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
+ 
+       // Create buffer (if not provided)
+       if (!new_buffer)
+@@ -1424,7 +1466,7 @@ AVFrame* FFmpegWriter::allocate_avframe(PixelFormat 
pix_fmt, int width, int heig
+               // New Buffer
+               new_buffer = (uint8_t*)av_malloc(*buffer_size * 
sizeof(uint8_t));
+               // Attach buffer to AVFrame
+-              avpicture_fill((AVPicture *)new_av_frame, new_buffer, pix_fmt, 
width, height);
++              AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, 
height);
+               new_av_frame->width = width;
+               new_av_frame->height = height;
+               new_av_frame->format = pix_fmt;
+@@ -1468,10 +1510,14 @@ void 
FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame)
+ 
+               // Init AVFrame for source image & final (converted image)
+               frame_source = allocate_avframe(PIX_FMT_RGBA, 
source_image_width, source_image_height, &bytes_source, (uint8_t*) pixels);
++              #if IS_FFMPEG_3_2
++              AVFrame *frame_final = 
allocate_avframe((AVPixelFormat)(video_st->codecpar->format), info.width, 
info.height, &bytes_final, NULL);
++              #else
+               AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt, 
info.width, info.height, &bytes_final, NULL);
++              #endif
+ 
+               // Fill with data
+-              avpicture_fill((AVPicture *) frame_source, (uint8_t*)pixels, 
PIX_FMT_RGBA, source_image_width, source_image_height);
++        AV_COPY_PICTURE_DATA(frame_source, (uint8_t*)pixels, PIX_FMT_RGBA, 
source_image_width, source_image_height);
+               
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::process_video_packet", 
"frame->number", frame->number, "bytes_source", bytes_source, "bytes_final", 
bytes_final, "", -1, "", -1, "", -1);
+ 
+               // Resize & convert pixel format
+@@ -1539,30 +1585,60 @@ bool 
FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame* fra
+               /* encode the image */
+               int got_packet_ptr = 0;
+               int error_code = 0;
+-              #if LIBAVFORMAT_VERSION_MAJOR >= 54
+-                      // Newer versions of FFMpeg
+-                      error_code = avcodec_encode_video2(video_codec, &pkt, 
frame_final, &got_packet_ptr);
+-
++              #if IS_FFMPEG_3_2
++              // Write video packet (latest version of FFmpeg)
++              int frameFinished = 0;
++              int ret = avcodec_send_frame(video_codec, frame_final);
++              error_code = ret;
++              if (ret < 0 ) {
++                      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet 
(Frame not sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
++                      if (ret == AVERROR(EAGAIN) )
++                              cerr << "Frame EAGAIN" << "\n";
++                      if (ret == AVERROR_EOF )
++                              cerr << "Frame AVERROR_EOF" << "\n";
++                      avcodec_send_frame(video_codec, NULL);
++              }
++              else {
++                      while (ret >= 0) {
++                              ret = avcodec_receive_packet(video_codec, &pkt);
++              if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
++                                      avcodec_flush_buffers(video_codec);
++                                      got_packet_ptr = 0;
++              break;
++                              }
++                              if (ret == 0) {
++                                      got_packet_ptr = 1;
++                                      break;
++                              }
++                      }
++              }
+               #else
+-                      // Older versions of FFmpeg (much sloppier)
++                      #if LIBAVFORMAT_VERSION_MAJOR >= 54
++                              // Write video packet (older than FFmpeg 3.2)
++                              error_code = avcodec_encode_video2(video_codec, 
&pkt, frame_final, &got_packet_ptr);
++                              if (error_code != 0 )
++                                      cerr << "Frame AVERROR_EOF" << "\n";
++                              if (got_packet_ptr == 0 )
++                                      cerr << "Frame gotpacket error" << "\n";
++                      #else
++                              // Write video packet (even older versions of 
FFmpeg)
++                              int video_outbuf_size = 200000;
++                              video_outbuf = (uint8_t*) av_malloc(200000);
+ 
+-                      // Encode Picture and Write Frame
+-                      int video_outbuf_size = 200000;
+-                      video_outbuf = (uint8_t*) av_malloc(200000);
++                              /* encode the image */
++                              int out_size = 
avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
+ 
+-                      /* encode the image */
+-                      int out_size = avcodec_encode_video(video_codec, 
video_outbuf, video_outbuf_size, frame_final);
++                              /* if zero size, it means the image was 
buffered */
++                              if (out_size > 0) {
++                                      if(video_codec->coded_frame->key_frame)
++                                              pkt.flags |= AV_PKT_FLAG_KEY;
++                                      pkt.data= video_outbuf;
++                                      pkt.size= out_size;
+ 
+-                      /* if zero size, it means the image was buffered */
+-                      if (out_size > 0) {
+-                              if(video_codec->coded_frame->key_frame)
+-                                      pkt.flags |= AV_PKT_FLAG_KEY;
+-                              pkt.data= video_outbuf;
+-                              pkt.size= out_size;
+-
+-                              // got data back (so encode this frame)
+-                              got_packet_ptr = 1;
+-                      }
++                                      // got data back (so encode this frame)
++                                      got_packet_ptr = 1;
++                              }
++                      #endif
+               #endif
+ 
+               /* if zero size, it means the image was buffered */
+@@ -1612,15 +1688,11 @@ void FFmpegWriter::OutputStreamInfo()
+ // Init a collection of software rescalers (thread safe)
+ void FFmpegWriter::InitScalers(int source_width, int source_height)
+ {
+-      // Get the codec
+-      AVCodecContext *c;
+-      c = video_st->codec;
+-
+       // Init software rescalers vector (many of them, one for each thread)
+       for (int x = 0; x < num_of_rescalers; x++)
+       {
+               // Init the software scaler from FFMpeg
+-              img_convert_ctx = sws_getContext(source_width, source_height, 
PIX_FMT_RGBA, info.width, info.height, c->pix_fmt, SWS_BILINEAR, NULL, NULL, 
NULL);
++              img_convert_ctx = sws_getContext(source_width, source_height, 
PIX_FMT_RGBA, info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, 
video_st->codec), SWS_BILINEAR, NULL, NULL, NULL);
+ 
+               // Add rescaler to vector
+               image_rescalers.push_back(img_convert_ctx);
+From 0db54c8a2c1becc6c0f56807e178c5ba93cda3c5 Mon Sep 17 00:00:00 2001
+From: Jonathan Thomas <[email protected]>
+Date: Thu, 29 Mar 2018 01:29:10 -0500
+Subject: [PATCH] Fixing FFmpeg version breakage in FFmpegWriter
+
+---
+ src/FFmpegWriter.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp
+index 889e262..5f50b85 100644
+--- a/src/FFmpegWriter.cpp
++++ b/src/FFmpegWriter.cpp
+@@ -926,7 +926,7 @@ AVStream* FFmpegWriter::add_video_stream()
+        identically 1. */
+       c->time_base.num = info.video_timebase.num;
+       c->time_base.den = info.video_timebase.den;
+-      #if LIBAVFORMAT_VERSION_MAJOR >= 55
++      #if LIBAVFORMAT_VERSION_MAJOR >= 56
+       c->framerate = av_inv_q(c->time_base);
+       #endif
+       st->avg_frame_rate = av_inv_q(c->time_base);
+--- a/src/FFmpegReader.cpp~    2018-04-29 21:29:04.000000000 +0200
++++ b/src/FFmpegReader.cpp     2018-04-29 21:30:32.336155455 +0200
+@@ -941,7 +941,7 @@ void FFmpegReader::ProcessAudioPacket(in
+       int data_size = 0;
+ 
+       // re-initialize buffer size (it gets changed in the 
avcodec_decode_audio2 method call)
+-      int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE;
++      int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + 
AV_INPUT_BUFFER_PADDING_SIZE;
+       #pragma omp critical (ProcessAudioPacket)
+       {
+       #if IS_FFMPEG_3_2
+@@ -1046,7 +1046,7 @@ void FFmpegReader::ProcessAudioPacket(in
+ 
+ 
+       // Allocate audio buffer
+-      int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE];
++      int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + 
AV_INPUT_BUFFER_PADDING_SIZE];
+ 
+       
ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket 
(ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, 
"info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", 
AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), "AV_SAMPLE_FMT_S16", 
AV_SAMPLE_FMT_S16, "", -1);
+ 
+--- libopenshot-0.1.9/src/FFmpegWriter.cpp~    2018-04-29 22:11:22.000000000 
+0200
++++ libopenshot-0.1.9/src/FFmpegWriter.cpp     2018-04-29 22:13:25.133795468 
+0200
+@@ -868,7 +868,7 @@ AVStream* FFmpegWriter::add_audio_stream
+ 
+       // some formats want stream headers to be separate
+       if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+-              c->flags |= CODEC_FLAG_GLOBAL_HEADER;
++              c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+ 
+       AV_COPY_PARAMS_FROM_CONTEXT(st, c);
+       
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_audio_stream", 
"c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->channels", 
c->channels, "c->sample_fmt", c->sample_fmt, "c->channel_layout", 
c->channel_layout, "c->sample_rate", c->sample_rate);
+@@ -940,7 +940,7 @@ AVStream* FFmpegWriter::add_video_stream
+               c->mb_decision = 2;
+       // some formats want stream headers to be separate
+       if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+-              c->flags |= CODEC_FLAG_GLOBAL_HEADER;
++              c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+ 
+       // Find all supported pixel formats for this codec
+     const PixelFormat* supported_pixel_formats = codec->pix_fmts;
+--- libopenshot-0.1.9/src/FFmpegWriter.cpp~    2018-04-29 22:18:37.000000000 
+0200
++++ libopenshot-0.1.9/src/FFmpegWriter.cpp     2018-04-29 22:20:24.006338376 
+0200
+@@ -544,8 +544,6 @@ void FFmpegWriter::flush_encoders()
+ {
+       if (info.has_audio && audio_codec && AV_GET_CODEC_TYPE(audio_st) == 
AVMEDIA_TYPE_AUDIO && AV_GET_CODEC_ATTRIBUTES(audio_st, 
audio_codec)->frame_size <= 1)
+               return;
+-      if (info.has_video && video_codec && AV_GET_CODEC_TYPE(video_st) == 
AVMEDIA_TYPE_VIDEO && (oc->oformat->flags & AVFMT_RAWPICTURE) && 
AV_FIND_DECODER_CODEC_ID(video_st) == AV_CODEC_ID_RAWVIDEO)
+-              return;
+ 
+     int error_code = 0;
+     int stop_encoding = 1;
+@@ -955,10 +953,6 @@ AVStream* FFmpegWriter::add_video_stream
+             // Raw video should use RGB24
+               c->pix_fmt = PIX_FMT_RGB24;
+ 
+-        if (strcmp(fmt->name, "gif") != 0)
+-                      // If not GIF format, skip the encoding process
+-                      // Set raw picture flag (so we don't encode this video)
+-                      oc->oformat->flags |= AVFMT_RAWPICTURE;
+         } else {
+               // Set the default codec
+               c->pix_fmt = PIX_FMT_YUV420P;
+@@ -966,7 +960,7 @@ AVStream* FFmpegWriter::add_video_stream
+     }
+ 
+       AV_COPY_PARAMS_FROM_CONTEXT(st, c);
+-      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_video_stream (" + 
(string)fmt->name + " : " + (string)av_get_pix_fmt_name(c->pix_fmt) + ")", 
"c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->pix_fmt", 
c->pix_fmt, "oc->oformat->flags", oc->oformat->flags, "AVFMT_RAWPICTURE", 
AVFMT_RAWPICTURE, "", -1);
++      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::add_video_stream (" + 
(string)fmt->name + " : " + (string)av_get_pix_fmt_name(c->pix_fmt) + ")", 
"c->codec_id", c->codec_id, "c->bit_rate", c->bit_rate, "c->pix_fmt", 
c->pix_fmt, "oc->oformat->flags", oc->oformat->flags, "", -1, "", -1);
+ 
+       return st;
+ }
+@@ -1519,34 +1513,7 @@ void FFmpegWriter::process_video_packet(
+ // write video frame
+ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame* 
frame_final)
+ {
+-      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", 
"frame->number", frame->number, "oc->oformat->flags & AVFMT_RAWPICTURE", 
oc->oformat->flags & AVFMT_RAWPICTURE, "", -1, "", -1, "", -1, "", -1);
+-
+-      if (oc->oformat->flags & AVFMT_RAWPICTURE) {
+-              // Raw video case.
+-              AVPacket pkt;
+-              av_init_packet(&pkt);
+-
+-              pkt.flags |= AV_PKT_FLAG_KEY;
+-              pkt.stream_index= video_st->index;
+-              pkt.data= (uint8_t*)frame_final->data;
+-              pkt.size= sizeof(AVPicture);
+-
+-              // Increment PTS (in frames and scaled to the codec's timebase)
+-              write_video_count += av_rescale_q(1, (AVRational){info.fps.den, 
info.fps.num}, video_codec->time_base);
+-              pkt.pts = write_video_count;
+-
+-              /* write the compressed frame in the media file */
+-              int error_code = av_interleaved_write_frame(oc, &pkt);
+-              if (error_code < 0)
+-              {
+-                      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet 
ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", 
-1, "", -1, "", -1, "", -1, "", -1);
+-                      return false;
+-              }
+-
+-              // Deallocate packet
+-              AV_FREE_PACKET(&pkt);
+-
+-      } else {
++      
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", 
"frame->number", frame->number, "", -1, "", -1, "", -1, "", -1, "", -1);
+ 
+               AVPacket pkt;
+               av_init_packet(&pkt);
+@@ -1653,7 +1620,6 @@ bool FFmpegWriter::write_video_packet(st
+ 
+               // Deallocate packet
+               AV_FREE_PACKET(&pkt);
+-      }
+ 
+       // Success
+       return true;
+
+--- libopenshot-0.1.9/src/FFmpegWriter.cpp~    2018-04-29 22:20:42.000000000 
+0200
++++ libopenshot-0.1.9/src/FFmpegWriter.cpp     2018-04-29 22:22:06.796083026 
+0200
+@@ -1022,7 +1022,7 @@ void FFmpegWriter::open_audio(AVFormatCo
+       audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
+       audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
+ 
+-      ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_audio", 
"audio_codec->thread_count", audio_codec->thread_count, 
"audio_input_frame_size", audio_input_frame_size, "buffer_size", 
AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE, "", -1, "", -1, 
"", -1);
++      ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::open_audio", 
"audio_codec->thread_count", audio_codec->thread_count, 
"audio_input_frame_size", audio_input_frame_size, "buffer_size", 
AVCODEC_MAX_AUDIO_FRAME_SIZE + AV_INPUT_BUFFER_PADDING_SIZE, "", -1, "", -1, 
"", -1);
+ 
+ }
+ 
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/libopenshot.git/commitdiff/c2d45ab56ef71c224fb59a5875b978d62f400d42

_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to