1 /*
2  * compatibility macros to make every ffmpeg installation appear
3  * like the most current installation (wrapping some functionality sometimes)
4  * it also includes all ffmpeg header files at once, no need to do it
5  * separately.
6  *
7  * Copyright (c) 2011 Peter Schlaile
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  */
19 
20 #ifndef __FFMPEG_COMPAT_H__
21 #define __FFMPEG_COMPAT_H__
22 
23 #include <libavformat/avformat.h>
24 
25 /* check our ffmpeg is new enough, avoids user complaints */
26 #if (LIBAVFORMAT_VERSION_MAJOR < 52) || \
27     ((LIBAVFORMAT_VERSION_MAJOR == 52) && (LIBAVFORMAT_VERSION_MINOR <= 64))
28 #  error "FFmpeg 0.7 or newer is needed, Upgrade your FFmpeg or disable it"
29 #endif
30 /* end sanity check */
31 
32 /* visual studio 2012 does not define inline for C */
33 #ifdef _MSC_VER
34 #  define FFMPEG_INLINE static __inline
35 #else
36 #  define FFMPEG_INLINE static inline
37 #endif
38 
39 #include <libavcodec/avcodec.h>
40 #include <libavutil/mathematics.h>
41 #include <libavutil/opt.h>
42 #include <libavutil/rational.h>
43 
44 #if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
45     ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
46 #  define FFMPEG_HAVE_PARSE_UTILS 1
47 #  include <libavutil/parseutils.h>
48 #endif
49 
50 #include <libswscale/swscale.h>
51 
52 /* Stupid way to distinguish FFmpeg from Libav:
53  * - FFmpeg's MICRO version starts from 100 and goes up, while
54  * - Libav's micro is always below 100.
55  */
56 #if LIBAVCODEC_VERSION_MICRO >= 100
57 #  define AV_USING_FFMPEG
58 #else
59 #  define AV_USING_LIBAV
60 #endif
61 
62 #if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
63     ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105))
64 #  define FFMPEG_HAVE_AVIO 1
65 #endif
66 
67 #if (LIBAVCODEC_VERSION_MAJOR > 53) || \
68     ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || \
69     ((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && \
70      (LIBAVCODEC_VERSION_MICRO >= 1)) || \
71     ((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121))
72 #  define FFMPEG_HAVE_DEFAULT_VAL_UNION 1
73 #endif
74 
75 #if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
76     ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
77 #  define FFMPEG_HAVE_AV_DUMP_FORMAT 1
78 #endif
79 
80 #if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
81     ((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 45))
82 #  define FFMPEG_HAVE_AV_GUESS_FORMAT 1
83 #endif
84 
85 #if (LIBAVCODEC_VERSION_MAJOR > 52) || \
86     ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 23))
87 #  define FFMPEG_HAVE_DECODE_AUDIO3 1
88 #  define FFMPEG_HAVE_DECODE_VIDEO2 1
89 #endif
90 
91 #if (LIBAVCODEC_VERSION_MAJOR > 52) || \
92     ((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 64))
93 #  define FFMPEG_HAVE_AVMEDIA_TYPES 1
94 #endif
95 
96 #if ((LIBAVCODEC_VERSION_MAJOR > 52) || \
97      (LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29)) && \
98     ((LIBSWSCALE_VERSION_MAJOR > 0) || \
99      (LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10))
100 #  define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
101 #endif
102 
103 #if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
104      (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR > 14))
105 #  define FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
106 #endif
107 
108 #if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
109      (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 60))
110 #  define FFMPEG_HAVE_ENCODE_AUDIO2
111 #endif
112 
113 #if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
114      (LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 42))
115 #  define FFMPEG_HAVE_DECODE_AUDIO4
116 #endif
117 
118 #if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
119      (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
120 #  define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
121 #endif
122 
123 #if ((LIBAVUTIL_VERSION_MAJOR > 51) || \
124      (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 21))
125 #  define FFMPEG_FFV1_ALPHA_SUPPORTED
126 #  define FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
127 #else
128 
129 FFMPEG_INLINE
av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)130 int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
131 {
132   /* no planar formats in FFmpeg < 0.9 */
133   (void)sample_fmt;
134   return 0;
135 }
136 
137 #endif
138 
139 /* XXX TODO Probably fix to correct modern flags in code? Not sure how old FFMPEG we want to
140  * support though, so for now this will do. */
141 
142 #ifndef FF_MIN_BUFFER_SIZE
143 #  ifdef AV_INPUT_BUFFER_MIN_SIZE
144 #    define FF_MIN_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
145 #  endif
146 #endif
147 
148 #ifndef FF_INPUT_BUFFER_PADDING_SIZE
149 #  ifdef AV_INPUT_BUFFER_PADDING_SIZE
150 #    define FF_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
151 #  endif
152 #endif
153 
154 #ifndef CODEC_FLAG_GLOBAL_HEADER
155 #  ifdef AV_CODEC_FLAG_GLOBAL_HEADER
156 #    define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
157 #  endif
158 #endif
159 
160 #ifndef CODEC_FLAG_GLOBAL_HEADER
161 #  ifdef AV_CODEC_FLAG_GLOBAL_HEADER
162 #    define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
163 #  endif
164 #endif
165 
166 #ifndef CODEC_FLAG_INTERLACED_DCT
167 #  ifdef AV_CODEC_FLAG_INTERLACED_DCT
168 #    define CODEC_FLAG_INTERLACED_DCT AV_CODEC_FLAG_INTERLACED_DCT
169 #  endif
170 #endif
171 
172 #ifndef CODEC_FLAG_INTERLACED_ME
173 #  ifdef AV_CODEC_FLAG_INTERLACED_ME
174 #    define CODEC_FLAG_INTERLACED_ME AV_CODEC_FLAG_INTERLACED_ME
175 #  endif
176 #endif
177 
178 /* FFmpeg upstream 1.0 is the first who added AV_ prefix. */
179 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
180 #  define AV_CODEC_ID_NONE CODEC_ID_NONE
181 #  define AV_CODEC_ID_MPEG4 CODEC_ID_MPEG4
182 #  define AV_CODEC_ID_MJPEG CODEC_ID_MJPEG
183 #  define AV_CODEC_ID_DNXHD CODEC_ID_DNXHD
184 #  define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
185 #  define AV_CODEC_ID_MPEG1VIDEO CODEC_ID_MPEG1VIDEO
186 #  define AV_CODEC_ID_DVVIDEO CODEC_ID_DVVIDEO
187 #  define AV_CODEC_ID_THEORA CODEC_ID_THEORA
188 #  define AV_CODEC_ID_PNG CODEC_ID_PNG
189 #  define AV_CODEC_ID_QTRLE CODEC_ID_QTRLE
190 #  define AV_CODEC_ID_FFV1 CODEC_ID_FFV1
191 #  define AV_CODEC_ID_HUFFYUV CODEC_ID_HUFFYUV
192 #  define AV_CODEC_ID_H264 CODEC_ID_H264
193 #  define AV_CODEC_ID_FLV1 CODEC_ID_FLV1
194 
195 #  define AV_CODEC_ID_AAC CODEC_ID_AAC
196 #  define AV_CODEC_ID_AC3 CODEC_ID_AC3
197 #  define AV_CODEC_ID_MP3 CODEC_ID_MP3
198 #  define AV_CODEC_ID_MP2 CODEC_ID_MP2
199 #  define AV_CODEC_ID_FLAC CODEC_ID_FLAC
200 #  define AV_CODEC_ID_PCM_U8 CODEC_ID_PCM_U8
201 #  define AV_CODEC_ID_PCM_S16LE CODEC_ID_PCM_S16LE
202 #  define AV_CODEC_ID_PCM_S24LE CODEC_ID_PCM_S24LE
203 #  define AV_CODEC_ID_PCM_S32LE CODEC_ID_PCM_S32LE
204 #  define AV_CODEC_ID_PCM_F32LE CODEC_ID_PCM_F32LE
205 #  define AV_CODEC_ID_PCM_F64LE CODEC_ID_PCM_F64LE
206 #  define AV_CODEC_ID_VORBIS CODEC_ID_VORBIS
207 #endif
208 
209 FFMPEG_INLINE
av_get_cropped_height_from_codec(AVCodecContext * pCodecCtx)210 int av_get_cropped_height_from_codec(AVCodecContext *pCodecCtx)
211 {
212   int y = pCodecCtx->height;
213 
214 #ifndef FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
215   /* really bad hack to remove this dreadfull black bar at the bottom
216    with Canon footage and old ffmpeg versions.
217    (to fix this properly in older ffmpeg versions one has to write a new
218    demuxer...)
219 
220    see the actual fix here for reference:
221 
222    http://git.libav.org/?p=libav.git;a=commit;h=30f515091c323da59c0f1b533703dedca2f4b95d
223 
224    We do our best to apply this only to matching footage.
225 */
226   if (pCodecCtx->width == 1920 && pCodecCtx->height == 1088 &&
227       pCodecCtx->pix_fmt == PIX_FMT_YUVJ420P && pCodecCtx->codec_id == AV_CODEC_ID_H264) {
228     y = 1080;
229   }
230 #endif
231 
232   return y;
233 }
234 
235 #if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
236      (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
237 FFMPEG_INLINE
av_opt_set(void * obj,const char * name,const char * val,int search_flags)238 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
239 {
240   const AVOption *rv = NULL;
241   (void)search_flags;
242   av_set_string3(obj, name, val, 1, &rv);
243   return rv != NULL;
244 }
245 
246 FFMPEG_INLINE
av_opt_set_int(void * obj,const char * name,int64_t val,int search_flags)247 int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
248 {
249   const AVOption *rv = NULL;
250   (void)search_flags;
251   rv = av_set_int(obj, name, val);
252   return rv != NULL;
253 }
254 
255 FFMPEG_INLINE
av_opt_set_double(void * obj,const char * name,double val,int search_flags)256 int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
257 {
258   const AVOption *rv = NULL;
259   (void)search_flags;
260   rv = av_set_double(obj, name, val);
261   return rv != NULL;
262 }
263 
264 #  define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
265 #  define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
266 #  define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
267 #  define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
268 #  define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
269 #  define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
270 #endif
271 
272 #if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
273      (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54))
274 FFMPEG_INLINE
av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)275 enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
276 {
277   if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
278     return AV_SAMPLE_FMT_NONE;
279   return sample_fmt;
280 }
281 #endif
282 
283 #if ((LIBAVCODEC_VERSION_MAJOR < 53) || \
284      (LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
285 FFMPEG_INLINE
avcodec_open2(AVCodecContext * avctx,AVCodec * codec,AVDictionary ** options)286 int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
287 {
288   /* TODO: no options are taking into account */
289   (void)options;
290   return avcodec_open(avctx, codec);
291 }
292 #endif
293 
294 #if ((LIBAVFORMAT_VERSION_MAJOR < 53) || \
295      (LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 21))
296 FFMPEG_INLINE
avformat_new_stream(AVFormatContext * s,AVCodec * c)297 AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
298 {
299   /* TODO: no codec is taking into account */
300   (void)c;
301   return av_new_stream(s, 0);
302 }
303 
304 FFMPEG_INLINE
avformat_find_stream_info(AVFormatContext * ic,AVDictionary ** options)305 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
306 {
307   /* TODO: no options are taking into account */
308   (void)options;
309   return av_find_stream_info(ic);
310 }
311 #endif
312 
313 #if ((LIBAVFORMAT_VERSION_MAJOR > 53) || \
314      ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || \
315      ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && \
316       (LIBAVFORMAT_VERSION_MICRO >= 100)))
317 FFMPEG_INLINE
my_update_cur_dts(AVFormatContext * s,AVStream * ref_st,int64_t timestamp)318 void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
319 {
320   int i;
321 
322   for (i = 0; i < s->nb_streams; i++) {
323     AVStream *st = s->streams[i];
324 
325     st->cur_dts = av_rescale(timestamp,
326                              st->time_base.den * (int64_t)ref_st->time_base.num,
327                              st->time_base.num * (int64_t)ref_st->time_base.den);
328   }
329 }
330 
331 FFMPEG_INLINE
av_update_cur_dts(AVFormatContext * s,AVStream * ref_st,int64_t timestamp)332 void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
333 {
334   my_update_cur_dts(s, ref_st, timestamp);
335 }
336 #endif
337 
338 #if ((LIBAVCODEC_VERSION_MAJOR < 54) || \
339      (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 28))
340 FFMPEG_INLINE
avcodec_free_frame(AVFrame ** frame)341 void avcodec_free_frame(AVFrame **frame)
342 {
343   /* don't need to do anything with old AVFrame
344    * since it does not have malloced members */
345   (void)frame;
346 }
347 #endif
348 
349 #if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
350      (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
351 #  define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
352 #endif
353 
354 #if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
355      (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR >= 13))
356 #  define FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
357 #endif
358 
359 #ifndef FFMPEG_HAVE_AVIO
360 #  define AVIO_FLAG_WRITE URL_WRONLY
361 #  define avio_open url_fopen
362 #  define avio_tell url_ftell
363 #  define avio_close url_fclose
364 #  define avio_size url_fsize
365 #endif
366 
367 /* There are some version in between, which have avio_... functions but no
368  * AVIO_FLAG_... */
369 #ifndef AVIO_FLAG_WRITE
370 #  define AVIO_FLAG_WRITE URL_WRONLY
371 #endif
372 
373 #ifndef AV_PKT_FLAG_KEY
374 #  define AV_PKT_FLAG_KEY PKT_FLAG_KEY
375 #endif
376 
377 #ifndef FFMPEG_HAVE_AV_DUMP_FORMAT
378 #  define av_dump_format dump_format
379 #endif
380 
381 #ifndef FFMPEG_HAVE_AV_GUESS_FORMAT
382 #  define av_guess_format guess_format
383 #endif
384 
385 #ifndef FFMPEG_HAVE_PARSE_UTILS
386 #  define av_parse_video_rate av_parse_video_frame_rate
387 #endif
388 
389 #ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION
390 #  define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val.i64
391 #  define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val.dbl
392 #else
393 #  define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val
394 #  define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val
395 #endif
396 
397 #ifndef FFMPEG_HAVE_AVMEDIA_TYPES
398 #  define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
399 #  define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
400 #endif
401 
402 #ifndef FFMPEG_HAVE_DECODE_AUDIO3
403 FFMPEG_INLINE
avcodec_decode_audio3(AVCodecContext * avctx,int16_t * samples,int * frame_size_ptr,AVPacket * avpkt)404 int avcodec_decode_audio3(AVCodecContext *avctx,
405                           int16_t *samples,
406                           int *frame_size_ptr,
407                           AVPacket *avpkt)
408 {
409   return avcodec_decode_audio2(avctx, samples, frame_size_ptr, avpkt->data, avpkt->size);
410 }
411 #endif
412 
413 #ifndef FFMPEG_HAVE_DECODE_VIDEO2
414 FFMPEG_INLINE
avcodec_decode_video2(AVCodecContext * avctx,AVFrame * picture,int * got_picture_ptr,AVPacket * avpkt)415 int avcodec_decode_video2(AVCodecContext *avctx,
416                           AVFrame *picture,
417                           int *got_picture_ptr,
418                           AVPacket *avpkt)
419 {
420   return avcodec_decode_video(avctx, picture, got_picture_ptr, avpkt->data, avpkt->size);
421 }
422 #endif
423 
424 FFMPEG_INLINE
av_get_pts_from_frame(AVFormatContext * avctx,AVFrame * picture)425 int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame *picture)
426 {
427   int64_t pts;
428 #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 34, 100)
429   pts = picture->pts;
430 #else
431   pts = picture->pkt_pts;
432 #endif
433 
434   if (pts == AV_NOPTS_VALUE) {
435     pts = picture->pkt_dts;
436   }
437   if (pts == AV_NOPTS_VALUE) {
438     pts = 0;
439   }
440 
441   (void)avctx;
442   return pts;
443 }
444 
445 /* obsolete constant formerly defined in FFMpeg libavcodec/avcodec.h */
446 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
447 #  define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000  // 1 second of 48khz 32bit audio
448 #endif
449 
450 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 1, 0)
451 FFMPEG_INLINE
avcodec_encode_video2(AVCodecContext * avctx,AVPacket * pkt,const AVFrame * frame,int * got_output)452 int avcodec_encode_video2(AVCodecContext *avctx,
453                           AVPacket *pkt,
454                           const AVFrame *frame,
455                           int *got_output)
456 {
457   int outsize, ret;
458 
459   ret = av_new_packet(pkt, avctx->width * avctx->height * 7 + 10000);
460   if (ret < 0)
461     return ret;
462 
463   outsize = avcodec_encode_video(avctx, pkt->data, pkt->size, frame);
464   if (outsize <= 0) {
465     *got_output = 0;
466     av_free_packet(pkt);
467   }
468   else {
469     *got_output = 1;
470     av_shrink_packet(pkt, outsize);
471     if (avctx->coded_frame) {
472       pkt->pts = avctx->coded_frame->pts;
473       if (avctx->coded_frame->key_frame)
474         pkt->flags |= AV_PKT_FLAG_KEY;
475     }
476   }
477 
478   return outsize >= 0 ? 0 : outsize;
479 }
480 
481 #endif
482 
483 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 17, 0)
484 FFMPEG_INLINE
avformat_close_input(AVFormatContext ** ctx)485 void avformat_close_input(AVFormatContext **ctx)
486 {
487   av_close_input_file(*ctx);
488   *ctx = NULL;
489 }
490 #endif
491 
492 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 8, 0)
493 FFMPEG_INLINE
av_frame_alloc(void)494 AVFrame *av_frame_alloc(void)
495 {
496   return avcodec_alloc_frame();
497 }
498 
499 FFMPEG_INLINE
av_frame_free(AVFrame ** frame)500 void av_frame_free(AVFrame **frame)
501 {
502   av_freep(frame);
503 }
504 #endif
505 
506 FFMPEG_INLINE
av_get_metadata_key_value(AVDictionary * metadata,const char * key)507 const char *av_get_metadata_key_value(AVDictionary *metadata, const char *key)
508 {
509   if (metadata == NULL) {
510     return NULL;
511   }
512   AVDictionaryEntry *tag = NULL;
513   while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
514     if (!strcmp(tag->key, key)) {
515       return tag->value;
516     }
517   }
518   return NULL;
519 }
520 
521 FFMPEG_INLINE
av_check_encoded_with_ffmpeg(AVFormatContext * ctx)522 bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx)
523 {
524   const char *encoder = av_get_metadata_key_value(ctx->metadata, "ENCODER");
525   if (encoder != NULL && !strncmp(encoder, "Lavf", 4)) {
526     return true;
527   }
528   return false;
529 }
530 
531 /* Libav doesn't have av_guess_frame_rate().
532  * It was introduced in FFmpeg's lavf 55.1.100. */
533 #ifdef AV_USING_LIBAV
av_guess_frame_rate(AVFormatContext * ctx,AVStream * stream,AVFrame * frame)534 AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame)
535 {
536   (void)ctx;
537   (void)frame;
538 #  if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1)
539   /* For until r_frame_rate was deprecated (in Libav) use it. */
540   return stream->r_frame_rate;
541 #  else
542   return stream->avg_frame_rate;
543 #  endif
544 }
545 #endif
546 
547 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 32, 0)
548 #  define AV_OPT_SEARCH_FAKE_OBJ 0
549 #endif
550 
551 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
552 #  define FFMPEG_HAVE_DEPRECATED_FLAGS2
553 #endif
554 
555 /* Since FFmpeg-1.1 this constant have AV_ prefix. */
556 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 3, 100)
557 #  define AV_PIX_FMT_BGR32 PIX_FMT_BGR32
558 #  define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
559 #  define AV_PIX_FMT_BGRA PIX_FMT_BGRA
560 #  define AV_PIX_FMT_ARGB PIX_FMT_ARGB
561 #  define AV_PIX_FMT_RGBA PIX_FMT_RGBA
562 #endif
563 
564 /* New API from FFmpeg-2.0 which soon became recommended one. */
565 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 38, 100)
566 #  define av_frame_alloc avcodec_alloc_frame
567 #  define av_frame_free avcodec_free_frame
568 #  define av_frame_unref avcodec_get_frame_defaults
569 #endif
570 
571 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 102)
572 
573 /* NOTE: The code in this block are from FFmpeg 2.6.4, which is licensed by LGPL. */
574 
575 #  define MAX_NEG_CROP 1024
576 
577 #  define times4(x) x, x, x, x
578 #  define times256(x) times4(times4(times4(times4(times4(x)))))
579 
580 static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
581     times256(0x00), 0x00, 0x01, 0x02, 0x03, 0x04,          0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
582     0x0B,           0x0C, 0x0D, 0x0E, 0x0F, 0x10,          0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
583     0x17,           0x18, 0x19, 0x1A, 0x1B, 0x1C,          0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
584     0x23,           0x24, 0x25, 0x26, 0x27, 0x28,          0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
585     0x2F,           0x30, 0x31, 0x32, 0x33, 0x34,          0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
586     0x3B,           0x3C, 0x3D, 0x3E, 0x3F, 0x40,          0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
587     0x47,           0x48, 0x49, 0x4A, 0x4B, 0x4C,          0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
588     0x53,           0x54, 0x55, 0x56, 0x57, 0x58,          0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
589     0x5F,           0x60, 0x61, 0x62, 0x63, 0x64,          0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
590     0x6B,           0x6C, 0x6D, 0x6E, 0x6F, 0x70,          0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
591     0x77,           0x78, 0x79, 0x7A, 0x7B, 0x7C,          0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
592     0x83,           0x84, 0x85, 0x86, 0x87, 0x88,          0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
593     0x8F,           0x90, 0x91, 0x92, 0x93, 0x94,          0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
594     0x9B,           0x9C, 0x9D, 0x9E, 0x9F, 0xA0,          0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
595     0xA7,           0xA8, 0xA9, 0xAA, 0xAB, 0xAC,          0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
596     0xB3,           0xB4, 0xB5, 0xB6, 0xB7, 0xB8,          0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
597     0xBF,           0xC0, 0xC1, 0xC2, 0xC3, 0xC4,          0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
598     0xCB,           0xCC, 0xCD, 0xCE, 0xCF, 0xD0,          0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
599     0xD7,           0xD8, 0xD9, 0xDA, 0xDB, 0xDC,          0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
600     0xE3,           0xE4, 0xE5, 0xE6, 0xE7, 0xE8,          0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
601     0xEF,           0xF0, 0xF1, 0xF2, 0xF3, 0xF4,          0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
602     0xFB,           0xFC, 0xFD, 0xFE, 0xFF, times256(0xFF)};
603 
604 #  undef times4
605 #  undef times256
606 
607 /* filter parameters: [-1 4 2 4 -1] // 8 */
608 FFMPEG_INLINE
deinterlace_line(uint8_t * dst,const uint8_t * lum_m4,const uint8_t * lum_m3,const uint8_t * lum_m2,const uint8_t * lum_m1,const uint8_t * lum,int size)609 void deinterlace_line(uint8_t *dst,
610                       const uint8_t *lum_m4,
611                       const uint8_t *lum_m3,
612                       const uint8_t *lum_m2,
613                       const uint8_t *lum_m1,
614                       const uint8_t *lum,
615                       int size)
616 {
617   const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
618   int sum;
619 
620   for (; size > 0; size--) {
621     sum = -lum_m4[0];
622     sum += lum_m3[0] << 2;
623     sum += lum_m2[0] << 1;
624     sum += lum_m1[0] << 2;
625     sum += -lum[0];
626     dst[0] = cm[(sum + 4) >> 3];
627     lum_m4++;
628     lum_m3++;
629     lum_m2++;
630     lum_m1++;
631     lum++;
632     dst++;
633   }
634 }
635 
636 FFMPEG_INLINE
deinterlace_line_inplace(uint8_t * lum_m4,uint8_t * lum_m3,uint8_t * lum_m2,uint8_t * lum_m1,uint8_t * lum,int size)637 void deinterlace_line_inplace(
638     uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size)
639 {
640   const uint8_t *cm = ff_compat_crop_tab + MAX_NEG_CROP;
641   int sum;
642 
643   for (; size > 0; size--) {
644     sum = -lum_m4[0];
645     sum += lum_m3[0] << 2;
646     sum += lum_m2[0] << 1;
647     lum_m4[0] = lum_m2[0];
648     sum += lum_m1[0] << 2;
649     sum += -lum[0];
650     lum_m2[0] = cm[(sum + 4) >> 3];
651     lum_m4++;
652     lum_m3++;
653     lum_m2++;
654     lum_m1++;
655     lum++;
656   }
657 }
658 
659 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
660    top field is copied as is, but the bottom field is deinterlaced
661    against the top field. */
662 FFMPEG_INLINE
deinterlace_bottom_field(uint8_t * dst,int dst_wrap,const uint8_t * src1,int src_wrap,int width,int height)663 void deinterlace_bottom_field(
664     uint8_t *dst, int dst_wrap, const uint8_t *src1, int src_wrap, int width, int height)
665 {
666   const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
667   int y;
668 
669   src_m2 = src1;
670   src_m1 = src1;
671   src_0 = &src_m1[src_wrap];
672   src_p1 = &src_0[src_wrap];
673   src_p2 = &src_p1[src_wrap];
674   for (y = 0; y < (height - 2); y += 2) {
675     memcpy(dst, src_m1, width);
676     dst += dst_wrap;
677     deinterlace_line(dst, src_m2, src_m1, src_0, src_p1, src_p2, width);
678     src_m2 = src_0;
679     src_m1 = src_p1;
680     src_0 = src_p2;
681     src_p1 += 2 * src_wrap;
682     src_p2 += 2 * src_wrap;
683     dst += dst_wrap;
684   }
685   memcpy(dst, src_m1, width);
686   dst += dst_wrap;
687   /* do last line */
688   deinterlace_line(dst, src_m2, src_m1, src_0, src_0, src_0, width);
689 }
690 
691 FFMPEG_INLINE
deinterlace_bottom_field_inplace(uint8_t * src1,int src_wrap,int width,int height)692 int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int height)
693 {
694   uint8_t *src_m1, *src_0, *src_p1, *src_p2;
695   int y;
696   uint8_t *buf = (uint8_t *)av_malloc(width);
697   if (!buf)
698     return AVERROR(ENOMEM);
699 
700   src_m1 = src1;
701   memcpy(buf, src_m1, width);
702   src_0 = &src_m1[src_wrap];
703   src_p1 = &src_0[src_wrap];
704   src_p2 = &src_p1[src_wrap];
705   for (y = 0; y < (height - 2); y += 2) {
706     deinterlace_line_inplace(buf, src_m1, src_0, src_p1, src_p2, width);
707     src_m1 = src_p1;
708     src_0 = src_p2;
709     src_p1 += 2 * src_wrap;
710     src_p2 += 2 * src_wrap;
711   }
712   /* do last line */
713   deinterlace_line_inplace(buf, src_m1, src_0, src_0, src_0, width);
714   av_free(buf);
715   return 0;
716 }
717 
718 #  ifdef __GNUC__
719 #    pragma GCC diagnostic push
720 #    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
721 #  endif
722 
723 FFMPEG_INLINE
avpicture_deinterlace(AVPicture * dst,const AVPicture * src,enum AVPixelFormat pix_fmt,int width,int height)724 int avpicture_deinterlace(
725     AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height)
726 {
727   int i, ret;
728 
729   if (pix_fmt != AV_PIX_FMT_YUV420P && pix_fmt != AV_PIX_FMT_YUVJ420P &&
730       pix_fmt != AV_PIX_FMT_YUV422P && pix_fmt != AV_PIX_FMT_YUVJ422P &&
731       pix_fmt != AV_PIX_FMT_YUV444P && pix_fmt != AV_PIX_FMT_YUV411P &&
732       pix_fmt != AV_PIX_FMT_GRAY8)
733     return -1;
734   if ((width & 3) != 0 || (height & 3) != 0)
735     return -1;
736 
737   for (i = 0; i < 3; i++) {
738     if (i == 1) {
739       switch (pix_fmt) {
740         case AV_PIX_FMT_YUVJ420P:
741         case AV_PIX_FMT_YUV420P:
742           width >>= 1;
743           height >>= 1;
744           break;
745         case AV_PIX_FMT_YUV422P:
746         case AV_PIX_FMT_YUVJ422P:
747           width >>= 1;
748           break;
749         case AV_PIX_FMT_YUV411P:
750           width >>= 2;
751           break;
752         default:
753           break;
754       }
755       if (pix_fmt == AV_PIX_FMT_GRAY8) {
756         break;
757       }
758     }
759     if (src == dst) {
760       ret = deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], width, height);
761       if (ret < 0)
762         return ret;
763     }
764     else {
765       deinterlace_bottom_field(
766           dst->data[i], dst->linesize[i], src->data[i], src->linesize[i], width, height);
767     }
768   }
769   return 0;
770 }
771 
772 #  ifdef __GNUC__
773 #    pragma GCC diagnostic pop
774 #  endif
775 
776 #endif
777 
778 #endif
779