Blender  V2.93
ffmpeg_compat.h
Go to the documentation of this file.
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 if our ffmpeg is new enough, avoids user complaints.
26  * Minimum supported version is currently 3.2.0 which mean the following library versions:
27  * libavutil > 55.30
28  * libavcodec > 57.60
29  * libavformat > 57.50
30  *
31  * We only check for one of these as they are usually updated in tandem.
32  */
33 #if (LIBAVFORMAT_VERSION_MAJOR < 57) || \
34  ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR <= 50))
35 # error "FFmpeg 3.2.0 or newer is needed, Upgrade your FFmpeg or disable it"
36 #endif
37 /* end sanity check */
38 
39 /* visual studio 2012 does not define inline for C */
40 #ifdef _MSC_VER
41 # define FFMPEG_INLINE static __inline
42 #else
43 # define FFMPEG_INLINE static inline
44 #endif
45 
46 #if (LIBAVFORMAT_VERSION_MAJOR < 58) || \
47  ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR < 76))
48 # define FFMPEG_USE_DURATION_WORKAROUND 1
49 
50 /* Before ffmpeg 4.4, package duration calculation used depricated variables to calculate the
51  * packet duration. Use the function from commit
52  * github.com/FFmpeg/FFmpeg/commit/1c0885334dda9ee8652e60c586fa2e3674056586
53  * to calculate the correct framerate for ffmpeg < 4.4.
54  */
55 
57 void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
58 {
59  if (pkt->duration < 0 && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
60  av_log(s,
61  AV_LOG_WARNING,
62  "Packet with invalid duration %" PRId64 " in stream %d\n",
63  pkt->duration,
64  pkt->stream_index);
65  pkt->duration = 0;
66  }
67 
68  if (pkt->duration) {
69  return;
70  }
71 
72  switch (st->codecpar->codec_type) {
73  case AVMEDIA_TYPE_VIDEO:
74  if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0) {
75  pkt->duration = av_rescale_q(1, av_inv_q(st->avg_frame_rate), st->time_base);
76  }
77  else if (st->time_base.num * 1000LL > st->time_base.den) {
78  pkt->duration = 1;
79  }
80  break;
81  case AVMEDIA_TYPE_AUDIO: {
82  int frame_size = av_get_audio_frame_duration2(st->codecpar, pkt->size);
83  if (frame_size && st->codecpar->sample_rate) {
84  pkt->duration = av_rescale_q(
85  frame_size, (AVRational){1, st->codecpar->sample_rate}, st->time_base);
86  }
87  break;
88  }
89  default:
90  break;
91  }
92 }
93 #endif
94 
97 {
98  /* Some videos do not have any pts values, use dts instead in those cases if
99  * possible. Usually when this happens dts can act as pts because as all frames
100  * should then be presented in their decoded in order. IE pts == dts. */
101  if (pts == AV_NOPTS_VALUE) {
102  return dts;
103  }
104  return pts;
105 }
106 
109 {
110  return timestamp_from_pts_or_dts(picture->pts, picture->pkt_dts);
111 }
112 
113 /* -------------------------------------------------------------------- */
119 #define MAX_NEG_CROP 1024
120 
121 #define times4(x) x, x, x, x
122 #define times256(x) times4(times4(times4(times4(times4(x)))))
123 
124 static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
125  times256(0x00), 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
126  0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
127  0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
128  0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E,
129  0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
130  0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
131  0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
132  0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
133  0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
134  0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
135  0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82,
136  0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
137  0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
138  0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
139  0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
140  0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
141  0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
142  0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
143  0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2,
144  0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
145  0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
146  0xFB, 0xFC, 0xFD, 0xFE, 0xFF, times256(0xFF)};
147 
148 #undef times4
149 #undef times256
150 
151 /* filter parameters: [-1 4 2 4 -1] // 8 */
154  const uint8_t *lum_m4,
155  const uint8_t *lum_m3,
156  const uint8_t *lum_m2,
157  const uint8_t *lum_m1,
158  const uint8_t *lum,
159  int size)
160 {
162  int sum;
163 
164  for (; size > 0; size--) {
165  sum = -lum_m4[0];
166  sum += lum_m3[0] << 2;
167  sum += lum_m2[0] << 1;
168  sum += lum_m1[0] << 2;
169  sum += -lum[0];
170  dst[0] = cm[(sum + 4) >> 3];
171  lum_m4++;
172  lum_m3++;
173  lum_m2++;
174  lum_m1++;
175  lum++;
176  dst++;
177  }
178 }
179 
182  uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size)
183 {
185  int sum;
186 
187  for (; size > 0; size--) {
188  sum = -lum_m4[0];
189  sum += lum_m3[0] << 2;
190  sum += lum_m2[0] << 1;
191  lum_m4[0] = lum_m2[0];
192  sum += lum_m1[0] << 2;
193  sum += -lum[0];
194  lum_m2[0] = cm[(sum + 4) >> 3];
195  lum_m4++;
196  lum_m3++;
197  lum_m2++;
198  lum_m1++;
199  lum++;
200  }
201 }
202 
203 /* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The
204  top field is copied as is, but the bottom field is deinterlaced
205  against the top field. */
208  uint8_t *dst, int dst_wrap, const uint8_t *src1, int src_wrap, int width, int height)
209 {
210  const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
211  int y;
212 
213  src_m2 = src1;
214  src_m1 = src1;
215  src_0 = &src_m1[src_wrap];
216  src_p1 = &src_0[src_wrap];
217  src_p2 = &src_p1[src_wrap];
218  for (y = 0; y < (height - 2); y += 2) {
219  memcpy(dst, src_m1, width);
220  dst += dst_wrap;
221  deinterlace_line(dst, src_m2, src_m1, src_0, src_p1, src_p2, width);
222  src_m2 = src_0;
223  src_m1 = src_p1;
224  src_0 = src_p2;
225  src_p1 += 2 * src_wrap;
226  src_p2 += 2 * src_wrap;
227  dst += dst_wrap;
228  }
229  memcpy(dst, src_m1, width);
230  dst += dst_wrap;
231  /* do last line */
232  deinterlace_line(dst, src_m2, src_m1, src_0, src_0, src_0, width);
233 }
234 
236 int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int height)
237 {
238  uint8_t *src_m1, *src_0, *src_p1, *src_p2;
239  int y;
240  uint8_t *buf = (uint8_t *)av_malloc(width);
241  if (!buf) {
242  return AVERROR(ENOMEM);
243  }
244 
245  src_m1 = src1;
246  memcpy(buf, src_m1, width);
247  src_0 = &src_m1[src_wrap];
248  src_p1 = &src_0[src_wrap];
249  src_p2 = &src_p1[src_wrap];
250  for (y = 0; y < (height - 2); y += 2) {
251  deinterlace_line_inplace(buf, src_m1, src_0, src_p1, src_p2, width);
252  src_m1 = src_p1;
253  src_0 = src_p2;
254  src_p1 += 2 * src_wrap;
255  src_p2 += 2 * src_wrap;
256  }
257  /* do last line */
258  deinterlace_line_inplace(buf, src_m1, src_0, src_0, src_0, width);
259  av_free(buf);
260  return 0;
261 }
262 
265  AVFrame *dst, const AVFrame *src, enum AVPixelFormat pix_fmt, int width, int height)
266 {
267  int i, ret;
268 
269  if (pix_fmt != AV_PIX_FMT_YUV420P && pix_fmt != AV_PIX_FMT_YUVJ420P &&
270  pix_fmt != AV_PIX_FMT_YUV422P && pix_fmt != AV_PIX_FMT_YUVJ422P &&
271  pix_fmt != AV_PIX_FMT_YUV444P && pix_fmt != AV_PIX_FMT_YUV411P &&
272  pix_fmt != AV_PIX_FMT_GRAY8) {
273  return -1;
274  }
275  if ((width & 3) != 0 || (height & 3) != 0) {
276  return -1;
277  }
278 
279  for (i = 0; i < 3; i++) {
280  if (i == 1) {
281  switch (pix_fmt) {
282  case AV_PIX_FMT_YUVJ420P:
283  case AV_PIX_FMT_YUV420P:
284  width >>= 1;
285  height >>= 1;
286  break;
287  case AV_PIX_FMT_YUV422P:
288  case AV_PIX_FMT_YUVJ422P:
289  width >>= 1;
290  break;
291  case AV_PIX_FMT_YUV411P:
292  width >>= 2;
293  break;
294  default:
295  break;
296  }
297  if (pix_fmt == AV_PIX_FMT_GRAY8) {
298  break;
299  }
300  }
301  if (src == dst) {
302  ret = deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], width, height);
303  if (ret < 0) {
304  return ret;
305  }
306  }
307  else {
309  dst->data[i], dst->linesize[i], src->data[i], src->linesize[i], width, height);
310  }
311  }
312  return 0;
313 }
314 
315 /* --- Deinterlace code block end --- */
316 
317 #endif
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static T sum(const btAlignedObjectArray< T > &items)
FFMPEG_INLINE void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size)
static const uint8_t ff_compat_crop_tab[256+2 *MAX_NEG_CROP]
FFMPEG_INLINE int64_t timestamp_from_pts_or_dts(int64_t pts, int64_t dts)
Definition: ffmpeg_compat.h:96
#define MAX_NEG_CROP
FFMPEG_INLINE int64_t av_get_pts_from_frame(AVFrame *picture)
FFMPEG_INLINE void 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)
FFMPEG_INLINE void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, const uint8_t *src1, int src_wrap, int width, int height)
FFMPEG_INLINE int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int height)
#define times256(x)
FFMPEG_INLINE void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
Definition: ffmpeg_compat.h:57
#define FFMPEG_INLINE
Definition: ffmpeg_compat.h:43
FFMPEG_INLINE int av_image_deinterlace(AVFrame *dst, const AVFrame *src, enum AVPixelFormat pix_fmt, int width, int height)
#define PRId64
Definition: inttypes.h:81
return ret
__int64 int64_t
Definition: stdint.h:92
unsigned char uint8_t
Definition: stdint.h:81