Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2017-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common ffmpeg filters
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include <gpac/setup.h>
27 :
28 : #ifdef GPAC_HAS_FFMPEG
29 :
30 : #include "ff_common.h"
31 :
32 : #include <libavfilter/avfilter.h>
33 :
34 : #if !defined(__GNUC__)
35 : # if defined(_WIN32_WCE) || defined (WIN32)
36 : # pragma comment(lib, "avutil")
37 : # pragma comment(lib, "avformat")
38 : # pragma comment(lib, "avcodec")
39 : # pragma comment(lib, "avdevice")
40 : # pragma comment(lib, "swscale")
41 : # pragma comment(lib, "avfilter")
42 : # endif
43 : #endif
44 :
45 :
46 : static Bool ffmpeg_init = GF_FALSE;
47 :
48 : typedef struct
49 : {
50 : GF_List *all_filters;
51 : u32 nb_arg_skip;
52 : } GF_FFRegistryExt;
53 :
54 : typedef struct
55 : {
56 : u32 ff_pf;
57 : u32 gpac_pf;
58 : u32 flags; //only 1 used, for full range
59 : } GF_FF_PFREG;
60 :
61 : #ifndef FFMPEG_ENABLE_VVC
62 : //enable this when compiling under xcode or visual (eg without ./configure), or add macro to configuration.h or project settings
63 : //to remove once we have a known API version number for vvc in libavcodec
64 : //#define FFMPEG_ENABLE_VVC
65 : #endif
66 :
67 : static const GF_FF_PFREG FF2GPAC_PixelFormats[] =
68 : {
69 : {AV_PIX_FMT_YUV420P, GF_PIXEL_YUV},
70 : {AV_PIX_FMT_YUV420P10LE, GF_PIXEL_YUV_10},
71 : {AV_PIX_FMT_YUV422P, GF_PIXEL_YUV422},
72 : {AV_PIX_FMT_YUV422P10LE, GF_PIXEL_YUV422_10},
73 : {AV_PIX_FMT_YUV444P, GF_PIXEL_YUV444},
74 : {AV_PIX_FMT_YUV444P10LE, GF_PIXEL_YUV444_10},
75 : {AV_PIX_FMT_RGBA, GF_PIXEL_RGBA},
76 : {AV_PIX_FMT_RGB24, GF_PIXEL_RGB},
77 : {AV_PIX_FMT_BGR24, GF_PIXEL_BGR},
78 : {AV_PIX_FMT_UYVY422, GF_PIXEL_UYVY},
79 : {AV_PIX_FMT_YUYV422, GF_PIXEL_YUYV},
80 : //remap unsupported pix formats
81 : {AV_PIX_FMT_UYVY422, GF_PIXEL_VYUY},
82 : {AV_PIX_FMT_YUYV422, GF_PIXEL_YVYU},
83 :
84 : {AV_PIX_FMT_NV12, GF_PIXEL_NV12},
85 : #if LIBAVCODEC_VERSION_MAJOR >= 58
86 : {AV_PIX_FMT_P010LE, GF_PIXEL_NV12_10},
87 : #endif
88 : {AV_PIX_FMT_NV21, GF_PIXEL_NV21},
89 : {AV_PIX_FMT_0RGB, GF_PIXEL_XRGB},
90 : {AV_PIX_FMT_RGB0, GF_PIXEL_RGBX},
91 : {AV_PIX_FMT_0BGR, GF_PIXEL_XBGR},
92 : {AV_PIX_FMT_BGR0, GF_PIXEL_BGRX},
93 : {AV_PIX_FMT_GRAY8, GF_PIXEL_GREYSCALE},
94 : {AV_PIX_FMT_YA8, GF_PIXEL_GREYALPHA},
95 : {AV_PIX_FMT_RGB444, GF_PIXEL_RGB_444},
96 : {AV_PIX_FMT_RGB555, GF_PIXEL_RGB_555},
97 : {AV_PIX_FMT_RGB565, GF_PIXEL_RGB_565},
98 : {AV_PIX_FMT_RGBA, GF_PIXEL_RGBA},
99 : {AV_PIX_FMT_ARGB, GF_PIXEL_ARGB},
100 : {AV_PIX_FMT_ABGR, GF_PIXEL_ABGR},
101 : {AV_PIX_FMT_BGRA, GF_PIXEL_BGRA},
102 :
103 : /*aliases*/
104 : {AV_PIX_FMT_YUVJ420P, GF_PIXEL_YUV, 1},
105 : {AV_PIX_FMT_YUVJ422P, GF_PIXEL_YUV422, 1},
106 : {AV_PIX_FMT_YUVJ444P, GF_PIXEL_YUV444, 1},
107 : {0},
108 : };
109 :
110 256 : u32 ffmpeg_pixfmt_from_gpac(u32 pfmt)
111 : {
112 : u32 i=0;
113 1532 : while (FF2GPAC_PixelFormats[i].gpac_pf) {
114 1276 : if (FF2GPAC_PixelFormats[i].gpac_pf == pfmt)
115 256 : return FF2GPAC_PixelFormats[i].ff_pf;
116 1020 : i++;
117 : }
118 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[FFMPEG] Unmapped GPAC pixel format %s, patch welcome\n", gf_4cc_to_str(pfmt) ));
119 : return 0;
120 : }
121 :
122 48 : u32 ffmpeg_pixfmt_to_gpac(u32 pfmt)
123 : {
124 48 : const AVPixFmtDescriptor *ffdesc = av_pix_fmt_desc_get(pfmt);
125 48 : if (!ffdesc) {
126 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[FFMPEG] Unrecognized FFMPEG pixel format %d\n", pfmt ));
127 : return 0;
128 : }
129 : u32 i=0;
130 558 : while (FF2GPAC_PixelFormats[i].gpac_pf) {
131 558 : if (FF2GPAC_PixelFormats[i].ff_pf == pfmt)
132 : return FF2GPAC_PixelFormats[i].gpac_pf;
133 510 : i++;
134 : }
135 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[FFMPEG] Unmapped FFMPEG pixel format %s, patch welcome\n", ffdesc->name));
136 : return 0;
137 : }
138 :
139 125 : Bool ffmpeg_pixfmt_is_fullrange(u32 pfmt)
140 : {
141 : u32 i=0;
142 3393 : while (FF2GPAC_PixelFormats[i].gpac_pf) {
143 3169 : if (FF2GPAC_PixelFormats[i].ff_pf == pfmt)
144 26 : return (FF2GPAC_PixelFormats[i].flags & 1) ? GF_TRUE : GF_FALSE;
145 3143 : i++;
146 : }
147 : return GF_FALSE;
148 : }
149 :
150 0 : u32 ffmpeg_pixfmt_from_codec_tag(u32 codec_tag, Bool *is_full_range)
151 : {
152 : u32 i=0;
153 0 : if (is_full_range) *is_full_range = 0;
154 :
155 0 : while (FF2GPAC_PixelFormats[i].gpac_pf) {
156 0 : if (avcodec_pix_fmt_to_codec_tag(FF2GPAC_PixelFormats[i].ff_pf) == codec_tag) {
157 0 : if (is_full_range && (FF2GPAC_PixelFormats[i].flags & 1)) {
158 0 : *is_full_range = GF_TRUE;
159 : }
160 : return FF2GPAC_PixelFormats[i].gpac_pf;
161 : }
162 0 : i++;
163 : }
164 : return 0;
165 : }
166 :
167 :
168 : typedef struct
169 : {
170 : u32 ff_sf;
171 : u32 gpac_sf;
172 : } GF_FF_AFREG;
173 :
174 : static const GF_FF_AFREG FF2GPAC_AudioFormats[] =
175 : {
176 : {AV_SAMPLE_FMT_U8, GF_AUDIO_FMT_U8},
177 : {AV_SAMPLE_FMT_S16, GF_AUDIO_FMT_S16},
178 : {AV_SAMPLE_FMT_S32, GF_AUDIO_FMT_S32},
179 : {AV_SAMPLE_FMT_FLT, GF_AUDIO_FMT_FLT},
180 : {AV_SAMPLE_FMT_DBL, GF_AUDIO_FMT_DBL},
181 : {AV_SAMPLE_FMT_U8P, GF_AUDIO_FMT_U8P},
182 : {AV_SAMPLE_FMT_S16P, GF_AUDIO_FMT_S16P},
183 : {AV_SAMPLE_FMT_S32P, GF_AUDIO_FMT_S32P},
184 : {AV_SAMPLE_FMT_FLTP, GF_AUDIO_FMT_FLTP},
185 : {AV_SAMPLE_FMT_DBLP, GF_AUDIO_FMT_DBLP},
186 : {0},
187 : };
188 :
189 18 : u32 ffmpeg_audio_fmt_from_gpac(u32 sfmt)
190 : {
191 : u32 i=0;
192 124 : while (FF2GPAC_AudioFormats[i].gpac_sf) {
193 106 : if (FF2GPAC_AudioFormats[i].gpac_sf == sfmt)
194 18 : return FF2GPAC_AudioFormats[i].ff_sf;
195 88 : i++;
196 : }
197 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[FFMPEG] Unmapped GPAC audio format %s, patch welcome\n", gf_4cc_to_str(sfmt) ));
198 : return 0;
199 : }
200 :
201 39 : u32 ffmpeg_audio_fmt_to_gpac(u32 sfmt)
202 : {
203 : u32 i=0;
204 351 : while (FF2GPAC_AudioFormats[i].gpac_sf) {
205 312 : if (FF2GPAC_AudioFormats[i].ff_sf == sfmt)
206 : return FF2GPAC_AudioFormats[i].gpac_sf;
207 273 : i++;
208 : }
209 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[FFMPEG] Unmapped FFMPEG audio format %d, patch welcome\n", sfmt ));
210 : return 0;
211 : }
212 :
213 :
214 : typedef struct
215 : {
216 : u64 ff_ch_mask;
217 : u64 gpac_ch_mask;
218 : } GF_FF_LAYOUTREG;
219 :
220 : static const GF_FF_LAYOUTREG FF2GPAC_ChannelLayout[] =
221 : {
222 : {AV_CH_FRONT_LEFT, GF_AUDIO_CH_FRONT_LEFT},
223 : {AV_CH_FRONT_RIGHT, GF_AUDIO_CH_FRONT_RIGHT},
224 : {AV_CH_FRONT_CENTER, GF_AUDIO_CH_FRONT_CENTER},
225 : {AV_CH_LOW_FREQUENCY, GF_AUDIO_CH_LFE},
226 : {AV_CH_BACK_LEFT, GF_AUDIO_CH_SURROUND_LEFT},
227 : {AV_CH_BACK_RIGHT, GF_AUDIO_CH_SURROUND_RIGHT},
228 : {AV_CH_FRONT_LEFT_OF_CENTER, GF_AUDIO_CH_FRONT_CENTER_LEFT},
229 : {AV_CH_FRONT_RIGHT_OF_CENTER, GF_AUDIO_CH_FRONT_CENTER_RIGHT},
230 : {AV_CH_BACK_CENTER, GF_AUDIO_CH_REAR_CENTER},
231 : {AV_CH_SIDE_LEFT, GF_AUDIO_CH_REAR_SURROUND_LEFT},
232 : {AV_CH_SIDE_RIGHT, GF_AUDIO_CH_REAR_SURROUND_RIGHT},
233 : {AV_CH_TOP_CENTER, GF_AUDIO_CH_CENTER_SURROUND_TOP},
234 : {AV_CH_TOP_FRONT_LEFT, GF_AUDIO_CH_FRONT_TOP_LEFT},
235 : {AV_CH_TOP_FRONT_CENTER, GF_AUDIO_CH_FRONT_TOP_CENTER},
236 : {AV_CH_TOP_FRONT_RIGHT, GF_AUDIO_CH_FRONT_TOP_RIGHT},
237 : {AV_CH_TOP_BACK_LEFT, GF_AUDIO_CH_SURROUND_TOP_LEFT},
238 : {AV_CH_TOP_BACK_CENTER, GF_AUDIO_CH_REAR_CENTER_TOP},
239 : {AV_CH_TOP_BACK_RIGHT, GF_AUDIO_CH_SURROUND_TOP_RIGHT},
240 : {AV_CH_WIDE_LEFT, GF_AUDIO_CH_WIDE_FRONT_LEFT},
241 : {AV_CH_WIDE_RIGHT, GF_AUDIO_CH_WIDE_FRONT_RIGHT},
242 : {AV_CH_SURROUND_DIRECT_LEFT, GF_AUDIO_CH_SURROUND_DIRECT_LEFT},
243 : {AV_CH_SURROUND_DIRECT_RIGHT, GF_AUDIO_CH_SURROUND_DIRECT_RIGHT},
244 : {AV_CH_LOW_FREQUENCY_2, GF_AUDIO_CH_LFE2},
245 : /* {AV_CH_STEREO_LEFT, },
246 : {AV_CH_STEREO_RIGHT, },
247 : */
248 : };
249 :
250 11 : u64 ffmpeg_channel_layout_from_gpac(u64 gpac_ch_layout)
251 : {
252 : u32 i, nb_layout = sizeof(FF2GPAC_ChannelLayout) / sizeof(GF_FF_LAYOUTREG);
253 : u64 res = 0;
254 264 : for (i=0; i<nb_layout; i++) {
255 253 : if (FF2GPAC_ChannelLayout[i].gpac_ch_mask & gpac_ch_layout)
256 21 : res |= FF2GPAC_ChannelLayout[i].ff_ch_mask;
257 : }
258 11 : return res;
259 : }
260 28 : u64 ffmpeg_channel_layout_to_gpac(u64 ff_ch_layout)
261 : {
262 : u32 i, nb_layout = sizeof(FF2GPAC_ChannelLayout) / sizeof(GF_FF_LAYOUTREG);
263 : u64 res = 0;
264 672 : for (i=0; i<nb_layout; i++) {
265 644 : if (FF2GPAC_ChannelLayout[i].ff_ch_mask & ff_ch_layout)
266 53 : res |= FF2GPAC_ChannelLayout[i].gpac_ch_mask;
267 : }
268 28 : return res;
269 : }
270 :
271 :
272 : typedef struct
273 : {
274 : u32 ff_codec_id;
275 : u32 gpac_codec_id;
276 : u32 ff_codectag;
277 : } GF_FF_CIDREG;
278 :
279 : static const GF_FF_CIDREG FF2GPAC_CodecIDs[] =
280 : {
281 : {AV_CODEC_ID_MP2, GF_CODECID_MPEG_AUDIO, 0},
282 : {AV_CODEC_ID_MP3, GF_CODECID_MPEG2_PART3, 0},
283 : {AV_CODEC_ID_AAC, GF_CODECID_AAC_MPEG4, 0},
284 : {AV_CODEC_ID_AC3, GF_CODECID_AC3, 0},
285 : {AV_CODEC_ID_EAC3, GF_CODECID_EAC3, 0},
286 : {AV_CODEC_ID_AMR_NB, GF_CODECID_AMR, 0},
287 : {AV_CODEC_ID_AMR_WB, GF_CODECID_AMR_WB, 0},
288 : {AV_CODEC_ID_QCELP, GF_CODECID_QCELP, 0},
289 : {AV_CODEC_ID_EVRC, GF_CODECID_EVRC, 0},
290 : {AV_CODEC_ID_SMV, GF_CODECID_SMV, 0},
291 : {AV_CODEC_ID_VORBIS, GF_CODECID_VORBIS, 0},
292 : {AV_CODEC_ID_FLAC, GF_CODECID_FLAC, 0},
293 : {AV_CODEC_ID_SPEEX, GF_CODECID_SPEEX, 0},
294 : {AV_CODEC_ID_THEORA, GF_CODECID_THEORA, 0},
295 : {AV_CODEC_ID_MPEG4, GF_CODECID_MPEG4_PART2, 0},
296 : {AV_CODEC_ID_H264, GF_CODECID_AVC, 0},
297 : {AV_CODEC_ID_HEVC, GF_CODECID_HEVC, 0},
298 : {AV_CODEC_ID_MPEG1VIDEO, GF_CODECID_MPEG1, 0},
299 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_SIMPLE, 0},
300 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_MAIN, 0},
301 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_HIGH, 0},
302 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_SPATIAL, 0},
303 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_SNR, 0},
304 : {AV_CODEC_ID_MPEG2VIDEO, GF_CODECID_MPEG2_422, 0},
305 : {AV_CODEC_ID_H263, GF_CODECID_S263, 0},
306 : {AV_CODEC_ID_H263, GF_CODECID_H263, 0},
307 : {AV_CODEC_ID_MJPEG, GF_CODECID_JPEG, 0},
308 : {AV_CODEC_ID_PNG, GF_CODECID_PNG, 0},
309 : {AV_CODEC_ID_JPEG2000, GF_CODECID_J2K, 0},
310 : #if LIBAVCODEC_VERSION_MAJOR >= 58
311 : {AV_CODEC_ID_AV1, GF_CODECID_AV1, 0},
312 : #endif
313 : {AV_CODEC_ID_VP8, GF_CODECID_VP8, 0},
314 : {AV_CODEC_ID_VP9, GF_CODECID_VP9, 0},
315 : {AV_CODEC_ID_VC1, GF_CODECID_SMPTE_VC1, 0},
316 :
317 : {AV_CODEC_ID_OPUS, GF_CODECID_OPUS, 0},
318 :
319 :
320 : //ProRes
321 : {AV_CODEC_ID_PRORES, GF_CODECID_APCH, GF_4CC('h','c','p','a') },
322 : {AV_CODEC_ID_PRORES, GF_CODECID_APCO, GF_4CC('o','c','p','a') },
323 : {AV_CODEC_ID_PRORES, GF_CODECID_APCN, GF_4CC('n','c','p','a')},
324 : {AV_CODEC_ID_PRORES, GF_CODECID_APCS, GF_4CC('s','c','p','a')},
325 : {AV_CODEC_ID_PRORES, GF_CODECID_AP4X, GF_4CC('x','4','p','a')},
326 : {AV_CODEC_ID_PRORES, GF_CODECID_AP4H, GF_4CC('h','4','p','a')},
327 :
328 : //RAW codecs
329 : {AV_CODEC_ID_RAWVIDEO, GF_CODECID_RAW, 0},
330 : {AV_CODEC_ID_PCM_S16LE, GF_CODECID_RAW, 0},
331 : {AV_CODEC_ID_PCM_S16BE, GF_CODECID_RAW, 0},
332 : {AV_CODEC_ID_PCM_U16LE, GF_CODECID_RAW, 0},
333 : {AV_CODEC_ID_PCM_U16BE, GF_CODECID_RAW, 0},
334 : {AV_CODEC_ID_PCM_S8, GF_CODECID_RAW, 0},
335 : {AV_CODEC_ID_PCM_U8, GF_CODECID_RAW, 0},
336 : {AV_CODEC_ID_PCM_MULAW, GF_CODECID_RAW, 0},
337 : {AV_CODEC_ID_PCM_ALAW, GF_CODECID_RAW, 0},
338 : {AV_CODEC_ID_PCM_S32LE, GF_CODECID_RAW, 0},
339 : {AV_CODEC_ID_PCM_S32BE, GF_CODECID_RAW, 0},
340 : {AV_CODEC_ID_PCM_U32LE, GF_CODECID_RAW, 0},
341 : {AV_CODEC_ID_PCM_U32BE, GF_CODECID_RAW, 0},
342 : {AV_CODEC_ID_PCM_S24LE, GF_CODECID_RAW, 0},
343 : {AV_CODEC_ID_PCM_S24BE, GF_CODECID_RAW, 0},
344 : {AV_CODEC_ID_PCM_U24LE, GF_CODECID_RAW, 0},
345 : {AV_CODEC_ID_PCM_U24BE, GF_CODECID_RAW, 0},
346 : {AV_CODEC_ID_PCM_S24DAUD, GF_CODECID_RAW, 0},
347 : {AV_CODEC_ID_PCM_ZORK, GF_CODECID_RAW, 0},
348 : {AV_CODEC_ID_PCM_S16LE_PLANAR, GF_CODECID_RAW, 0},
349 : {AV_CODEC_ID_PCM_DVD, GF_CODECID_RAW, 0},
350 : {AV_CODEC_ID_PCM_F32BE, GF_CODECID_RAW, 0},
351 : {AV_CODEC_ID_PCM_F32LE, GF_CODECID_RAW, 0},
352 : {AV_CODEC_ID_PCM_F64BE, GF_CODECID_RAW, 0},
353 : {AV_CODEC_ID_PCM_F64LE, GF_CODECID_RAW, 0},
354 : {AV_CODEC_ID_PCM_BLURAY, GF_CODECID_RAW, 0},
355 : {AV_CODEC_ID_PCM_LXF, GF_CODECID_RAW, 0},
356 : {AV_CODEC_ID_S302M, GF_CODECID_RAW, 0},
357 : {AV_CODEC_ID_PCM_S8_PLANAR, GF_CODECID_RAW, 0},
358 : {AV_CODEC_ID_PCM_S24LE_PLANAR, GF_CODECID_RAW, 0},
359 : {AV_CODEC_ID_PCM_S32LE_PLANAR, GF_CODECID_RAW, 0},
360 : {AV_CODEC_ID_PCM_S16BE_PLANAR, GF_CODECID_RAW, 0},
361 : #if LIBAVCODEC_VERSION_MAJOR >= 58
362 : {AV_CODEC_ID_PCM_S64LE, GF_CODECID_RAW, 0},
363 : {AV_CODEC_ID_PCM_S64BE, GF_CODECID_RAW, 0},
364 : {AV_CODEC_ID_PCM_F16LE, GF_CODECID_RAW, 0},
365 : {AV_CODEC_ID_PCM_F24LE, GF_CODECID_RAW, 0},
366 : #endif
367 :
368 : #ifdef FFMPEG_ENABLE_VVC
369 : {AV_CODEC_ID_VVC, GF_CODECID_VVC, 0},
370 : #endif
371 :
372 : {AV_CODEC_ID_V210, GF_CODECID_V210, 0},
373 :
374 : {AV_CODEC_ID_TRUEHD, GF_CODECID_TRUEHD, 0},
375 :
376 : {0}
377 : };
378 :
379 253 : u32 ffmpeg_codecid_from_gpac(u32 codec_id, u32 *ff_codectag)
380 : {
381 : u32 i=0;
382 253 : if (ff_codectag) *ff_codectag = 0;
383 :
384 3796 : while (FF2GPAC_CodecIDs[i].gpac_codec_id) {
385 3796 : if (FF2GPAC_CodecIDs[i].gpac_codec_id == codec_id) {
386 253 : if (ff_codectag) *ff_codectag = FF2GPAC_CodecIDs[i].ff_codectag;
387 253 : return FF2GPAC_CodecIDs[i].ff_codec_id;
388 : }
389 3543 : i++;
390 : }
391 0 : GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[FFMPEG] Unmapped GPAC codec %s\n", gf_codecid_name(codec_id) ));
392 : return 0;
393 : }
394 :
395 19981 : u32 ffmpeg_codecid_to_gpac(u32 codec_id)
396 : {
397 : u32 i=0;
398 1268264 : while (FF2GPAC_CodecIDs[i].ff_codec_id) {
399 1233806 : if (FF2GPAC_CodecIDs[i].ff_codec_id == codec_id)
400 5504 : return FF2GPAC_CodecIDs[i].gpac_codec_id;
401 1228302 : i++;
402 : }
403 14477 : GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[FFMPEG] Unmapped FFMPEG codec ID %s\n", avcodec_get_name(codec_id) ));
404 : return 0;
405 : }
406 :
407 :
408 : typedef struct
409 : {
410 : u32 ff_st;
411 : u32 gpac_st;
412 : } GF_FF_ST;
413 :
414 : static const GF_FF_ST FF2GPAC_StreamTypes[] =
415 : {
416 : {AVMEDIA_TYPE_VIDEO, GF_STREAM_VISUAL},
417 : {AVMEDIA_TYPE_AUDIO, GF_STREAM_AUDIO},
418 : {AVMEDIA_TYPE_DATA, GF_STREAM_METADATA},
419 : {AVMEDIA_TYPE_SUBTITLE, GF_STREAM_TEXT},
420 : {AVMEDIA_TYPE_ATTACHMENT, GF_STREAM_METADATA},
421 : {AVMEDIA_TYPE_UNKNOWN, GF_STREAM_UNKNOWN},
422 : {0},
423 : };
424 :
425 9 : u32 ffmpeg_stream_type_from_gpac(u32 streamtype)
426 : {
427 : u32 i=0;
428 19 : while (FF2GPAC_StreamTypes[i].gpac_st) {
429 10 : if (FF2GPAC_StreamTypes[i].gpac_st == streamtype)
430 9 : return FF2GPAC_StreamTypes[i].ff_st;
431 1 : i++;
432 : }
433 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[FFMPEG] Unmapped GPAC stream type %s, assuming data\n", gf_stream_type_name(streamtype) ));
434 : return AVMEDIA_TYPE_DATA;
435 : }
436 :
437 :
438 62 : u32 ffmpeg_stream_type_to_gpac(u32 streamtype)
439 : {
440 : u32 i=0;
441 142 : while (FF2GPAC_StreamTypes[i].gpac_st) {
442 80 : if (FF2GPAC_StreamTypes[i].ff_st == streamtype)
443 : return FF2GPAC_StreamTypes[i].gpac_st;
444 18 : i++;
445 : }
446 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[FFMPEG] Unmapped FFMPEG stream type %d, assuming data\n", streamtype ));
447 : return GF_STREAM_METADATA;
448 : }
449 :
450 : //static void ff_log_callback(void *avcl, int level, const char *fmt, va_list vl) { }
451 :
452 187 : void ffmpeg_setup_logs(u32 log_class)
453 : {
454 187 : u32 level = gf_log_get_tool_level(log_class);
455 187 : switch (level) {
456 0 : case GF_LOG_DEBUG:
457 0 : av_log_set_level(AV_LOG_DEBUG);
458 0 : break;
459 2 : case GF_LOG_INFO:
460 2 : av_log_set_level(AV_LOG_INFO);
461 2 : break;
462 185 : case GF_LOG_WARNING:
463 185 : av_log_set_level(AV_LOG_WARNING);
464 185 : break;
465 0 : default:
466 0 : av_log_set_level(AV_LOG_ERROR);
467 0 : break;
468 : }
469 : // av_log_set_callback(ff_log_callback);
470 187 : }
471 :
472 14385 : void ffmpeg_initialize()
473 : {
474 14385 : if (ffmpeg_init) return;
475 2740 : av_register_all();
476 2740 : avformat_network_init();
477 2740 : ffmpeg_init = GF_TRUE;
478 : }
479 :
480 155 : static void ffmpeg_register_free(GF_FilterSession *session, GF_FilterRegister *reg)
481 : {
482 : u32 i;
483 155 : GF_FFRegistryExt *ffregext = reg->udta;
484 155 : GF_List *all_filters = ffregext->all_filters;
485 155 : u32 nb_skip_begin = ffregext->nb_arg_skip;
486 155 : gf_free(ffregext);
487 155 : reg->udta = NULL;
488 :
489 155 : if (all_filters) {
490 34300 : while (gf_list_count(all_filters)) {
491 : i=0;
492 34145 : GF_FilterRegister *f = gf_list_pop_back(all_filters);
493 34145 : if (f->caps)
494 27156 : gf_free((void *)f->caps);
495 :
496 98372 : while (f->args) {
497 74254 : GF_FilterArgs *arg = (GF_FilterArgs *) &f->args[i];
498 74254 : if (!arg || !arg->arg_name) break;
499 64227 : i++;
500 64227 : if (arg->arg_default_val) gf_free((void *) arg->arg_default_val);
501 64227 : if (arg->min_max_enum) gf_free((void *) arg->min_max_enum);
502 64227 : if (arg->flags & GF_FS_ARG_META_ALLOC) gf_free((void *) arg->arg_desc);
503 : }
504 34145 : gf_free((void *) f->args);
505 34145 : gf_free((char*) f->name);
506 34145 : gf_fs_remove_filter_register(session, f);
507 34145 : gf_free(f);
508 : }
509 155 : gf_list_del(all_filters);
510 : }
511 : i=nb_skip_begin;
512 6975 : while (reg->args) {
513 6975 : GF_FilterArgs *arg = (GF_FilterArgs *) ®->args[i];
514 6975 : if (!arg || !arg->arg_name) break;
515 6820 : i++;
516 6820 : if (arg->arg_default_val) gf_free((void *) arg->arg_default_val);
517 6820 : if (arg->min_max_enum) gf_free((void *) arg->min_max_enum);
518 6820 : if (arg->flags & GF_FS_ARG_META_ALLOC) gf_free((void *) arg->arg_desc);
519 : }
520 155 : if (reg->args) gf_free((void *) reg->args);
521 :
522 155 : }
523 :
524 132942 : GF_FilterArgs ffmpeg_arg_translate(const struct AVOption *opt)
525 : {
526 : char szDef[200];
527 : GF_FilterArgs arg;
528 : memset(&arg, 0, sizeof(GF_FilterArgs));
529 132942 : arg.arg_name = opt->name;
530 132942 : arg.arg_desc = opt->help;
531 132942 : arg.offset_in_private=-1;
532 132942 : arg.flags = GF_FS_ARG_META;
533 : if (opt->name[0] == 0)
534 : arg.flags = GF_FS_ARG_META;
535 :
536 132942 : switch (opt->type) {
537 42102 : case AV_OPT_TYPE_INT64:
538 : case AV_OPT_TYPE_INT:
539 : case AV_OPT_TYPE_CHANNEL_LAYOUT:
540 42102 : if (opt->type==AV_OPT_TYPE_INT64) arg.arg_type = GF_PROP_LSINT;
541 40921 : else if (opt->type==AV_OPT_TYPE_INT) arg.arg_type = GF_PROP_SINT;
542 31 : else arg.arg_type = GF_PROP_UINT; //channel layout, map to int
543 :
544 42102 : sprintf(szDef, LLD, opt->default_val.i64);
545 42102 : arg.arg_default_val = gf_strdup(szDef);
546 42102 : if (opt->max>=(Double) GF_INT_MAX)
547 27148 : sprintf(szDef, LLD"-I", (s64) opt->min);
548 : else
549 14954 : sprintf(szDef, LLD"-"LLD, (s64) opt->min, (s64) opt->max);
550 42102 : arg.min_max_enum = gf_strdup(szDef);
551 42102 : break;
552 : #if LIBAVCODEC_VERSION_MAJOR >= 57
553 93 : case AV_OPT_TYPE_UINT64:
554 : // case AV_OPT_TYPE_UINT:
555 93 : arg.arg_type = GF_PROP_LUINT;
556 93 : sprintf(szDef, LLU, opt->default_val.i64);
557 93 : arg.arg_default_val = gf_strdup(szDef);
558 93 : if (opt->max>=(Double) GF_INT_MAX)
559 93 : sprintf(szDef, LLU"-I", (s64) opt->min);
560 : else
561 0 : sprintf(szDef, LLU"-"LLU, (u64) opt->min, (u64) opt->max);
562 93 : arg.min_max_enum = gf_strdup(szDef);
563 93 : break;
564 10882 : case AV_OPT_TYPE_BOOL:
565 10882 : arg.arg_type = GF_PROP_BOOL;
566 10882 : arg.arg_default_val = gf_strdup(opt->default_val.i64 ? "true" : "false");
567 10882 : break;
568 : #endif
569 4402 : case AV_OPT_TYPE_FLOAT:
570 4402 : arg.arg_type = GF_PROP_FLOAT;
571 4402 : sprintf(szDef, "%g", opt->default_val.dbl);
572 4402 : arg.arg_default_val = gf_strdup(szDef);
573 4402 : break;
574 155 : case AV_OPT_TYPE_DOUBLE:
575 155 : arg.arg_type = GF_PROP_DOUBLE;
576 155 : sprintf(szDef, "%g", opt->default_val.dbl);
577 155 : arg.arg_default_val = gf_strdup(szDef);
578 155 : break;
579 1831 : case AV_OPT_TYPE_VIDEO_RATE:
580 : case AV_OPT_TYPE_RATIONAL:
581 1831 : arg.arg_type = GF_PROP_FRACTION;
582 1831 : sprintf(szDef, "%d/%d", opt->default_val.q.num, opt->default_val.q.den);
583 1831 : arg.arg_default_val = gf_strdup(szDef);
584 1831 : break;
585 6806 : case AV_OPT_TYPE_COLOR://color is a string in libavfilter
586 : case AV_OPT_TYPE_STRING:
587 : case AV_OPT_TYPE_DICT:
588 6806 : arg.arg_type = GF_PROP_STRING;
589 6806 : if (opt->default_val.str)
590 1062 : arg.arg_default_val = gf_strdup(opt->default_val.str);
591 : break;
592 1210 : case AV_OPT_TYPE_IMAGE_SIZE:
593 1210 : arg.arg_type = GF_PROP_STRING;
594 1210 : break;
595 61832 : case AV_OPT_TYPE_CONST:
596 61832 : arg.arg_type = GF_PROP_BOOL;
597 61832 : arg.arg_default_val = gf_strdup("false");
598 61832 : break;
599 2574 : case AV_OPT_TYPE_FLAGS:
600 2574 : arg.arg_type = GF_PROP_UINT;
601 2574 : sprintf(szDef, ""LLD, opt->default_val.i64);
602 2574 : arg.arg_default_val = gf_strdup(szDef);
603 2574 : break;
604 992 : case AV_OPT_TYPE_BINARY:
605 : case AV_OPT_TYPE_DURATION:
606 992 : arg.arg_type = GF_PROP_UINT;
607 992 : break;
608 31 : case AV_OPT_TYPE_SAMPLE_FMT:
609 31 : arg.arg_type = GF_PROP_UINT;
610 31 : arg.arg_default_val = gf_strdup("s16");
611 31 : arg.min_max_enum = gf_strdup("u8|s16|s32|flt|dbl|u8p|s16p|s32p|fltp|dblp");
612 31 : break;
613 32 : case AV_OPT_TYPE_PIXEL_FMT:
614 32 : arg.arg_type = GF_PROP_UINT;
615 32 : arg.arg_default_val = gf_strdup(av_get_pix_fmt_name(AV_PIX_FMT_YUV420P) );
616 : {
617 : u32 i, all_len=1, def_size=1000;
618 32 : char *enum_val = gf_malloc(sizeof(char)*def_size);
619 32 : enum_val[0] = 0;
620 11424 : for (i=0; i<AV_PIX_FMT_NB; i++) {
621 : u32 len;
622 11392 : const char *n = av_get_pix_fmt_name(i);
623 11392 : if (!n) continue;
624 :
625 6112 : len = (u32) strlen(n)+ (i ? 2 : 1);
626 6112 : if (len+all_len>def_size) {
627 32 : def_size+=1000;
628 32 : enum_val = gf_realloc(enum_val, sizeof(char)*def_size);
629 : }
630 6112 : if (i) strcat(enum_val, "|");
631 : strcat(enum_val, n);
632 6112 : all_len+=len-1;
633 : }
634 32 : arg.min_max_enum = enum_val;
635 : }
636 32 : break;
637 0 : default:
638 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[FFMPEG] Unknown ffmpeg option type %d\n", opt->type));
639 : break;
640 : }
641 132942 : return arg;
642 : }
643 :
644 : static u32 ff_streamtype(u32 st)
645 : {
646 : switch (st) {
647 : case AVMEDIA_TYPE_AUDIO: return GF_STREAM_AUDIO;
648 : case AVMEDIA_TYPE_VIDEO: return GF_STREAM_VISUAL;
649 : case AVMEDIA_TYPE_DATA: return GF_STREAM_METADATA;
650 : case AVMEDIA_TYPE_SUBTITLE: return GF_STREAM_TEXT;
651 : }
652 : return GF_STREAM_UNKNOWN;
653 : }
654 :
655 : #if (LIBAVFORMAT_VERSION_MAJOR >= 58) && (LIBAVFORMAT_VERSION_MINOR>=30)
656 : #else
657 : #define NO_AVIO_PROTO
658 : #endif
659 :
660 155 : static void ffmpeg_expand_register(GF_FilterSession *session, GF_FilterRegister *orig_reg, u32 type)
661 : {
662 : u32 i=0, idx=0, flags=0;
663 : #ifndef NO_AVIO_PROTO
664 : Bool protocol_pass = GF_FALSE;
665 : #endif
666 : const struct AVOption *opt;
667 155 : GF_List *all_filters = gf_list_new();
668 : AVInputFormat *fmt = NULL;
669 : const AVOutputFormat *ofmt = NULL;
670 : AVCodec *codec = NULL;
671 : #if (LIBAVFILTER_VERSION_MAJOR > 5)
672 : const AVFilter *avf = NULL;
673 : #endif
674 :
675 : #if !defined(NO_AVIO_PROTO) || (LIBAVFILTER_VERSION_MAJOR > 6)
676 : void *av_it;
677 : #endif
678 :
679 : const char *fname = "";
680 155 : if (type==FF_REG_TYPE_DEMUX) fname = "ffdmx";
681 124 : else if (type==FF_REG_TYPE_DECODE) {
682 : fname = "ffdec";
683 : flags=AV_OPT_FLAG_DECODING_PARAM;
684 : }
685 93 : else if (type==FF_REG_TYPE_DEV_IN) {
686 : fname = "ffavin";
687 31 : avdevice_register_all();
688 : flags=AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM;
689 : }
690 62 : else if (type==FF_REG_TYPE_ENCODE) {
691 : fname = "ffenc";
692 : flags=AV_OPT_FLAG_ENCODING_PARAM;
693 : }
694 31 : else if (type==FF_REG_TYPE_MUX) {
695 : fname = "ffmx";
696 : }
697 0 : else if (type==FF_REG_TYPE_AVF) {
698 : fname = "ffavf";
699 : }
700 : else return;
701 :
702 :
703 155 : ((GF_FFRegistryExt *)orig_reg->udta)->all_filters = all_filters;
704 :
705 :
706 : #ifndef NO_AVIO_PROTO
707 : second_pass:
708 : #endif
709 :
710 : #if !defined(NO_AVIO_PROTO) || (LIBAVFILTER_VERSION_MAJOR > 6)
711 : av_it = NULL;
712 : #endif
713 :
714 : while (1) {
715 : const AVClass *av_class=NULL;
716 : const char *subname = NULL;
717 : #ifndef GPAC_DISABLE_DOC
718 : const char *description = "description unavailable in ffmpeg";
719 : #endif
720 : char szDef[100];
721 : GF_FilterRegister *freg;
722 63068 : if (type==FF_REG_TYPE_DEMUX) {
723 : #ifndef NO_AVIO_PROTO
724 : if (protocol_pass) {
725 : subname = avio_enum_protocols(&av_it, 0);
726 : if (!subname) break;
727 : av_class = avio_protocol_get_class(subname);
728 : #ifndef GPAC_DISABLE_DOC
729 : description = "Input protocol";
730 : #endif
731 : } else
732 : #endif
733 : {
734 8756 : fmt = av_iformat_next(fmt);
735 8756 : if (!fmt) break;
736 8725 : av_class = fmt->priv_class;
737 8725 : subname = fmt->name;
738 : #ifndef GPAC_DISABLE_DOC
739 8725 : description = fmt->long_name;
740 : #endif
741 : }
742 54312 : } else if (type==FF_REG_TYPE_DECODE) {
743 19995 : codec = av_codec_next(codec);
744 19995 : if (!codec) break;
745 19964 : if (!av_codec_is_decoder(codec))
746 34472 : continue;
747 :
748 14260 : av_class = codec->priv_class;
749 14260 : subname = codec->name;
750 : #ifndef GPAC_DISABLE_DOC
751 14260 : description = codec->long_name;
752 : #endif
753 34317 : } else if (type==FF_REG_TYPE_DEV_IN) {
754 : #if (LIBAVCODEC_VERSION_MAJOR >= 58) && (LIBAVCODEC_VERSION_MINOR>=20)
755 : fmt = av_input_video_device_next(fmt);
756 : if (!fmt) break;
757 : av_class = fmt->priv_class;
758 : subname = fmt->name;
759 : #ifndef GPAC_DISABLE_DOC
760 : description = fmt->long_name;
761 : #endif
762 : if (!av_class || (av_class->category!=AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) ) continue;
763 : #else
764 9176 : fmt = av_iformat_next(fmt);
765 9176 : if (!fmt) break;
766 9145 : av_class = fmt->priv_class;
767 9145 : subname = fmt->name;
768 : #ifndef GPAC_DISABLE_DOC
769 9145 : description = fmt->long_name;
770 : #endif
771 : //brute force ...
772 9145 : if (!strcmp(subname, "dshow")) {}
773 9145 : else if (!strcmp(subname, "avfoundation")) {}
774 9145 : else if (!strcmp(subname, "video4linux2")) {}
775 9145 : else if (!strcmp(subname, "x11grab")) {}
776 9114 : else if (!strcmp(subname, "alsa")) {}
777 9083 : else if (!strcmp(subname, "decklink")) {}
778 9083 : else if (!strcmp(subname, "kmsgrab")) {}
779 9052 : else if (!strcmp(subname, "libndi_newtek")) {}
780 9052 : else if (!strcmp(subname, "fbdev")) {}
781 9021 : else if (!strcmp(subname, "gdigrab")) {}
782 9021 : else if (!strcmp(subname, "iec61883")) {}
783 8990 : else if (!strcmp(subname, "lavfi")) {}
784 8959 : else if (!strcmp(subname, "libcdio")) {}
785 8928 : else if (!strcmp(subname, "openal")) {}
786 8897 : else if (!strcmp(subname, "oss")) {}
787 8866 : else if (!strcmp(subname, "pulse")) {}
788 8835 : else if (!strcmp(subname, "sndio")) {}
789 8804 : else if (!stricmp(subname, "vfw")) {}
790 8804 : else continue;
791 : #endif
792 25141 : } else if (type==FF_REG_TYPE_ENCODE) {
793 19995 : codec = av_codec_next(codec);
794 19995 : if (!codec) break;
795 19964 : if (!av_codec_is_encoder(codec))
796 14260 : continue;
797 5704 : av_class = codec->priv_class;
798 5704 : subname = codec->name;
799 : #ifndef GPAC_DISABLE_DOC
800 5704 : description = codec->long_name;
801 : #endif
802 5146 : } else if (type==FF_REG_TYPE_MUX) {
803 : #ifndef NO_AVIO_PROTO
804 : if (protocol_pass) {
805 : subname = avio_enum_protocols(&av_it, 1);
806 : if (!subname) break;
807 : av_class = avio_protocol_get_class(subname);
808 : #ifndef GPAC_DISABLE_DOC
809 : description = "Output protocol";
810 : #endif
811 : } else
812 : #endif
813 :
814 : {
815 : #if (LIBAVFILTER_VERSION_MAJOR > 6)
816 : ofmt = av_muxer_iterate(&av_it);
817 : #else
818 5146 : ofmt = av_oformat_next(ofmt);
819 : #endif
820 5146 : if (!ofmt) break;
821 5115 : av_class = ofmt->priv_class;
822 5115 : subname = ofmt->name;
823 : #ifndef GPAC_DISABLE_DOC
824 5115 : description = ofmt->long_name;
825 : #endif
826 : }
827 0 : } else if (type==FF_REG_TYPE_AVF) {
828 : #if (LIBAVFILTER_VERSION_MAJOR > 5)
829 : #if (LIBAVFILTER_VERSION_MAJOR > 6)
830 : avf = av_filter_iterate(&av_it);
831 : #else
832 0 : avf = avfilter_next(avf);
833 : #endif
834 0 : if (!avf) break;
835 0 : av_class = avf->priv_class;
836 0 : subname = avf->name;
837 : #ifndef GPAC_DISABLE_DOC
838 0 : description = avf->description;
839 : #endif
840 :
841 : #else
842 : break;
843 :
844 : #endif
845 : } else {
846 : break;
847 : }
848 34145 : GF_SAFEALLOC(freg, GF_FilterRegister);
849 34145 : if (!freg) continue;
850 : memcpy(freg, orig_reg, sizeof(GF_FilterRegister));
851 34145 : freg->args = NULL;
852 34145 : freg->caps = NULL;
853 34145 : freg->nb_caps = 0;
854 : //no help
855 34145 : freg->help = NULL;
856 :
857 34145 : gf_list_add(all_filters, freg);
858 :
859 : sprintf(szDef, "%s:%s", fname, subname);
860 34145 : freg->name = gf_strdup(szDef);
861 : #ifndef GPAC_DISABLE_DOC
862 34145 : freg->description = description;
863 : #endif
864 34145 : if ((type==FF_REG_TYPE_ENCODE) || (type==FF_REG_TYPE_DECODE)) {
865 : GF_FilterCapability *caps;
866 19964 : u32 cid = ffmpeg_codecid_to_gpac(codec->id);
867 19964 : freg->nb_caps = 3;
868 :
869 19964 : caps = gf_malloc(sizeof(GF_FilterCapability)*3);
870 : memset(caps, 0, sizeof(GF_FilterCapability)*3);
871 19964 : caps[0].code = GF_PROP_PID_STREAM_TYPE;
872 19964 : caps[0].val.type = GF_PROP_UINT;
873 19964 : caps[0].val.value.uint = ff_streamtype(codec->type);
874 19964 : caps[0].flags = GF_CAPS_INPUT_OUTPUT;
875 :
876 19964 : caps[1].code = GF_PROP_PID_CODECID;
877 19964 : caps[1].val.type = GF_PROP_UINT;
878 19964 : caps[1].val.value.uint = (type==FF_REG_TYPE_DECODE) ? cid : GF_CODECID_RAW;
879 19964 : caps[1].flags = GF_CAPS_INPUT;
880 :
881 19964 : caps[2].code = GF_PROP_PID_CODECID;
882 19964 : caps[2].val.type = GF_PROP_UINT;
883 19964 : caps[2].val.value.uint = (type==FF_REG_TYPE_DECODE) ? GF_CODECID_RAW : cid;
884 19964 : caps[2].flags = GF_CAPS_OUTPUT;
885 :
886 19964 : freg->caps = caps;
887 : }
888 28362 : else if ((type==FF_REG_TYPE_DEMUX)
889 14181 : && fmt
890 : #if LIBAVCODEC_VERSION_MAJOR >= 58
891 : && (fmt->mime_type || fmt->extensions)
892 : #else
893 8725 : && fmt->extensions
894 : #endif
895 3751 : ){
896 : GF_FilterCapability *caps;
897 : #if LIBAVCODEC_VERSION_MAJOR >= 58
898 : freg->nb_caps = (fmt->mime_type && fmt->extensions) ? 4 : 2;
899 : #else
900 3751 : freg->nb_caps = 2;
901 : #endif
902 3751 : caps = gf_malloc(sizeof(GF_FilterCapability)*freg->nb_caps);
903 3751 : memset(caps, 0, sizeof(GF_FilterCapability)*freg->nb_caps);
904 3751 : caps[0].code = GF_PROP_PID_STREAM_TYPE;
905 3751 : caps[0].val.type = GF_PROP_UINT;
906 3751 : caps[0].val.value.uint = GF_STREAM_FILE;
907 3751 : caps[0].flags = GF_CAPS_INPUT_STATIC;
908 :
909 3751 : caps[1].code = fmt->extensions ? GF_PROP_PID_FILE_EXT : GF_PROP_PID_MIME;
910 3751 : caps[1].val.type = GF_PROP_NAME;
911 : #if LIBAVCODEC_VERSION_MAJOR >= 58
912 : caps[1].val.value.string = (char *) ( fmt->extensions ? fmt->extensions : fmt->mime_type );
913 : #else
914 3751 : caps[1].val.value.string = (char *) fmt->extensions;
915 : #endif
916 3751 : caps[1].flags = GF_CAPS_INPUT;
917 :
918 : #if LIBAVCODEC_VERSION_MAJOR >= 58
919 : if (fmt->mime_type && fmt->extensions) {
920 : caps[2].flags = 0;
921 : caps[3].code = GF_PROP_PID_MIME;
922 : caps[3].val.type = GF_PROP_NAME;
923 : caps[3].val.value.string = (char *) fmt->mime_type;
924 : caps[3].flags = GF_CAPS_INPUT;
925 : }
926 : #endif
927 : //TODO map codec IDs if known ?
928 3751 : freg->caps = caps;
929 : }
930 20860 : else if ((type==FF_REG_TYPE_MUX)
931 10430 : && ofmt
932 : #if LIBAVCODEC_VERSION_MAJOR >= 58
933 : && (ofmt->mime_type || ofmt->extensions)
934 : #else
935 5115 : && ofmt->extensions
936 : #endif
937 : ){
938 : GF_FilterCapability *caps;
939 : #if LIBAVCODEC_VERSION_MAJOR >= 58
940 : freg->nb_caps = (ofmt->mime_type && ofmt->extensions) ? 4 : 2;
941 : #else
942 3441 : freg->nb_caps = 2;
943 : #endif
944 3441 : caps = gf_malloc(sizeof(GF_FilterCapability)*freg->nb_caps);
945 3441 : memset(caps, 0, sizeof(GF_FilterCapability)*freg->nb_caps);
946 3441 : caps[0].code = GF_PROP_PID_STREAM_TYPE;
947 3441 : caps[0].val.type = GF_PROP_UINT;
948 3441 : caps[0].val.value.uint = GF_STREAM_FILE;
949 3441 : caps[0].flags = GF_CAPS_OUTPUT_STATIC;
950 :
951 3441 : caps[1].code = ofmt->extensions ? GF_PROP_PID_FILE_EXT : GF_PROP_PID_MIME;
952 3441 : caps[1].val.type = GF_PROP_NAME;
953 : #if LIBAVCODEC_VERSION_MAJOR >= 58
954 : caps[1].val.value.string = (char *) ( ofmt->extensions ? ofmt->extensions : ofmt->mime_type );
955 : #else
956 3441 : caps[1].val.value.string = (char *) ofmt->extensions;
957 : #endif
958 3441 : caps[1].flags = GF_CAPS_OUTPUT;
959 :
960 : #if LIBAVCODEC_VERSION_MAJOR >= 58
961 : if (ofmt->mime_type && ofmt->extensions) {
962 : caps[2].flags = 0;
963 : caps[3].code = GF_PROP_PID_MIME;
964 : caps[3].val.type = GF_PROP_NAME;
965 : caps[3].val.value.string = (char *) ofmt->mime_type;
966 : caps[3].flags = GF_CAPS_OUTPUT;
967 : }
968 : #endif
969 : //TODO map codec IDs if known ?
970 3441 : freg->caps = caps;
971 : }
972 :
973 : idx=0;
974 : i=0;
975 181454 : while (av_class) {
976 123439 : opt = &av_class->option[idx];
977 123439 : if (!opt || !opt->name) break;
978 113164 : if (!flags || (opt->flags & flags) ) {
979 112606 : if (!opt->unit)
980 54579 : i++;
981 : else {
982 : u32 k;
983 : Bool is_first = GF_TRUE;
984 755913 : for (k=0; k<idx; k++) {
985 804292 : const struct AVOption *an_opt = &av_class->option[k];
986 804292 : if (an_opt && an_opt->unit && !strcmp(opt->unit, an_opt->unit)) {
987 : //patch some broken AVClass where the option name declaring the option unit is not declared first
988 : u32 l;
989 603664 : for (l=0; l<k; l++) {
990 603664 : const struct AVOption *par_opt = &av_class->option[l];
991 603664 : if (!strcmp(par_opt->name, an_opt->name)) {
992 : is_first=GF_FALSE;
993 : break;
994 : }
995 : }
996 : break;
997 : }
998 : }
999 58027 : if (is_first)
1000 58027 : i++;
1001 : }
1002 : }
1003 113164 : idx++;
1004 : }
1005 34145 : if (i) {
1006 10027 : GF_FilterArgs *args = gf_malloc(sizeof(GF_FilterArgs)*(i+1));
1007 : memset(args, 0, sizeof(GF_FilterArgs)*(i+1));
1008 10027 : freg->args = args;
1009 :
1010 : i=0;
1011 : idx=0;
1012 133094 : while (av_class) {
1013 123067 : opt = &av_class->option[idx];
1014 123067 : if (!opt || !opt->name) break;
1015 113040 : if (flags && !(opt->flags & flags) ) {
1016 434 : idx++;
1017 434 : continue;
1018 : }
1019 :
1020 112606 : if (opt->unit) {
1021 : u32 k;
1022 : const char *opt_name = NULL;
1023 : GF_FilterArgs *par_arg=NULL;
1024 755913 : for (k=0; k<idx; k++) {
1025 804292 : const struct AVOption *an_opt = &av_class->option[k];
1026 804292 : if (an_opt && an_opt->unit && !strcmp(opt->unit, an_opt->unit)) {
1027 48379 : opt_name = an_opt->name;
1028 48379 : break;
1029 : }
1030 : }
1031 58027 : if (opt_name) {
1032 242991 : for (k=0; k<i; k++) {
1033 291370 : par_arg = &args[k];
1034 291370 : if (!strcmp(par_arg->arg_name, opt_name))
1035 : break;
1036 : par_arg = NULL;
1037 : }
1038 : }
1039 :
1040 48379 : if (par_arg) {
1041 48379 : GF_FilterArgs an_arg = ffmpeg_arg_translate(opt);
1042 48379 : if (!(par_arg->flags & GF_FS_ARG_META_ALLOC)) {
1043 9462 : par_arg->arg_desc = par_arg->arg_desc ? gf_strdup(par_arg->arg_desc) : NULL;
1044 9462 : par_arg->flags |= GF_FS_ARG_META_ALLOC;
1045 : }
1046 48379 : gf_dynstrcat((char **) &par_arg->arg_desc, an_arg.arg_name, "\n - ");
1047 48379 : gf_dynstrcat((char **) &par_arg->arg_desc, an_arg.arg_desc, ": ");
1048 :
1049 48379 : if (an_arg.arg_default_val)
1050 48379 : gf_free((void *) an_arg.arg_default_val);
1051 48379 : if (an_arg.min_max_enum)
1052 528 : gf_free((void *) an_arg.min_max_enum);
1053 :
1054 48379 : idx++;
1055 48379 : continue;
1056 : }
1057 : }
1058 :
1059 64227 : args[i] = ffmpeg_arg_translate(opt);
1060 64227 : i++;
1061 :
1062 64227 : idx++;
1063 : }
1064 : }
1065 34145 : gf_fs_add_filter_register(session, freg);
1066 : }
1067 :
1068 : #ifndef NO_AVIO_PROTO
1069 : if ((type==FF_REG_TYPE_MUX) || (type==FF_REG_TYPE_DEMUX)) {
1070 : if (!protocol_pass) {
1071 : protocol_pass = GF_TRUE;
1072 : goto second_pass;
1073 : }
1074 : }
1075 : #endif
1076 :
1077 : }
1078 :
1079 14385 : void ffmpeg_build_register(GF_FilterSession *session, GF_FilterRegister *orig_reg, const GF_FilterArgs *default_args, u32 nb_def_args, u32 reg_type)
1080 : {
1081 : GF_FilterArgs *args;
1082 : u32 i=0, idx=0, nb_args;
1083 : const struct AVOption *opt;
1084 : u32 opt_type = AV_OPT_FLAG_DECODING_PARAM;
1085 : Bool load_meta_filters = session ? GF_TRUE : GF_FALSE;
1086 : AVFormatContext *format_ctx = NULL;
1087 : AVCodecContext *codec_ctx = NULL;
1088 : const AVClass *av_class = NULL;
1089 : GF_FFRegistryExt *ffregext;
1090 :
1091 14385 : ffmpeg_initialize();
1092 :
1093 14385 : orig_reg->author = avfilter_configuration();
1094 :
1095 : //by default no need to load option descriptions, everything is handled by av_set_opt in update_args
1096 14385 : if (!load_meta_filters) {
1097 14230 : orig_reg->args = default_args;
1098 14230 : orig_reg->register_free = NULL;
1099 14230 : return;
1100 : }
1101 :
1102 155 : if (reg_type==FF_REG_TYPE_ENCODE) opt_type = AV_OPT_FLAG_ENCODING_PARAM;
1103 124 : else if (reg_type==FF_REG_TYPE_MUX) opt_type = AV_OPT_FLAG_ENCODING_PARAM;
1104 93 : else if (reg_type==FF_REG_TYPE_AVF) opt_type = 0xFFFFFFFF;
1105 :
1106 155 : if ((reg_type==FF_REG_TYPE_ENCODE) || (reg_type==FF_REG_TYPE_DECODE)) {
1107 62 : orig_reg->author = avcodec_configuration();
1108 62 : codec_ctx = avcodec_alloc_context3(NULL);
1109 62 : av_class = codec_ctx->av_class;
1110 93 : } else if (reg_type==FF_REG_TYPE_AVF) {
1111 : #if (LIBAVFILTER_VERSION_MAJOR > 5)
1112 0 : av_class = avfilter_get_class();
1113 : #endif
1114 : } else {
1115 93 : format_ctx = avformat_alloc_context();
1116 93 : av_class = format_ctx->av_class;
1117 : }
1118 :
1119 : i=0;
1120 : idx=0;
1121 33604 : while (av_class && av_class->option) {
1122 33449 : opt = &av_class->option[idx];
1123 33449 : if (!opt || !opt->name) break;
1124 :
1125 33294 : if (opt->flags & opt_type) {
1126 20336 : if (!opt->unit) {
1127 4557 : i++;
1128 : } else {
1129 : u32 k;
1130 : Bool is_first = GF_TRUE;
1131 3168603 : for (k=0; k<idx; k++) {
1132 3182491 : const struct AVOption *an_opt = &av_class->option[k];
1133 3182491 : if (an_opt && an_opt->unit && !strcmp(opt->unit, an_opt->unit)) {
1134 : //patch some broken AVClass where the option name declaring the option unit is not declared first
1135 : u32 l;
1136 2793999 : for (l=0; l<k; l++) {
1137 2793999 : const struct AVOption *par_opt = &av_class->option[l];
1138 2793999 : if (!strcmp(par_opt->name, an_opt->name)) {
1139 : is_first=GF_FALSE;
1140 : break;
1141 : }
1142 : }
1143 : break;
1144 : }
1145 : }
1146 15779 : if (is_first)
1147 15779 : i++;
1148 : }
1149 : }
1150 33294 : idx++;
1151 : }
1152 155 : i += nb_def_args;
1153 :
1154 155 : nb_args = i+1;
1155 155 : args = gf_malloc(sizeof(GF_FilterArgs)*nb_args);
1156 : memset(args, 0, sizeof(GF_FilterArgs)*nb_args);
1157 155 : orig_reg->args = args;
1158 :
1159 868 : for (i=0; i<nb_def_args-1; i++) {
1160 713 : memcpy(&args[i], &default_args[i], sizeof(GF_FilterArgs));
1161 : }
1162 : //do not reset i
1163 :
1164 : idx=0;
1165 33449 : while (av_class && av_class->option) {
1166 33449 : opt = &av_class->option[idx];
1167 33449 : if (!opt || !opt->name) break;
1168 :
1169 33294 : if (opt->flags & opt_type) {
1170 :
1171 20336 : if (opt->unit) {
1172 : u32 k;
1173 : const char *opt_name = NULL;
1174 : GF_FilterArgs *par_arg=NULL;
1175 3168603 : for (k=0; k<idx; k++) {
1176 3182491 : const struct AVOption *an_opt = &av_class->option[k];
1177 3182491 : if (an_opt && an_opt->unit && !strcmp(opt->unit, an_opt->unit)) {
1178 13888 : opt_name = an_opt->name;
1179 13888 : break;
1180 : }
1181 : }
1182 15779 : if (opt_name) {
1183 569036 : for (k=0; k<i; k++) {
1184 582707 : par_arg = &args[k];
1185 582707 : if (!strcmp(par_arg->arg_name, opt_name))
1186 : break;
1187 : par_arg = NULL;
1188 : }
1189 : }
1190 :
1191 13888 : if (par_arg) {
1192 13671 : GF_FilterArgs an_arg = ffmpeg_arg_translate(opt);
1193 13671 : if (!(par_arg->flags & GF_FS_ARG_META_ALLOC)) {
1194 : //move from const to allocated memory
1195 1767 : par_arg->arg_desc = gf_strdup(par_arg->arg_desc ? par_arg->arg_desc : " ");
1196 1767 : par_arg->flags |= GF_FS_ARG_META_ALLOC;
1197 : /*trash default values and min_max_enum for flags*/
1198 1767 : if (par_arg->arg_default_val) {
1199 1767 : gf_free((char *) par_arg->arg_default_val);
1200 1767 : par_arg->arg_default_val = NULL;
1201 : }
1202 1767 : if (par_arg->min_max_enum) {
1203 1023 : gf_free((char *) par_arg->min_max_enum);
1204 1023 : par_arg->min_max_enum = NULL;
1205 : }
1206 : }
1207 13671 : gf_dynstrcat((char **) &par_arg->arg_desc, an_arg.arg_name, "\n- ");
1208 13671 : gf_dynstrcat((char **) &par_arg->arg_desc, an_arg.arg_desc ? an_arg.arg_desc : "", ": ");
1209 :
1210 13671 : if (an_arg.arg_default_val)
1211 13671 : gf_free((void *) an_arg.arg_default_val);
1212 13671 : if (an_arg.min_max_enum)
1213 310 : gf_free((void *) an_arg.min_max_enum);
1214 :
1215 13671 : idx++;
1216 13671 : continue;
1217 : }
1218 : }
1219 : assert(nb_args>i);
1220 6665 : args[i] = ffmpeg_arg_translate(opt);
1221 6665 : i++;
1222 : }
1223 19623 : idx++;
1224 : }
1225 155 : memcpy(&args[i], &default_args[nb_def_args-1], sizeof(GF_FilterArgs));
1226 :
1227 155 : if (codec_ctx) {
1228 : #if (LIBAVCODEC_VERSION_MAJOR >= 58) && (LIBAVCODEC_VERSION_MINOR>=20)
1229 : avcodec_free_context(&codec_ctx);
1230 : #else
1231 62 : av_free(codec_ctx);
1232 : #endif
1233 : } else {
1234 93 : avformat_free_context(format_ctx);
1235 : }
1236 :
1237 155 : GF_SAFEALLOC(ffregext, GF_FFRegistryExt);
1238 155 : if (!ffregext) return;
1239 :
1240 155 : orig_reg->udta = ffregext;
1241 155 : ffregext->nb_arg_skip = nb_def_args-1;
1242 155 : orig_reg->register_free = ffmpeg_register_free;
1243 :
1244 155 : ffmpeg_expand_register(session, orig_reg, reg_type);
1245 :
1246 : }
1247 :
1248 182 : void ffmpeg_set_enc_dec_flags(const AVDictionary *options, AVCodecContext *ctx)
1249 : {
1250 : AVDictionaryEntry *de=NULL;
1251 :
1252 182 : ctx->flags = 0;
1253 182 : ctx->flags2 = 0;
1254 : while (1) {
1255 : u32 idx=0;
1256 262 : de = av_dict_get((AVDictionary *)options, "", (const AVDictionaryEntry *) de, AV_DICT_IGNORE_SUFFIX);
1257 262 : if (!de) break;
1258 :
1259 34640 : while (ctx->av_class->option) {
1260 34640 : const struct AVOption *opt = &ctx->av_class->option[idx];
1261 34640 : if (!opt || !opt->name) break;
1262 34560 : if (opt->name && !strcmp(opt->name, de->key) && (!stricmp(de->value, "true") || !stricmp(de->value, "yes") || !stricmp(de->value, "1") )) {
1263 0 : if (opt->unit && !strcmp(opt->unit, "flags"))
1264 0 : ctx->flags |= (int) opt->default_val.i64;
1265 0 : else if (opt->unit && !strcmp(opt->unit, "flags2"))
1266 0 : ctx->flags2 |= (int) opt->default_val.i64;
1267 : break;
1268 : }
1269 34560 : idx++;
1270 : }
1271 : }
1272 182 : }
1273 :
1274 7 : void ffmpeg_set_mx_dmx_flags(const AVDictionary *options, AVFormatContext *ctx)
1275 : {
1276 : AVDictionaryEntry *de=NULL;
1277 :
1278 : while (1) {
1279 : u32 idx=0;
1280 7 : de = av_dict_get((AVDictionary *)options, "", de, AV_DICT_IGNORE_SUFFIX);
1281 7 : if (!de) break;
1282 :
1283 0 : while (ctx->av_class->option) {
1284 0 : const struct AVOption *opt = &ctx->av_class->option[idx];
1285 0 : if (!opt || !opt->name) break;
1286 0 : if (opt->name && !strcmp(opt->name, de->key)) {
1287 0 : if (opt->unit && !strcmp(opt->unit, "fflags"))
1288 0 : ctx->flags |= (int) opt->default_val.i64;
1289 0 : else if (opt->unit && !strcmp(opt->unit, "avioflags"))
1290 0 : ctx->avio_flags |= (int) opt->default_val.i64;
1291 : break;
1292 : }
1293 0 : idx++;
1294 : }
1295 : }
1296 7 : }
1297 :
1298 58 : void ffmpeg_report_unused_options(GF_Filter *filter, AVDictionary *options)
1299 : {
1300 : AVDictionaryEntry *prev_e = NULL;
1301 190 : while (options) {
1302 120 : prev_e = av_dict_get(options, "", prev_e, AV_DICT_IGNORE_SUFFIX);
1303 120 : if (!prev_e) break;
1304 74 : gf_filter_report_unused_meta_option(filter, prev_e->key);
1305 : }
1306 :
1307 58 : }
1308 : #endif
|