]> git.pld-linux.org Git - packages/libopenshot.git/blob - libopenshot-ffmpeg.patch
- release 3 (by relup.sh)
[packages/libopenshot.git] / libopenshot-ffmpeg.patch
1 From 774eb365b3f663b1f53dd24c1650fafb3c445ea6 Mon Sep 17 00:00:00 2001
2 From: Jonathan Thomas <jonathan@openshot.org>
3 Date: Wed, 21 Mar 2018 02:10:46 -0500
4 Subject: [PATCH] FFMPEG 3.2 support for FFmpegReader (writer support coming
5  soon)
6
7 ---
8  include/FFmpegReader.h       |   7 +-
9  include/FFmpegUtilities.h    |  49 ++++++++++-
10  src/FFmpegReader.cpp         | 195 +++++++++++++++++++++++++++++--------------
11  tests/FFmpegReader_Tests.cpp |   4 +-
12  4 files changed, 183 insertions(+), 72 deletions(-)
13
14 diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h
15 index beed9bc..6072756 100644
16 --- a/include/FFmpegReader.h
17 +++ b/include/FFmpegReader.h
18 @@ -99,7 +99,7 @@ namespace openshot
19                 AVCodecContext *pCodecCtx, *aCodecCtx;
20                 AVStream *pStream, *aStream;
21                 AVPacket *packet;
22 -               AVPicture *pFrame;
23 +               AVFrame *pFrame;
24                 bool is_open;
25                 bool is_duration_known;
26                 bool check_interlace;
27 @@ -154,9 +154,6 @@ namespace openshot
28                 /// Check the working queue, and move finished frames to the finished queue
29                 void CheckWorkingFrames(bool end_of_stream, int64_t requested_frame);
30  
31 -               /// Convert image to RGB format
32 -               void convert_image(int64_t current_frame, AVPicture *copyFrame, int width, int height, PixelFormat pix_fmt);
33 -
34                 /// Convert Frame Number into Audio PTS
35                 int64_t ConvertFrameToAudioPTS(int64_t frame_number);
36  
37 @@ -200,7 +197,7 @@ namespace openshot
38                 std::shared_ptr<Frame> ReadStream(int64_t requested_frame);
39  
40                 /// Remove AVFrame from cache (and deallocate it's memory)
41 -               void RemoveAVFrame(AVPicture*);
42 +               void RemoveAVFrame(AVFrame*);
43  
44                 /// Remove AVPacket from cache (and deallocate it's memory)
45                 void RemoveAVPacket(AVPacket*);
46 diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
47 index 103aceb..b38132f 100644
48 --- a/include/FFmpegUtilities.h
49 +++ b/include/FFmpegUtilities.h
50 @@ -34,6 +34,10 @@
51         #define UINT64_C(c) (c ## ULL)
52         #endif
53  
54 +       #ifndef IS_FFMPEG_3_2
55 +       #define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101))
56 +       #endif
57 +
58         // Include the FFmpeg headers
59         extern "C" {
60                 #include <libavcodec/avcodec.h>
61 @@ -55,6 +59,10 @@
62                 #if LIBAVFORMAT_VERSION_MAJOR >= 54
63                         #include <libavutil/channel_layout.h>
64                 #endif
65 +
66 +               #if IS_FFMPEG_3_2
67 +                       #include "libavutil/imgutils.h"
68 +               #endif
69         }
70  
71         // This was removed from newer versions of FFmpeg (but still used in libopenshot)
72 @@ -98,16 +106,55 @@
73                 #define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
74         #endif
75  
76 -       #if LIBAVFORMAT_VERSION_MAJOR >= 55
77 +       #if IS_FFMPEG_3_2
78 +               #define AV_ALLOCATE_FRAME() av_frame_alloc()
79 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1);
80 +               #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
81 +       #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
82 +               #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
83 +               #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context);
84 +               #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
85 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id;
86 +               auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* av_codec) { \
87 +                       AVCodecContext *context = avcodec_alloc_context3(av_codec); \
88 +                       avcodec_parameters_to_context(context, av_stream->codecpar); \
89 +                       return context; \
90 +               };
91 +               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
92 +               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
93 +               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
94 +               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
95 +               #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);
96 +       #elif LIBAVFORMAT_VERSION_MAJOR >= 55
97                 #define AV_ALLOCATE_FRAME() av_frame_alloc()
98 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
99                 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
100         #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
101                 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
102 +               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
103 +               #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
104 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
105 +               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
106 +               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
107 +               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
108 +               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
109 +               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
110 +               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
111         #else
112                 #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
113 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
114                 #define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
115                 #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
116                 #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
117 +               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
118 +               #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
119 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
120 +               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
121 +               #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
122 +               #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
123 +               #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
124 +               #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
125 +               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
126         #endif
127  
128  
129 diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp
130 index f803c86..57dffc2 100644
131 --- a/src/FFmpegReader.cpp
132 +++ b/src/FFmpegReader.cpp
133 @@ -123,11 +123,11 @@ void FFmpegReader::Open()
134                 for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
135                 {
136                         // Is this a video stream?
137 -                       if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
138 +                       if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
139                                 videoStream = i;
140                         }
141                         // Is this an audio stream?
142 -                       if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audioStream < 0) {
143 +                       if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == AVMEDIA_TYPE_AUDIO && audioStream < 0) {
144                                 audioStream = i;
145                         }
146                 }
147 @@ -142,13 +142,17 @@ void FFmpegReader::Open()
148  
149                         // Set the codec and codec context pointers
150                         pStream = pFormatCtx->streams[videoStream];
151 -                       pCodecCtx = pFormatCtx->streams[videoStream]->codec;
152 +
153 +                       // Find the codec ID from stream
154 +                       AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(pStream);
155 +
156 +                       // Get codec and codec context from stream
157 +                       AVCodec *pCodec = avcodec_find_decoder(codecId);
158 +                       pCodecCtx = AV_GET_CODEC_CONTEXT(pStream, pCodec);
159  
160                         // Set number of threads equal to number of processors (not to exceed 16)
161                         pCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
162  
163 -                       // Find the decoder for the video stream
164 -                       AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
165                         if (pCodec == NULL) {
166                                 throw InvalidCodec("A valid video codec could not be found for this file.", path);
167                         }
168 @@ -168,13 +172,17 @@ void FFmpegReader::Open()
169  
170                         // Get a pointer to the codec context for the audio stream
171                         aStream = pFormatCtx->streams[audioStream];
172 -                       aCodecCtx = pFormatCtx->streams[audioStream]->codec;
173 +
174 +                       // Find the codec ID from stream
175 +                       AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(aStream);
176 +
177 +                       // Get codec and codec context from stream
178 +                       AVCodec *aCodec = avcodec_find_decoder(codecId);
179 +                       aCodecCtx = AV_GET_CODEC_CONTEXT(aStream, aCodec);
180  
181                         // Set number of threads equal to number of processors (not to exceed 16)
182                         aCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
183  
184 -                       // Find the decoder for the audio stream
185 -                       AVCodec *aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
186                         if (aCodec == NULL) {
187                                 throw InvalidCodec("A valid audio codec could not be found for this file.", path);
188                         }
189 @@ -222,12 +230,12 @@ void FFmpegReader::Close()
190                 if (info.has_video)
191                 {
192                         avcodec_flush_buffers(pCodecCtx);
193 -                       avcodec_close(pCodecCtx);
194 +                       AV_FREE_CONTEXT(pCodecCtx);
195                 }
196                 if (info.has_audio)
197                 {
198                         avcodec_flush_buffers(aCodecCtx);
199 -                       avcodec_close(aCodecCtx);
200 +                       AV_FREE_CONTEXT(aCodecCtx);
201                 }
202  
203                 // Clear final cache
204 @@ -269,12 +277,12 @@ void FFmpegReader::UpdateAudioInfo()
205         info.has_audio = true;
206         info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
207         info.acodec = aCodecCtx->codec->name;
208 -       info.channels = aCodecCtx->channels;
209 -       if (aCodecCtx->channel_layout == 0)
210 -               aCodecCtx->channel_layout = av_get_default_channel_layout( aCodecCtx->channels );
211 -       info.channel_layout = (ChannelLayout) aCodecCtx->channel_layout;
212 -       info.sample_rate = aCodecCtx->sample_rate;
213 -       info.audio_bit_rate = aCodecCtx->bit_rate;
214 +       info.channels = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
215 +       if (AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout == 0)
216 +               AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout = av_get_default_channel_layout( AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels );
217 +       info.channel_layout = (ChannelLayout) AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout;
218 +       info.sample_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->sample_rate;
219 +       info.audio_bit_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->bit_rate;
220  
221         // Set audio timebase
222         info.audio_timebase.num = aStream->time_base.num;
223 @@ -318,8 +326,8 @@ void FFmpegReader::UpdateVideoInfo()
224         // Set values of FileInfo struct
225         info.has_video = true;
226         info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
227 -       info.height = pCodecCtx->height;
228 -       info.width = pCodecCtx->width;
229 +       info.height = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->height;
230 +       info.width = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->width;
231         info.vcodec = pCodecCtx->codec->name;
232         info.video_bit_rate = pFormatCtx->bit_rate;
233         if (!check_fps)
234 @@ -334,18 +342,17 @@ void FFmpegReader::UpdateVideoInfo()
235                 info.pixel_ratio.num = pStream->sample_aspect_ratio.num;
236                 info.pixel_ratio.den = pStream->sample_aspect_ratio.den;
237         }
238 -       else if (pCodecCtx->sample_aspect_ratio.num != 0)
239 +       else if (AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num != 0)
240         {
241 -               info.pixel_ratio.num = pCodecCtx->sample_aspect_ratio.num;
242 -               info.pixel_ratio.den = pCodecCtx->sample_aspect_ratio.den;
243 +               info.pixel_ratio.num = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num;
244 +               info.pixel_ratio.den = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.den;
245         }
246         else
247         {
248                 info.pixel_ratio.num = 1;
249                 info.pixel_ratio.den = 1;
250         }
251 -
252 -       info.pixel_format = pCodecCtx->pix_fmt;
253 +       info.pixel_format = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
254  
255         // Calculate the DAR (display aspect ratio)
256         Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den);
257 @@ -697,28 +704,60 @@ int FFmpegReader::GetNextPacket()
258  bool FFmpegReader::GetAVFrame()
259  {
260         int frameFinished = -1;
261 +       int ret = 0;
262  
263         // Decode video frame
264         AVFrame *next_frame = AV_ALLOCATE_FRAME();
265         #pragma omp critical (packet_cache)
266 -       avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
267 -
268 -       // is frame finished
269 -       if (frameFinished)
270         {
271 -               // AVFrames are clobbered on the each call to avcodec_decode_video, so we
272 -               // must make a copy of the image data before this method is called again.
273 -               pFrame = new AVPicture();
274 -               avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, info.height);
275 -               av_picture_copy(pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width, info.height);
276 -
277 -               // Detect interlaced frame (only once)
278 -               if (!check_interlace)
279 -               {
280 -                       check_interlace = true;
281 -                       info.interlaced_frame = next_frame->interlaced_frame;
282 -                       info.top_field_first = next_frame->top_field_first;
283 +       #if IS_FFMPEG_3_2
284 +               frameFinished = 0;
285 +               ret = avcodec_send_packet(pCodecCtx, packet);
286 +               if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
287 +                       ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
288 +               }
289 +               else {
290 +                       pFrame = new AVFrame();
291 +                       while (ret >= 0) {
292 +                               ret =  avcodec_receive_frame(pCodecCtx, next_frame);
293 +                 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
294 +                 break;
295 +                               }
296 +                               // TODO also handle possible further frames
297 +                               // Use only the first frame like avcodec_decode_video2
298 +                               if (frameFinished == 0 ) {
299 +                                       frameFinished = 1;
300 +                                       av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 1);
301 +                                       av_image_copy(pFrame->data, pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize,
302 +                                                                                               (AVPixelFormat)(pStream->codecpar->format), info.width, info.height);
303 +                                       if (!check_interlace)   {
304 +                                               check_interlace = true;
305 +                                               info.interlaced_frame = next_frame->interlaced_frame;
306 +                                               info.top_field_first = next_frame->top_field_first;
307 +                                       }
308 +                               }
309 +                       }
310 +               }
311 +       #else
312 +               avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
313 +
314 +               // is frame finished
315 +               if (frameFinished) {
316 +                       // AVFrames are clobbered on the each call to avcodec_decode_video, so we
317 +                       // must make a copy of the image data before this method is called again.
318 +                       pFrame = AV_ALLOCATE_FRAME();
319 +                       avpicture_alloc((AVPicture *) pFrame, pCodecCtx->pix_fmt, info.width, info.height);
320 +                       av_picture_copy((AVPicture *) pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width,
321 +                                                       info.height);
322 +
323 +                       // Detect interlaced frame (only once)
324 +                       if (!check_interlace) {
325 +                               check_interlace = true;
326 +                               info.interlaced_frame = next_frame->interlaced_frame;
327 +                               info.top_field_first = next_frame->top_field_first;
328 +                       }
329                 }
330 +       #endif
331         }
332  
333         // deallocate the frame
334 @@ -800,11 +839,11 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
335         ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessVideoPacket (Before)", "requested_frame", requested_frame, "current_frame", current_frame, "", -1, "", -1, "", -1, "", -1);
336  
337         // Init some things local (for OpenMP)
338 -       PixelFormat pix_fmt = pCodecCtx->pix_fmt;
339 +       PixelFormat pix_fmt = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
340         int height = info.height;
341         int width = info.width;
342         int64_t video_length = info.video_length;
343 -    AVPicture *my_frame = pFrame;
344 +       AVFrame *my_frame = pFrame;
345  
346         // Add video frame to list of processing video frames
347         const GenericScopedLock<CriticalSection> lock(processingCriticalSection);
348 @@ -844,17 +883,16 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
349                 }
350  
351                 // Determine required buffer size and allocate buffer
352 -               numBytes = avpicture_get_size(PIX_FMT_RGBA, width, height);
353 +               numBytes = AV_GET_IMAGE_SIZE(PIX_FMT_RGBA, width, height);
354 +
355                 #pragma omp critical (video_buffer)
356                 buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
357  
358 -               // Assign appropriate parts of buffer to image planes in pFrameRGB
359 -               // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
360 -               // of AVPicture
361 -               avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
362 +               // Copy picture data from one AVFrame (or AVPicture) to another one.
363 +               AV_COPY_PICTURE_DATA(pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
364  
365 -               SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, pCodecCtx->pix_fmt, width,
366 -                                                                                                         height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
367 +               SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), width,
368 +                                                                                                                         height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
369  
370                 // Resize / Convert to RGB
371                 sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 0,
372 @@ -925,20 +963,52 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
373  
374         // re-initialize buffer size (it gets changed in the avcodec_decode_audio2 method call)
375         int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
376 -       int used = avcodec_decode_audio4(aCodecCtx, audio_frame, &frame_finished, packet);
377 +       #pragma omp critical (ProcessAudioPacket)
378 +       {
379 +       #if IS_FFMPEG_3_2
380 +               int ret = 0;
381 +               frame_finished = 1;
382 +               while((packet->size > 0 || (!packet->data && frame_finished)) && ret >= 0) {
383 +                       frame_finished = 0;
384 +                       ret =  avcodec_send_packet(aCodecCtx, packet);
385 +                       if (ret < 0 && ret !=  AVERROR(EINVAL) && ret != AVERROR_EOF) {
386 +                               avcodec_send_packet(aCodecCtx, NULL);
387 +                               break;
388 +                       }
389 +                       if (ret >= 0)
390 +                               packet->size = 0;
391 +                       ret =  avcodec_receive_frame(aCodecCtx, audio_frame);
392 +                       if (ret >= 0)
393 +                               frame_finished = 1;
394 +                       if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
395 +                               avcodec_flush_buffers(aCodecCtx);
396 +                               ret = 0;
397 +                       }
398 +                       if (ret >= 0) {
399 +                               ret = frame_finished;
400 +                       }
401 +               }
402 +               if (!packet->data && !frame_finished)
403 +               {
404 +                       ret = -1;
405 +               }
406 +       #else
407 +               int used = avcodec_decode_audio4(aCodecCtx, audio_frame, &frame_finished, packet);
408 +#endif
409 +       }
410  
411         if (frame_finished) {
412  
413                 // determine how many samples were decoded
414 -               int planar = av_sample_fmt_is_planar(aCodecCtx->sample_fmt);
415 +               int planar = av_sample_fmt_is_planar((AVSampleFormat)AV_GET_CODEC_PIXEL_FORMAT(aStream, aCodecCtx));
416                 int plane_size = -1;
417                 data_size = av_samples_get_buffer_size(&plane_size,
418 -                               aCodecCtx->channels,
419 +                               AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels,
420                                 audio_frame->nb_samples,
421 -                               aCodecCtx->sample_fmt, 1);
422 +                               (AVSampleFormat)(AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx)), 1);
423  
424                 // Calculate total number of samples
425 -               packet_samples = audio_frame->nb_samples * aCodecCtx->channels;
426 +               packet_samples = audio_frame->nb_samples * AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
427         }
428  
429         // Estimate the # of samples and the end of this packet's location (to prevent GAPS for the next timestamp)
430 @@ -999,7 +1069,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
431         // Allocate audio buffer
432         int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
433  
434 -       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);
435 +       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);
436  
437         // Create output frame
438         AVFrame *audio_converted = AV_ALLOCATE_FRAME();
439 @@ -1012,9 +1082,9 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
440  
441         // setup resample context
442         avr = avresample_alloc_context();
443 -       av_opt_set_int(avr,  "in_channel_layout", aCodecCtx->channel_layout, 0);
444 -       av_opt_set_int(avr, "out_channel_layout", aCodecCtx->channel_layout, 0);
445 -       av_opt_set_int(avr,  "in_sample_fmt",     aCodecCtx->sample_fmt,     0);
446 +       av_opt_set_int(avr,  "in_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
447 +       av_opt_set_int(avr, "out_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
448 +       av_opt_set_int(avr,  "in_sample_fmt",     AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), 0);
449         av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_S16,     0);
450         av_opt_set_int(avr,  "in_sample_rate",    info.sample_rate,    0);
451         av_opt_set_int(avr, "out_sample_rate",    info.sample_rate,    0);
452 @@ -1767,7 +1837,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram
453  void FFmpegReader::CheckFPS()
454  {
455         check_fps = true;
456 -       avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, info.height);
457 +       AV_ALLOCATE_IMAGE(pFrame, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), info.width, info.height);
458  
459         int first_second_counter = 0;
460         int second_second_counter = 0;
461 @@ -1878,17 +1948,14 @@ void FFmpegReader::CheckFPS()
462  }
463  
464  // Remove AVFrame from cache (and deallocate it's memory)
465 -void FFmpegReader::RemoveAVFrame(AVPicture* remove_frame)
466 +void FFmpegReader::RemoveAVFrame(AVFrame* remove_frame)
467  {
468      // Remove pFrame (if exists)
469      if (remove_frame)
470      {
471          // Free memory
472 -        avpicture_free(remove_frame);
473 -
474 -        // Delete the object
475 -        delete remove_frame;
476 -    }
477 +               av_freep(&remove_frame->data[0]);
478 +       }
479  }
480  
481  // Remove AVPacket from cache (and deallocate it's memory)
482 diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp
483 index 54017e8..82e8573 100644
484 --- a/tests/FFmpegReader_Tests.cpp
485 +++ b/tests/FFmpegReader_Tests.cpp
486 @@ -72,8 +72,8 @@ TEST(FFmpegReader_Check_Audio_File)
487         CHECK_CLOSE(0.0f, samples[50], 0.00001);
488         CHECK_CLOSE(0.0f, samples[100], 0.00001);
489         CHECK_CLOSE(0.0f, samples[200], 0.00001);
490 -       CHECK_CLOSE(0.160781, samples[230], 0.00001);
491 -       CHECK_CLOSE(-0.06125f, samples[300], 0.00001);
492 +       CHECK_CLOSE(0.164062f, samples[230], 0.00001);
493 +       CHECK_CLOSE(-0.0625f, samples[300], 0.00001);
494  
495         // Close reader
496         r.Close();
497 From 22384c770501b9d737501847400f571f67edf385 Mon Sep 17 00:00:00 2001
498 From: Jonathan Thomas <jonathan@openshot.org>
499 Date: Wed, 28 Mar 2018 15:09:55 -0500
500 Subject: [PATCH] FFMPEG 3.2 support for FFmpegWriter (Thanks Peter!)
501
502 ---
503  include/FFmpegUtilities.h |  62 +++++++++---
504  src/FFmpegWriter.cpp      | 252 +++++++++++++++++++++++++++++-----------------
505  2 files changed, 210 insertions(+), 104 deletions(-)
506
507 diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
508 index b38132f..578c658 100644
509 --- a/include/FFmpegUtilities.h
510 +++ b/include/FFmpegUtilities.h
511 @@ -108,53 +108,87 @@
512  
513         #if IS_FFMPEG_3_2
514                 #define AV_ALLOCATE_FRAME() av_frame_alloc()
515 -               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1);
516 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1)
517                 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
518         #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
519                 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
520 -               #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context);
521 +               #define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context)
522                 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
523 -               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id;
524 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id
525                 auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* av_codec) { \
526                         AVCodecContext *context = avcodec_alloc_context3(av_codec); \
527                         avcodec_parameters_to_context(context, av_stream->codecpar); \
528                         return context; \
529                 };
530 +               #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_codec;
531 +               #define AV_GET_CODEC_FROM_STREAM(av_stream,codec_in)
532                 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
533                 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
534                 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
535                 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
536 -               #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);
537 +               #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)
538 +               #define AV_OUTPUT_CONTEXT(output_context, path) avformat_alloc_output_context2( output_context, NULL, NULL, path)
539 +               #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
540 +               #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);
541 +               #define AV_FORMAT_NEW_STREAM(oc, st_codec, av_codec, av_st)     av_st = avformat_new_stream(oc, NULL);\
542 +                       if (!av_st) \
543 +                               throw OutOfMemory("Could not allocate memory for the video stream.", path); \
544 +                       c = avcodec_alloc_context3(av_codec); \
545 +                       st_codec = c; \
546 +                       av_st->codecpar->codec_id = av_codec->id;
547 +               #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec) avcodec_parameters_from_context(av_stream->codecpar, av_codec);
548         #elif LIBAVFORMAT_VERSION_MAJOR >= 55
549                 #define AV_ALLOCATE_FRAME() av_frame_alloc()
550 -               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
551 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
552                 #define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
553         #define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
554                 #define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
555 -               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
556 +               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
557                 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
558 -               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
559 -               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
560 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
561 +               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
562 +               #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
563 +               #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in) codec_in = av_stream->codec;
564                 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
565                 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
566                 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
567                 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
568 -               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
569 +               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
570 +               #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
571 +               #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
572 +               #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
573 +               #define AV_FORMAT_NEW_STREAM( oc,  av_context,  av_codec, av_st) av_st = avformat_new_stream(oc, av_codec); \
574 +                       if (!av_st) \
575 +                               throw OutOfMemory("Could not allocate memory for the video stream.", path); \
576 +                       avcodec_get_context_defaults3(av_st->codec, av_codec); \
577 +                       c = av_st->codec;
578 +               #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
579         #else
580                 #define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
581 -               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
582 +               #define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height)
583                 #define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
584                 #define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
585                 #define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
586 -               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
587 +               #define AV_FREE_CONTEXT(av_context) avcodec_close(av_context)
588                 #define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
589 -               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
590 -               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
591 +               #define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id
592 +               #define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec
593 +               #define AV_GET_CODEC_PAR_CONTEXT(av_stream, av_codec) av_stream->codec
594 +               #define AV_GET_CODEC_FROM_STREAM(av_stream, codec_in ) codec_in = av_stream->codec;
595                 #define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
596                 #define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
597                 #define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
598                 #define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
599 -               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
600 +               #define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height)
601 +               #define AV_OUTPUT_CONTEXT(output_context, path) oc = avformat_alloc_context()
602 +               #define AV_OPTION_FIND(priv_data, name) av_opt_find(priv_data, name, NULL, 0, 0)
603 +               #define AV_OPTION_SET(av_stream, priv_data, name, value, avcodec) av_opt_set (priv_data, name, value, 0)
604 +               #define AV_FORMAT_NEW_STREAM( oc,  av_context,  av_codec, av_st) av_st = avformat_new_stream(oc, av_codec); \
605 +                       if (!av_st) \
606 +                               throw OutOfMemory("Could not allocate memory for the video stream.", path); \
607 +                       avcodec_get_context_defaults3(av_st->codec, av_codec); \
608 +                       c = av_st->codec;
609 +               #define AV_COPY_PARAMS_FROM_CONTEXT(av_stream, av_codec)
610         #endif
611  
612  
613 diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp
614 index e83e478..889e262 100644
615 --- a/src/FFmpegWriter.cpp
616 +++ b/src/FFmpegWriter.cpp
617 @@ -76,7 +76,7 @@ void FFmpegWriter::auto_detect_format()
618                 throw InvalidFormat("Could not deduce output format from file extension.", path);
619  
620         // Allocate the output media context
621 -       oc = avformat_alloc_context();
622 +       AV_OUTPUT_CONTEXT(&oc, path.c_str());
623         if (!oc)
624                 throw OutOfMemory("Could not allocate memory for AVFormatContext.", path);
625  
626 @@ -211,12 +211,19 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value)
627  {
628         // Declare codec context
629         AVCodecContext *c = NULL;
630 +       AVStream *st = NULL;
631         stringstream convert(value);
632  
633 -       if (info.has_video && stream == VIDEO_STREAM && video_st)
634 -               c = video_st->codec;
635 -       else if (info.has_audio && stream == AUDIO_STREAM && audio_st)
636 -               c = audio_st->codec;
637 +       if (info.has_video && stream == VIDEO_STREAM && video_st) {
638 +               st = video_st;
639 +               // Get codec context
640 +               c = AV_GET_CODEC_PAR_CONTEXT(st, video_codec);
641 +       }
642 +       else if (info.has_audio && stream == AUDIO_STREAM && audio_st) {
643 +               st = audio_st;
644 +               // Get codec context
645 +               c = AV_GET_CODEC_PAR_CONTEXT(st, audio_codec);
646 +       }
647         else
648                 throw NoStreamsFound("The stream was not found. Be sure to call PrepareStreams() first.", path);
649  
650 @@ -226,11 +233,7 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value)
651         // Was a codec / stream found?
652         if (c)
653                 // Find AVOption (if it exists)
654 -               #if LIBAVFORMAT_VERSION_MAJOR <= 53
655 -                       option = av_find_opt(c->priv_data, name.c_str(), NULL, NULL, NULL);
656 -               #else
657 -                       option = av_opt_find(c->priv_data, name.c_str(), NULL, 0, 0);
658 -               #endif
659 +               option = AV_OPTION_FIND(c->priv_data, name.c_str());
660  
661         // Was option found?
662         if (option || (name == "g" || name == "qmin" || name == "qmax" || name == "max_b_frames" || name == "mb_decision" ||
663 @@ -283,11 +286,7 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value)
664  
665                 else
666                         // Set AVOption
667 -                       #if LIBAVFORMAT_VERSION_MAJOR <= 53
668 -                               av_set_string3 (c->priv_data, name.c_str(), value.c_str(), 0, NULL);
669 -                       #else
670 -                               av_opt_set (c->priv_data, name.c_str(), value.c_str(), 0);
671 -                       #endif
672 +                       AV_OPTION_SET(st, c->priv_data, name.c_str(), value.c_str(), c);
673  
674                 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::SetOption (" + (string)name + ")", "stream == VIDEO_STREAM", stream == VIDEO_STREAM, "", -1, "", -1, "", -1, "", -1, "", -1);
675  
676 @@ -334,7 +333,9 @@ void FFmpegWriter::WriteHeader()
677  
678         // Write the stream header, if any
679         // TODO: add avoptions / parameters instead of NULL
680 -       avformat_write_header(oc, NULL);
681 +       if (avformat_write_header(oc, NULL) != 0) {
682 +           throw InvalidFile("Could not write header to file.", path);
683 +       }
684  
685         // Mark as 'written'
686         write_header = true;
687 @@ -548,10 +549,10 @@ void FFmpegWriter::WriteTrailer()
688  // Flush encoders
689  void FFmpegWriter::flush_encoders()
690  {
691 -    if (info.has_audio && audio_codec && audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_codec->frame_size <= 1)
692 -        return;
693 -    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)
694 -        return;
695 +       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)
696 +               return;
697 +       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)
698 +               return;
699  
700      int error_code = 0;
701      int stop_encoding = 1;
702 @@ -575,29 +576,37 @@ void FFmpegWriter::flush_encoders()
703                         int got_packet = 0;
704                         int error_code = 0;
705  
706 -                       #if LIBAVFORMAT_VERSION_MAJOR >= 54
707 -                               // Newer versions of FFMpeg
708 -                       error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
709 -
710 +                       #if IS_FFMPEG_3_2
711 +                       #pragma omp critical (write_video_packet)
712 +                       {
713 +                               // Encode video packet (latest version of FFmpeg)
714 +                               error_code = avcodec_send_frame(video_codec, NULL);
715 +                               got_packet = 0;
716 +                       }
717                         #else
718 -                               // Older versions of FFmpeg (much sloppier)
719  
720 -                               // Encode Picture and Write Frame
721 -                               int video_outbuf_size = 0;
722 +                               #if LIBAVFORMAT_VERSION_MAJOR >= 54
723 +                               // Encode video packet (older than FFmpeg 3.2)
724 +                               error_code = avcodec_encode_video2(video_codec, &pkt, NULL, &got_packet);
725  
726 -                               /* encode the image */
727 -                               int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
728 +                               #else
729 +                                       // Encode video packet (even older version of FFmpeg)
730 +                                       int video_outbuf_size = 0;
731  
732 -                               /* if zero size, it means the image was buffered */
733 -                               if (out_size > 0) {
734 -                                       if(video_codec->coded_frame->key_frame)
735 -                                               pkt.flags |= AV_PKT_FLAG_KEY;
736 -                                       pkt.data= video_outbuf;
737 -                                       pkt.size= out_size;
738 +                                       /* encode the image */
739 +                                       int out_size = avcodec_encode_video(video_codec, NULL, video_outbuf_size, NULL);
740  
741 -                                       // got data back (so encode this frame)
742 -                                       got_packet = 1;
743 -                               }
744 +                                       /* if zero size, it means the image was buffered */
745 +                                       if (out_size > 0) {
746 +                                               if(video_codec->coded_frame->key_frame)
747 +                                                       pkt.flags |= AV_PKT_FLAG_KEY;
748 +                                               pkt.data= video_outbuf;
749 +                                               pkt.size= out_size;
750 +
751 +                                               // got data back (so encode this frame)
752 +                                               got_packet = 1;
753 +                                       }
754 +                               #endif
755                         #endif
756  
757                         if (error_code < 0) {
758 @@ -651,7 +660,12 @@ void FFmpegWriter::flush_encoders()
759  
760                         /* encode the image */
761                         int got_packet = 0;
762 +                       #if IS_FFMPEG_3_2
763 +                       avcodec_send_frame(audio_codec, NULL);
764 +                       got_packet = 0;
765 +                       #else
766                         error_code = avcodec_encode_audio2(audio_codec, &pkt, NULL, &got_packet);
767 +                       #endif
768                         if (error_code < 0) {
769                                 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::flush_encoders ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
770                         }
771 @@ -692,14 +706,14 @@ void FFmpegWriter::flush_encoders()
772  // Close the video codec
773  void FFmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
774  {
775 -       avcodec_close(st->codec);
776 +       AV_FREE_CONTEXT(video_codec);
777         video_codec = NULL;
778  }
779  
780  // Close the audio codec
781  void FFmpegWriter::close_audio(AVFormatContext *oc, AVStream *st)
782  {
783 -       avcodec_close(st->codec);
784 +       AV_FREE_CONTEXT(audio_codec);
785         audio_codec = NULL;
786  
787         // Clear buffers
788 @@ -743,7 +757,7 @@ void FFmpegWriter::Close()
789  
790         // Free the streams
791         for (int i = 0; i < oc->nb_streams; i++) {
792 -               av_freep(&oc->streams[i]->codec);
793 +               av_freep(AV_GET_CODEC_ATTRIBUTES(&oc->streams[i], &oc->streams[i]));
794                 av_freep(&oc->streams[i]);
795         }
796  
797 @@ -796,14 +810,8 @@ AVStream* FFmpegWriter::add_audio_stream()
798                 throw InvalidCodec("A valid audio codec could not be found for this file.", path);
799  
800         // Create a new audio stream
801 -       st = avformat_new_stream(oc, codec);
802 -       if (!st)
803 -               throw OutOfMemory("Could not allocate memory for the audio stream.", path);
804 +       AV_FORMAT_NEW_STREAM(oc, audio_codec, codec, st)
805  
806 -       // Set default values
807 -    avcodec_get_context_defaults3(st->codec, codec);
808 -
809 -       c = st->codec;
810         c->codec_id = codec->id;
811  #if LIBAVFORMAT_VERSION_MAJOR >= 53
812         c->codec_type = AVMEDIA_TYPE_AUDIO;
813 @@ -867,6 +875,7 @@ AVStream* FFmpegWriter::add_audio_stream()
814         if (oc->oformat->flags & AVFMT_GLOBALHEADER)
815                 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
816  
817 +       AV_COPY_PARAMS_FROM_CONTEXT(st, c);
818         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);
819  
820         return st;
821 @@ -878,20 +887,14 @@ AVStream* FFmpegWriter::add_video_stream()
822         AVCodecContext *c;
823         AVStream *st;
824  
825 -       // Find the audio codec
826 +       // Find the video codec
827         AVCodec *codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
828         if (codec == NULL)
829                 throw InvalidCodec("A valid video codec could not be found for this file.", path);
830  
831 -       // Create a new stream
832 -       st = avformat_new_stream(oc, codec);
833 -       if (!st)
834 -               throw OutOfMemory("Could not allocate memory for the video stream.", path);
835 +       // Create a new video stream
836 +       AV_FORMAT_NEW_STREAM(oc, video_codec, codec, st)
837  
838 -       // Set default values
839 -    avcodec_get_context_defaults3(st->codec, codec);
840 -
841 -       c = st->codec;
842         c->codec_id = codec->id;
843  #if LIBAVFORMAT_VERSION_MAJOR >= 53
844         c->codec_type = AVMEDIA_TYPE_VIDEO;
845 @@ -923,6 +926,10 @@ AVStream* FFmpegWriter::add_video_stream()
846          identically 1. */
847         c->time_base.num = info.video_timebase.num;
848         c->time_base.den = info.video_timebase.den;
849 +       #if LIBAVFORMAT_VERSION_MAJOR >= 55
850 +       c->framerate = av_inv_q(c->time_base);
851 +       #endif
852 +       st->avg_frame_rate = av_inv_q(c->time_base);
853         st->time_base.num = info.video_timebase.num;
854         st->time_base.den = info.video_timebase.den;
855  
856 @@ -965,6 +972,7 @@ AVStream* FFmpegWriter::add_video_stream()
857          }
858      }
859  
860 +       AV_COPY_PARAMS_FROM_CONTEXT(st, c);
861         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);
862  
863         return st;
864 @@ -974,7 +982,7 @@ AVStream* FFmpegWriter::add_video_stream()
865  void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
866  {
867         AVCodec *codec;
868 -       audio_codec = st->codec;
869 +       AV_GET_CODEC_FROM_STREAM(st, audio_codec)
870  
871         // Set number of threads equal to number of processors (not to exceed 16)
872         audio_codec->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
873 @@ -989,6 +997,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
874         // Open the codec
875         if (avcodec_open2(audio_codec, codec, NULL) < 0)
876                 throw InvalidCodec("Could not open codec", path);
877 +       AV_COPY_PARAMS_FROM_CONTEXT(st, audio_codec);
878  
879         // Calculate the size of the input frame (i..e how many samples per packet), and the output buffer
880         // TODO: Ugly hack for PCM codecs (will be removed ASAP with new PCM support to compute the input frame size in samples
881 @@ -996,7 +1005,8 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
882                 // No frame size found... so calculate
883                 audio_input_frame_size = 50000 / info.channels;
884  
885 -               switch (st->codec->codec_id) {
886 +               int s = AV_FIND_DECODER_CODEC_ID(st);
887 +               switch (s) {
888                 case AV_CODEC_ID_PCM_S16LE:
889                 case AV_CODEC_ID_PCM_S16BE:
890                 case AV_CODEC_ID_PCM_U16LE:
891 @@ -1039,7 +1049,7 @@ void FFmpegWriter::open_audio(AVFormatContext *oc, AVStream *st)
892  void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
893  {
894         AVCodec *codec;
895 -       video_codec = st->codec;
896 +       AV_GET_CODEC_FROM_STREAM(st, video_codec)
897  
898         // Set number of threads equal to number of processors (not to exceed 16)
899         video_codec->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
900 @@ -1047,7 +1057,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
901         /* find the video encoder */
902         codec = avcodec_find_encoder_by_name(info.vcodec.c_str());
903         if (!codec)
904 -               codec = avcodec_find_encoder(video_codec->codec_id);
905 +               codec = avcodec_find_encoder(AV_FIND_DECODER_CODEC_ID(st));
906         if (!codec)
907                 throw InvalidCodec("Could not find codec", path);
908  
909 @@ -1058,6 +1068,7 @@ void FFmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
910         /* open the codec */
911         if (avcodec_open2(video_codec, codec, NULL) < 0)
912                 throw InvalidCodec("Could not open codec", path);
913 +       AV_COPY_PARAMS_FROM_CONTEXT(st, video_codec);
914  
915         // Add video metadata (if any)
916         for(std::map<string, string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter)
917 @@ -1345,8 +1356,39 @@ void FFmpegWriter::write_audio_packets(bool final)
918  
919                         /* encode the audio samples */
920                         int got_packet_ptr = 0;
921 -                       int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
922  
923 +                       #if IS_FFMPEG_3_2
924 +                       // Encode audio (latest version of FFmpeg)
925 +                       int error_code;
926 +                       int ret = 0;
927 +                       int frame_finished = 0;
928 +                       error_code = ret =  avcodec_send_frame(audio_codec, frame_final);
929 +                       if (ret < 0 && ret !=  AVERROR(EINVAL) && ret != AVERROR_EOF) {
930 +                               avcodec_send_frame(audio_codec, NULL);
931 +                       }
932 +                       else {
933 +                               if (ret >= 0)
934 +                                       pkt.size = 0;
935 +                               ret =  avcodec_receive_packet(audio_codec, &pkt);
936 +                               if (ret >= 0)
937 +                                       frame_finished = 1;
938 +                               if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
939 +                                       avcodec_flush_buffers(audio_codec);
940 +                                       ret = 0;
941 +                               }
942 +                               if (ret >= 0) {
943 +                                       ret = frame_finished;
944 +                               }
945 +                       }
946 +                       if (!pkt.data && !frame_finished)
947 +                       {
948 +                               ret = -1;
949 +                       }
950 +                       got_packet_ptr = ret;
951 +                       #else
952 +                       // Encode audio (older versions of FFmpeg)
953 +                       int error_code = avcodec_encode_audio2(audio_codec, &pkt, frame_final, &got_packet_ptr);
954 +                       #endif
955                         /* if zero size, it means the image was buffered */
956                         if (error_code == 0 && got_packet_ptr) {
957  
958 @@ -1416,7 +1458,7 @@ AVFrame* FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int heig
959                 throw OutOfMemory("Could not allocate AVFrame", path);
960  
961         // Determine required buffer size and allocate buffer
962 -       *buffer_size = avpicture_get_size(pix_fmt, width, height);
963 +       *buffer_size = AV_GET_IMAGE_SIZE(pix_fmt, width, height);
964  
965         // Create buffer (if not provided)
966         if (!new_buffer)
967 @@ -1424,7 +1466,7 @@ AVFrame* FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int heig
968                 // New Buffer
969                 new_buffer = (uint8_t*)av_malloc(*buffer_size * sizeof(uint8_t));
970                 // Attach buffer to AVFrame
971 -               avpicture_fill((AVPicture *)new_av_frame, new_buffer, pix_fmt, width, height);
972 +               AV_COPY_PICTURE_DATA(new_av_frame, new_buffer, pix_fmt, width, height);
973                 new_av_frame->width = width;
974                 new_av_frame->height = height;
975                 new_av_frame->format = pix_fmt;
976 @@ -1468,10 +1510,14 @@ void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame)
977  
978                 // Init AVFrame for source image & final (converted image)
979                 frame_source = allocate_avframe(PIX_FMT_RGBA, source_image_width, source_image_height, &bytes_source, (uint8_t*) pixels);
980 +               #if IS_FFMPEG_3_2
981 +               AVFrame *frame_final = allocate_avframe((AVPixelFormat)(video_st->codecpar->format), info.width, info.height, &bytes_final, NULL);
982 +               #else
983                 AVFrame *frame_final = allocate_avframe(video_codec->pix_fmt, info.width, info.height, &bytes_final, NULL);
984 +               #endif
985  
986                 // Fill with data
987 -               avpicture_fill((AVPicture *) frame_source, (uint8_t*)pixels, PIX_FMT_RGBA, source_image_width, source_image_height);
988 +        AV_COPY_PICTURE_DATA(frame_source, (uint8_t*)pixels, PIX_FMT_RGBA, source_image_width, source_image_height);
989                 ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::process_video_packet", "frame->number", frame->number, "bytes_source", bytes_source, "bytes_final", bytes_final, "", -1, "", -1, "", -1);
990  
991                 // Resize & convert pixel format
992 @@ -1539,30 +1585,60 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame* fra
993                 /* encode the image */
994                 int got_packet_ptr = 0;
995                 int error_code = 0;
996 -               #if LIBAVFORMAT_VERSION_MAJOR >= 54
997 -                       // Newer versions of FFMpeg
998 -                       error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
999 -
1000 +               #if IS_FFMPEG_3_2
1001 +               // Write video packet (latest version of FFmpeg)
1002 +               int frameFinished = 0;
1003 +               int ret = avcodec_send_frame(video_codec, frame_final);
1004 +               error_code = ret;
1005 +               if (ret < 0 ) {
1006 +                       ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet (Frame not sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
1007 +                       if (ret == AVERROR(EAGAIN) )
1008 +                               cerr << "Frame EAGAIN" << "\n";
1009 +                       if (ret == AVERROR_EOF )
1010 +                               cerr << "Frame AVERROR_EOF" << "\n";
1011 +                       avcodec_send_frame(video_codec, NULL);
1012 +               }
1013 +               else {
1014 +                       while (ret >= 0) {
1015 +                               ret = avcodec_receive_packet(video_codec, &pkt);
1016 +               if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
1017 +                                       avcodec_flush_buffers(video_codec);
1018 +                                       got_packet_ptr = 0;
1019 +               break;
1020 +                               }
1021 +                               if (ret == 0) {
1022 +                                       got_packet_ptr = 1;
1023 +                                       break;
1024 +                               }
1025 +                       }
1026 +               }
1027                 #else
1028 -                       // Older versions of FFmpeg (much sloppier)
1029 +                       #if LIBAVFORMAT_VERSION_MAJOR >= 54
1030 +                               // Write video packet (older than FFmpeg 3.2)
1031 +                               error_code = avcodec_encode_video2(video_codec, &pkt, frame_final, &got_packet_ptr);
1032 +                               if (error_code != 0 )
1033 +                                       cerr << "Frame AVERROR_EOF" << "\n";
1034 +                               if (got_packet_ptr == 0 )
1035 +                                       cerr << "Frame gotpacket error" << "\n";
1036 +                       #else
1037 +                               // Write video packet (even older versions of FFmpeg)
1038 +                               int video_outbuf_size = 200000;
1039 +                               video_outbuf = (uint8_t*) av_malloc(200000);
1040  
1041 -                       // Encode Picture and Write Frame
1042 -                       int video_outbuf_size = 200000;
1043 -                       video_outbuf = (uint8_t*) av_malloc(200000);
1044 +                               /* encode the image */
1045 +                               int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
1046  
1047 -                       /* encode the image */
1048 -                       int out_size = avcodec_encode_video(video_codec, video_outbuf, video_outbuf_size, frame_final);
1049 +                               /* if zero size, it means the image was buffered */
1050 +                               if (out_size > 0) {
1051 +                                       if(video_codec->coded_frame->key_frame)
1052 +                                               pkt.flags |= AV_PKT_FLAG_KEY;
1053 +                                       pkt.data= video_outbuf;
1054 +                                       pkt.size= out_size;
1055  
1056 -                       /* if zero size, it means the image was buffered */
1057 -                       if (out_size > 0) {
1058 -                               if(video_codec->coded_frame->key_frame)
1059 -                                       pkt.flags |= AV_PKT_FLAG_KEY;
1060 -                               pkt.data= video_outbuf;
1061 -                               pkt.size= out_size;
1062 -
1063 -                               // got data back (so encode this frame)
1064 -                               got_packet_ptr = 1;
1065 -                       }
1066 +                                       // got data back (so encode this frame)
1067 +                                       got_packet_ptr = 1;
1068 +                               }
1069 +                       #endif
1070                 #endif
1071  
1072                 /* if zero size, it means the image was buffered */
1073 @@ -1612,15 +1688,11 @@ void FFmpegWriter::OutputStreamInfo()
1074  // Init a collection of software rescalers (thread safe)
1075  void FFmpegWriter::InitScalers(int source_width, int source_height)
1076  {
1077 -       // Get the codec
1078 -       AVCodecContext *c;
1079 -       c = video_st->codec;
1080 -
1081         // Init software rescalers vector (many of them, one for each thread)
1082         for (int x = 0; x < num_of_rescalers; x++)
1083         {
1084                 // Init the software scaler from FFMpeg
1085 -               img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, info.width, info.height, c->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL);
1086 +               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);
1087  
1088                 // Add rescaler to vector
1089                 image_rescalers.push_back(img_convert_ctx);
1090 From 0db54c8a2c1becc6c0f56807e178c5ba93cda3c5 Mon Sep 17 00:00:00 2001
1091 From: Jonathan Thomas <jonathan@openshot.org>
1092 Date: Thu, 29 Mar 2018 01:29:10 -0500
1093 Subject: [PATCH] Fixing FFmpeg version breakage in FFmpegWriter
1094
1095 ---
1096  src/FFmpegWriter.cpp | 2 +-
1097  1 file changed, 1 insertion(+), 1 deletion(-)
1098
1099 diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp
1100 index 889e262..5f50b85 100644
1101 --- a/src/FFmpegWriter.cpp
1102 +++ b/src/FFmpegWriter.cpp
1103 @@ -926,7 +926,7 @@ AVStream* FFmpegWriter::add_video_stream()
1104          identically 1. */
1105         c->time_base.num = info.video_timebase.num;
1106         c->time_base.den = info.video_timebase.den;
1107 -       #if LIBAVFORMAT_VERSION_MAJOR >= 55
1108 +       #if LIBAVFORMAT_VERSION_MAJOR >= 56
1109         c->framerate = av_inv_q(c->time_base);
1110         #endif
1111         st->avg_frame_rate = av_inv_q(c->time_base);
1112 --- a/src/FFmpegReader.cpp~     2018-04-29 21:29:04.000000000 +0200
1113 +++ b/src/FFmpegReader.cpp      2018-04-29 21:30:32.336155455 +0200
1114 @@ -941,7 +941,7 @@ void FFmpegReader::ProcessAudioPacket(in
1115         int data_size = 0;
1116  
1117         // re-initialize buffer size (it gets changed in the avcodec_decode_audio2 method call)
1118 -       int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
1119 +       int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + AV_INPUT_BUFFER_PADDING_SIZE;
1120         #pragma omp critical (ProcessAudioPacket)
1121         {
1122         #if IS_FFMPEG_3_2
1123 @@ -1046,7 +1046,7 @@ void FFmpegReader::ProcessAudioPacket(in
1124  
1125  
1126         // Allocate audio buffer
1127 -       int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
1128 +       int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
1129  
1130         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);
1131  
1132 --- libopenshot-0.1.9/src/FFmpegWriter.cpp~     2018-04-29 22:11:22.000000000 +0200
1133 +++ libopenshot-0.1.9/src/FFmpegWriter.cpp      2018-04-29 22:13:25.133795468 +0200
1134 @@ -868,7 +868,7 @@ AVStream* FFmpegWriter::add_audio_stream
1135  
1136         // some formats want stream headers to be separate
1137         if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1138 -               c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1139 +               c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1140  
1141         AV_COPY_PARAMS_FROM_CONTEXT(st, c);
1142         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);
1143 @@ -940,7 +940,7 @@ AVStream* FFmpegWriter::add_video_stream
1144                 c->mb_decision = 2;
1145         // some formats want stream headers to be separate
1146         if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1147 -               c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1148 +               c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1149  
1150         // Find all supported pixel formats for this codec
1151      const PixelFormat* supported_pixel_formats = codec->pix_fmts;
1152 --- libopenshot-0.1.9/src/FFmpegWriter.cpp~     2018-04-29 22:18:37.000000000 +0200
1153 +++ libopenshot-0.1.9/src/FFmpegWriter.cpp      2018-04-29 22:20:24.006338376 +0200
1154 @@ -544,8 +544,6 @@ void FFmpegWriter::flush_encoders()
1155  {
1156         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)
1157                 return;
1158 -       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)
1159 -               return;
1160  
1161      int error_code = 0;
1162      int stop_encoding = 1;
1163 @@ -955,10 +953,6 @@ AVStream* FFmpegWriter::add_video_stream
1164              // Raw video should use RGB24
1165                 c->pix_fmt = PIX_FMT_RGB24;
1166  
1167 -        if (strcmp(fmt->name, "gif") != 0)
1168 -                       // If not GIF format, skip the encoding process
1169 -                       // Set raw picture flag (so we don't encode this video)
1170 -                       oc->oformat->flags |= AVFMT_RAWPICTURE;
1171          } else {
1172                 // Set the default codec
1173                 c->pix_fmt = PIX_FMT_YUV420P;
1174 @@ -966,7 +960,7 @@ AVStream* FFmpegWriter::add_video_stream
1175      }
1176  
1177         AV_COPY_PARAMS_FROM_CONTEXT(st, c);
1178 -       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);
1179 +       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);
1180  
1181         return st;
1182  }
1183 @@ -1519,34 +1513,7 @@ void FFmpegWriter::process_video_packet(
1184  // write video frame
1185  bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame* frame_final)
1186  {
1187 -       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);
1188 -
1189 -       if (oc->oformat->flags & AVFMT_RAWPICTURE) {
1190 -               // Raw video case.
1191 -               AVPacket pkt;
1192 -               av_init_packet(&pkt);
1193 -
1194 -               pkt.flags |= AV_PKT_FLAG_KEY;
1195 -               pkt.stream_index= video_st->index;
1196 -               pkt.data= (uint8_t*)frame_final->data;
1197 -               pkt.size= sizeof(AVPicture);
1198 -
1199 -               // Increment PTS (in frames and scaled to the codec's timebase)
1200 -               write_video_count += av_rescale_q(1, (AVRational){info.fps.den, info.fps.num}, video_codec->time_base);
1201 -               pkt.pts = write_video_count;
1202 -
1203 -               /* write the compressed frame in the media file */
1204 -               int error_code = av_interleaved_write_frame(oc, &pkt);
1205 -               if (error_code < 0)
1206 -               {
1207 -                       ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet ERROR [" + (string)av_err2str(error_code) + "]", "error_code", error_code, "", -1, "", -1, "", -1, "", -1, "", -1);
1208 -                       return false;
1209 -               }
1210 -
1211 -               // Deallocate packet
1212 -               AV_FREE_PACKET(&pkt);
1213 -
1214 -       } else {
1215 +       ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::write_video_packet", "frame->number", frame->number, "", -1, "", -1, "", -1, "", -1, "", -1);
1216  
1217                 AVPacket pkt;
1218                 av_init_packet(&pkt);
1219 @@ -1653,7 +1620,6 @@ bool FFmpegWriter::write_video_packet(st
1220  
1221                 // Deallocate packet
1222                 AV_FREE_PACKET(&pkt);
1223 -       }
1224  
1225         // Success
1226         return true;
1227
1228 --- libopenshot-0.1.9/src/FFmpegWriter.cpp~     2018-04-29 22:20:42.000000000 +0200
1229 +++ libopenshot-0.1.9/src/FFmpegWriter.cpp      2018-04-29 22:22:06.796083026 +0200
1230 @@ -1022,7 +1022,7 @@ void FFmpegWriter::open_audio(AVFormatCo
1231         audio_encoder_buffer_size = AUDIO_PACKET_ENCODING_SIZE;
1232         audio_encoder_buffer = new uint8_t[audio_encoder_buffer_size];
1233  
1234 -       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);
1235 +       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);
1236  
1237  }
1238  
This page took 0.166708 seconds and 3 git commands to generate.