• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * This file:
4  * Copyright (c) 2002-2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <string.h>
27 
28 #include <gst/gst.h>
29 #include <libavcodec/avcodec.h>
30 #include <libavutil/channel_layout.h>
31 
32 #include "gstav.h"
33 #include "gstavcodecmap.h"
34 
35 #include <gst/video/video.h>
36 #include <gst/audio/audio.h>
37 #include <gst/pbutils/codec-utils.h>
38 
39 /* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
40 static const struct
41 {
42   guint64 ff;
43   GstAudioChannelPosition gst;
44 } _ff_to_gst_layout[] = {
45   {
46   AV_CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
47   AV_CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
48   AV_CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
49   AV_CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
50   AV_CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
51   AV_CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
52   AV_CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
53   AV_CH_FRONT_RIGHT_OF_CENTER,
54         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
55   AV_CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
56   AV_CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
57   AV_CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
58   AV_CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
59   AV_CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
60   AV_CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
61   AV_CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
62   AV_CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
63   AV_CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
64   AV_CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
65   AV_CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
66   AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
67 };
68 
69 static guint64
gst_ffmpeg_channel_positions_to_layout(GstAudioChannelPosition * pos,gint channels)70 gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos,
71     gint channels)
72 {
73   gint i, j;
74   guint64 ret = 0;
75   gint channels_found = 0;
76 
77   if (!pos)
78     return 0;
79 
80   if (channels == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_MONO)
81     return AV_CH_LAYOUT_MONO;
82 
83   for (i = 0; i < channels; i++) {
84     for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) {
85       if (_ff_to_gst_layout[j].gst == pos[i]) {
86         ret |= _ff_to_gst_layout[j].ff;
87         channels_found++;
88         break;
89       }
90     }
91   }
92 
93   if (channels_found != channels)
94     return 0;
95   return ret;
96 }
97 
98 gboolean
gst_ffmpeg_channel_layout_to_gst(guint64 channel_layout,gint channels,GstAudioChannelPosition * pos)99 gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
100     GstAudioChannelPosition * pos)
101 {
102   guint nchannels = 0;
103   gboolean none_layout = FALSE;
104 
105   if (channel_layout == 0 || channels > 64) {
106     nchannels = channels;
107     none_layout = TRUE;
108   } else {
109     guint i, j;
110 
111     /* Special path for mono, as AV_CH_LAYOUT_MONO is the same
112      * as FRONT_CENTER but we distinguish between the two in
113      * GStreamer
114      */
115     if (channels == 1 && channel_layout == AV_CH_LAYOUT_MONO) {
116       pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
117       return TRUE;
118     }
119 
120     for (i = 0; i < 64; i++) {
121       if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
122         nchannels++;
123       }
124     }
125 
126     if (nchannels != channels) {
127       GST_ERROR ("Number of channels is different (%u != %u)", channels,
128           nchannels);
129       nchannels = channels;
130       none_layout = TRUE;
131     } else {
132 
133       for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
134         if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
135           pos[j++] = _ff_to_gst_layout[i].gst;
136 
137           if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE)
138             none_layout = TRUE;
139         }
140       }
141 
142       if (j != nchannels) {
143         GST_WARNING
144             ("Unknown channels in channel layout - assuming NONE layout");
145         none_layout = TRUE;
146       }
147     }
148   }
149 
150   if (!none_layout
151       && !gst_audio_check_valid_channel_positions (pos, nchannels, FALSE)) {
152     GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
153         " - assuming NONE layout", channel_layout);
154     none_layout = TRUE;
155   }
156 
157   if (none_layout) {
158     if (nchannels == 1) {
159       pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
160     } else if (nchannels == 2) {
161       pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
162       pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
163     } else {
164       guint i;
165 
166       for (i = 0; i < nchannels && i < 64; i++)
167         pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
168     }
169   }
170 
171   return TRUE;
172 }
173 
174 static gboolean
_gst_value_list_contains(const GValue * list,const GValue * value)175 _gst_value_list_contains (const GValue * list, const GValue * value)
176 {
177   guint i, n;
178   const GValue *tmp;
179 
180   n = gst_value_list_get_size (list);
181   for (i = 0; i < n; i++) {
182     tmp = gst_value_list_get_value (list, i);
183     if (gst_value_compare (value, tmp) == GST_VALUE_EQUAL)
184       return TRUE;
185   }
186 
187   return FALSE;
188 }
189 
190 static void
gst_ffmpeg_video_set_pix_fmts(GstCaps * caps,const enum AVPixelFormat * fmts)191 gst_ffmpeg_video_set_pix_fmts (GstCaps * caps, const enum AVPixelFormat *fmts)
192 {
193   GValue va = { 0, };
194   GValue v = { 0, };
195   GstVideoFormat format;
196 
197   if (!fmts || fmts[0] == -1) {
198     gint i;
199 
200     g_value_init (&va, GST_TYPE_LIST);
201     g_value_init (&v, G_TYPE_STRING);
202     for (i = 0; i <= AV_PIX_FMT_NB; i++) {
203       format = gst_ffmpeg_pixfmt_to_videoformat (i);
204       if (format == GST_VIDEO_FORMAT_UNKNOWN)
205         continue;
206       g_value_set_string (&v, gst_video_format_to_string (format));
207       gst_value_list_append_value (&va, &v);
208     }
209     gst_caps_set_value (caps, "format", &va);
210     g_value_unset (&v);
211     g_value_unset (&va);
212     return;
213   }
214 
215   /* Only a single format */
216   g_value_init (&va, GST_TYPE_LIST);
217   g_value_init (&v, G_TYPE_STRING);
218   while (*fmts != -1) {
219     format = gst_ffmpeg_pixfmt_to_videoformat (*fmts);
220     if (format != GST_VIDEO_FORMAT_UNKNOWN) {
221       g_value_set_string (&v, gst_video_format_to_string (format));
222       /* Only append values we don't have yet */
223       if (!_gst_value_list_contains (&va, &v))
224         gst_value_list_append_value (&va, &v);
225     }
226     fmts++;
227   }
228   if (gst_value_list_get_size (&va) == 1) {
229     /* The single value is still in v */
230     gst_caps_set_value (caps, "format", &v);
231   } else if (gst_value_list_get_size (&va) > 1) {
232     gst_caps_set_value (caps, "format", &va);
233   }
234   g_value_unset (&v);
235   g_value_unset (&va);
236 }
237 
238 /* this macro makes a caps width fixed or unfixed width/height
239  * properties depending on whether we've got a context.
240  *
241  * See below for why we use this.
242  *
243  * We should actually do this stuff at the end, like in riff-media.c,
244  * but I'm too lazy today. Maybe later.
245  */
246 static GstCaps *
gst_ff_vid_caps_new(AVCodecContext * context,AVCodec * codec,enum AVCodecID codec_id,gboolean encode,const char * mimetype,const char * fieldname,...)247 gst_ff_vid_caps_new (AVCodecContext * context, AVCodec * codec,
248     enum AVCodecID codec_id, gboolean encode, const char *mimetype,
249     const char *fieldname, ...)
250 {
251   GstCaps *caps = NULL;
252   va_list var_args;
253   gint i;
254 
255   GST_LOG ("context:%p, codec_id:%d, mimetype:%s", context, codec_id, mimetype);
256 
257   /* fixed, non probing context */
258   if (context != NULL && context->width != -1) {
259     gint num, denom;
260 
261     caps = gst_caps_new_simple (mimetype,
262         "width", G_TYPE_INT, context->width,
263         "height", G_TYPE_INT, context->height, NULL);
264 
265     num = context->framerate.num;
266     denom = context->framerate.den;
267 
268     if (!denom) {
269       GST_LOG ("invalid framerate: %d/0, -> %d/1", num, num);
270       denom = 1;
271     }
272     if (gst_util_fraction_compare (num, denom, 1000, 1) > 0) {
273       GST_LOG ("excessive framerate: %d/%d, -> 0/1", num, denom);
274       num = 0;
275       denom = 1;
276     }
277     GST_LOG ("setting framerate: %d/%d", num, denom);
278     gst_caps_set_simple (caps,
279         "framerate", GST_TYPE_FRACTION, num, denom, NULL);
280   } else if (encode) {
281     /* so we are after restricted caps in this case */
282     switch (codec_id) {
283       case AV_CODEC_ID_H261:
284       {
285         caps = gst_caps_new_simple (mimetype,
286             "width", G_TYPE_INT, 352,
287             "height", G_TYPE_INT, 288,
288             "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
289         gst_caps_append (caps, gst_caps_new_simple (mimetype,
290                 "width", G_TYPE_INT, 176,
291                 "height", G_TYPE_INT, 144,
292                 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
293         break;
294       }
295       case AV_CODEC_ID_H263:
296       {
297         /* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
298          * because we want automatic negotiation to go as close to 320x240 as
299          * possible. */
300         const static gint widths[] = { 352, 704, 176, 1408, 128 };
301         const static gint heights[] = { 288, 576, 144, 1152, 96 };
302         GstCaps *temp;
303         gint n_sizes = G_N_ELEMENTS (widths);
304 
305         caps = gst_caps_new_empty ();
306         for (i = 0; i < n_sizes; i++) {
307           temp = gst_caps_new_simple (mimetype,
308               "width", G_TYPE_INT, widths[i],
309               "height", G_TYPE_INT, heights[i],
310               "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
311 
312           gst_caps_append (caps, temp);
313         }
314         break;
315       }
316       case AV_CODEC_ID_DVVIDEO:
317       {
318         static struct
319         {
320           const gchar *csp;
321           gint width, height;
322           gint par_n, par_d;
323           gint framerate_n, framerate_d;
324         } profiles[] = {
325           {
326           "Y41B", 720, 480, 8, 9, 30000, 1001}, {
327           "Y41B", 720, 480, 32, 27, 30000, 1001}, {
328           "Y42B", 720, 480, 8, 9, 30000, 1001}, {
329           "Y42B", 720, 480, 32, 27, 30000, 1001}, {
330           "I420", 720, 576, 16, 15, 25, 1}, {
331           "I420", 720, 576, 64, 45, 25, 1}, {
332           "Y41B", 720, 576, 16, 15, 25, 1}, {
333           "Y41B", 720, 576, 64, 45, 25, 1}, {
334           "Y42B", 720, 576, 16, 15, 25, 1}, {
335           "Y42B", 720, 576, 64, 45, 25, 1}, {
336           "Y42B", 1280, 1080, 1, 1, 30000, 1001}, {
337           "Y42B", 1280, 1080, 3, 2, 30000, 1001}, {
338           "Y42B", 1440, 1080, 1, 1, 25, 1}, {
339           "Y42B", 1440, 1080, 4, 3, 25, 1}, {
340           "Y42B", 960, 720, 1, 1, 60000, 1001}, {
341           "Y42B", 960, 720, 4, 3, 60000, 1001}, {
342           "Y42B", 960, 720, 1, 1, 50, 1}, {
343         "Y42B", 960, 720, 4, 3, 50, 1},};
344         GstCaps *temp;
345         gint n_sizes = G_N_ELEMENTS (profiles);
346 
347         if (strcmp (mimetype, "video/x-raw") == 0) {
348           caps = gst_caps_new_empty ();
349           for (i = 0; i < n_sizes; i++) {
350             temp = gst_caps_new_simple (mimetype,
351                 "format", G_TYPE_STRING, profiles[i].csp,
352                 "width", G_TYPE_INT, profiles[i].width,
353                 "height", G_TYPE_INT, profiles[i].height,
354                 "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
355                 profiles[i].framerate_d, "pixel-aspect-ratio",
356                 GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
357 
358             gst_caps_append (caps, temp);
359           }
360         } else {
361           caps = gst_caps_new_empty ();
362           for (i = 0; i < n_sizes; i++) {
363             temp = gst_caps_new_simple (mimetype,
364                 "width", G_TYPE_INT, profiles[i].width,
365                 "height", G_TYPE_INT, profiles[i].height,
366                 "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
367                 profiles[i].framerate_d, "pixel-aspect-ratio",
368                 GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
369 
370             gst_caps_append (caps, temp);
371           }
372         }
373         break;
374       }
375       case AV_CODEC_ID_DNXHD:
376       {
377         caps = gst_caps_new_simple (mimetype,
378             "width", G_TYPE_INT, 1920,
379             "height", G_TYPE_INT, 1080,
380             "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
381         gst_caps_append (caps, gst_caps_new_simple (mimetype,
382                 "width", G_TYPE_INT, 1280,
383                 "height", G_TYPE_INT, 720,
384                 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
385         break;
386       }
387       default:
388       {
389         if (codec && codec->supported_framerates
390             && codec->supported_framerates[0].num != 0
391             && codec->supported_framerates[0].den != 0) {
392           GValue va = { 0, };
393           GValue v = { 0, };
394           const AVRational *rates = codec->supported_framerates;
395 
396           if (rates[1].num == 0 && rates[1].den == 0) {
397             caps =
398                 gst_caps_new_simple (mimetype, "framerate", GST_TYPE_FRACTION,
399                 rates[0].num, rates[0].den, NULL);
400           } else {
401             g_value_init (&va, GST_TYPE_LIST);
402             g_value_init (&v, GST_TYPE_FRACTION);
403 
404             while (rates->num != 0 && rates->den != 0) {
405               gst_value_set_fraction (&v, rates->num, rates->den);
406               gst_value_list_append_value (&va, &v);
407               rates++;
408             }
409 
410             caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
411             gst_caps_set_value (caps, "framerate", &va);
412             g_value_unset (&va);
413             g_value_unset (&v);
414           }
415 
416         } else {
417           caps = gst_caps_new_empty_simple (mimetype);
418         }
419 
420         break;
421       }
422     }
423   }
424 
425   /* no fixed caps or special restrictions applied;
426    * default unfixed setting */
427   if (!caps) {
428     GST_DEBUG ("Creating default caps");
429     caps = gst_caps_new_empty_simple (mimetype);
430   }
431 
432   va_start (var_args, fieldname);
433   gst_caps_set_simple_valist (caps, fieldname, var_args);
434   va_end (var_args);
435 
436   return caps;
437 }
438 
439 static gint
get_nbits_set(guint64 n)440 get_nbits_set (guint64 n)
441 {
442   gint i, x;
443 
444   x = 0;
445   for (i = 0; i < 64; i++) {
446     if ((n & (G_GUINT64_CONSTANT (1) << i)))
447       x++;
448   }
449 
450   return x;
451 }
452 
453 static void
gst_ffmpeg_audio_set_sample_fmts(GstCaps * caps,const enum AVSampleFormat * fmts,gboolean always_interleaved)454 gst_ffmpeg_audio_set_sample_fmts (GstCaps * caps,
455     const enum AVSampleFormat *fmts, gboolean always_interleaved)
456 {
457   GValue va = { 0, };
458   GValue vap = { 0, };
459   GValue v = { 0, };
460   GstAudioFormat format;
461   GstAudioLayout layout;
462   GstCaps *caps_copy = NULL;
463 
464   if (!fmts || fmts[0] == -1) {
465     gint i;
466 
467     g_value_init (&va, GST_TYPE_LIST);
468     g_value_init (&v, G_TYPE_STRING);
469     for (i = 0; i <= AV_SAMPLE_FMT_DBL; i++) {
470       format = gst_ffmpeg_smpfmt_to_audioformat (i, NULL);
471       if (format == GST_AUDIO_FORMAT_UNKNOWN)
472         continue;
473       g_value_set_string (&v, gst_audio_format_to_string (format));
474       gst_value_list_append_value (&va, &v);
475     }
476     gst_caps_set_value (caps, "format", &va);
477     if (!always_interleaved) {
478       g_value_init (&vap, GST_TYPE_LIST);
479       g_value_set_string (&v, "interleaved");
480       gst_value_list_append_value (&vap, &v);
481       g_value_set_string (&v, "non-interleaved");
482       gst_value_list_append_value (&vap, &v);
483       gst_caps_set_value (caps, "layout", &vap);
484       g_value_unset (&vap);
485     } else {
486       gst_caps_set_simple (caps, "layout", G_TYPE_STRING, "interleaved", NULL);
487     }
488     g_value_unset (&v);
489     g_value_unset (&va);
490     return;
491   }
492 
493   g_value_init (&va, GST_TYPE_LIST);
494   g_value_init (&vap, GST_TYPE_LIST);
495   g_value_init (&v, G_TYPE_STRING);
496   while (*fmts != -1) {
497     format = gst_ffmpeg_smpfmt_to_audioformat (*fmts, &layout);
498     if (format != GST_AUDIO_FORMAT_UNKNOWN) {
499       g_value_set_string (&v, gst_audio_format_to_string (format));
500       /* Only append values we don't have yet */
501       if (layout == GST_AUDIO_LAYOUT_INTERLEAVED || always_interleaved) {
502         if (!_gst_value_list_contains (&va, &v))
503           gst_value_list_append_value (&va, &v);
504       } else {
505         if (!_gst_value_list_contains (&vap, &v))
506           gst_value_list_append_value (&vap, &v);
507       }
508     }
509     fmts++;
510   }
511   if (gst_value_list_get_size (&va) >= 1 && gst_value_list_get_size (&vap) >= 1) {
512     caps_copy = gst_caps_copy (caps);
513   }
514   if (gst_value_list_get_size (&va) == 1) {
515     gst_caps_set_value (caps, "format", gst_value_list_get_value (&va, 0));
516     gst_caps_set_simple (caps, "layout", G_TYPE_STRING, "interleaved", NULL);
517   } else if (gst_value_list_get_size (&va) > 1) {
518     gst_caps_set_value (caps, "format", &va);
519     gst_caps_set_simple (caps, "layout", G_TYPE_STRING, "interleaved", NULL);
520   }
521   if (gst_value_list_get_size (&vap) == 1) {
522     gst_caps_set_value (caps_copy ? caps_copy : caps, "format",
523         gst_value_list_get_value (&vap, 0));
524     gst_caps_set_simple (caps_copy ? caps_copy : caps, "layout", G_TYPE_STRING,
525         "non-interleaved", NULL);
526   } else if (gst_value_list_get_size (&vap) > 1) {
527     gst_caps_set_value (caps_copy ? caps_copy : caps, "format", &vap);
528     gst_caps_set_simple (caps_copy ? caps_copy : caps, "layout", G_TYPE_STRING,
529         "non-interleaved", NULL);
530   }
531   if (caps_copy) {
532     gst_caps_append (caps, caps_copy);
533   }
534   g_value_unset (&v);
535   g_value_unset (&va);
536   g_value_unset (&vap);
537 }
538 
539 /* same for audio - now with channels/sample rate
540  */
541 static GstCaps *
gst_ff_aud_caps_new(AVCodecContext * context,AVCodec * codec,enum AVCodecID codec_id,gboolean encode,const char * mimetype,const char * fieldname,...)542 gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
543     enum AVCodecID codec_id, gboolean encode, const char *mimetype,
544     const char *fieldname, ...)
545 {
546   GstCaps *caps = NULL;
547   gint i;
548   va_list var_args;
549 
550   /* fixed, non-probing context */
551   if (context != NULL && context->channels != -1) {
552     GstAudioChannelPosition pos[64];
553     guint64 mask;
554 
555     caps = gst_caps_new_simple (mimetype,
556         "rate", G_TYPE_INT, context->sample_rate,
557         "channels", G_TYPE_INT, context->channels, NULL);
558 
559     if (context->channels > 1 &&
560         gst_ffmpeg_channel_layout_to_gst (context->channel_layout,
561             context->channels, pos) &&
562         gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
563             &mask)) {
564       gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, mask, NULL);
565     }
566   } else if (encode) {
567     gint maxchannels = 2;
568     const gint *rates = NULL;
569     gint n_rates = 0;
570 
571     /* so we must be after restricted caps in this case */
572     switch (codec_id) {
573       case AV_CODEC_ID_AAC:
574       case AV_CODEC_ID_AAC_LATM:
575       case AV_CODEC_ID_DTS:
576         maxchannels = 6;
577         break;
578       case AV_CODEC_ID_MP2:
579       {
580         const static gint l_rates[] =
581             { 48000, 44100, 32000, 24000, 22050, 16000 };
582         n_rates = G_N_ELEMENTS (l_rates);
583         rates = l_rates;
584         break;
585       }
586       case AV_CODEC_ID_EAC3:
587       case AV_CODEC_ID_AC3:
588       {
589         const static gint l_rates[] = { 48000, 44100, 32000 };
590         maxchannels = 6;
591         n_rates = G_N_ELEMENTS (l_rates);
592         rates = l_rates;
593         break;
594       }
595       case AV_CODEC_ID_ADPCM_G722:
596       {
597         const static gint l_rates[] = { 16000 };
598         n_rates = G_N_ELEMENTS (l_rates);
599         rates = l_rates;
600         maxchannels = 1;
601         break;
602       }
603       case AV_CODEC_ID_ADPCM_G726:
604       {
605         const static gint l_rates[] = { 8000 };
606         n_rates = G_N_ELEMENTS (l_rates);
607         rates = l_rates;
608         maxchannels = 1;
609         break;
610       }
611       case AV_CODEC_ID_ADPCM_SWF:
612       {
613         const static gint l_rates[] = { 11025, 22050, 44100 };
614         n_rates = G_N_ELEMENTS (l_rates);
615         rates = l_rates;
616         break;
617       }
618       case AV_CODEC_ID_ROQ_DPCM:
619       {
620         const static gint l_rates[] = { 22050 };
621         n_rates = G_N_ELEMENTS (l_rates);
622         rates = l_rates;
623         break;
624       }
625       case AV_CODEC_ID_AMR_NB:
626       {
627         const static gint l_rates[] = { 8000 };
628         maxchannels = 1;
629         n_rates = G_N_ELEMENTS (l_rates);
630         rates = l_rates;
631         break;
632       }
633       case AV_CODEC_ID_AMR_WB:
634       {
635         const static gint l_rates[] = { 16000 };
636         maxchannels = 1;
637         n_rates = G_N_ELEMENTS (l_rates);
638         rates = l_rates;
639         break;
640       }
641       default:
642         break;
643     }
644 
645     /* regardless of encode/decode, open up channels if applicable */
646     /* Until decoders/encoders expose the maximum number of channels
647      * they support, we whitelist them here. */
648     switch (codec_id) {
649       case AV_CODEC_ID_WMAPRO:
650       case AV_CODEC_ID_TRUEHD:
651         maxchannels = 8;
652         break;
653       default:
654         break;
655     }
656 
657     if (codec && codec->channel_layouts) {
658       const uint64_t *layouts = codec->channel_layouts;
659       GstAudioChannelPosition pos[64];
660 
661       caps = gst_caps_new_empty ();
662       while (*layouts) {
663         gint nbits_set = get_nbits_set (*layouts);
664 
665         if (gst_ffmpeg_channel_layout_to_gst (*layouts, nbits_set, pos)) {
666           guint64 mask;
667 
668           if (gst_audio_channel_positions_to_mask (pos, nbits_set, FALSE,
669                   &mask)) {
670             GstStructure *s =
671                 gst_structure_new (mimetype, "channels", G_TYPE_INT, nbits_set,
672                 NULL);
673 
674             /* No need to require a channel mask for mono or stereo */
675             if (!(nbits_set == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_MONO)
676                 && !(nbits_set == 2
677                     && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
678                     && pos[1] == GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT))
679               gst_structure_set (s, "channel-mask", GST_TYPE_BITMASK, mask,
680                   NULL);
681 
682             gst_caps_append_structure (caps, s);
683           }
684         }
685         layouts++;
686       }
687     } else {
688       if (maxchannels == 1)
689         caps = gst_caps_new_simple (mimetype,
690             "channels", G_TYPE_INT, maxchannels, NULL);
691       else
692         caps = gst_caps_new_simple (mimetype,
693             "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
694     }
695 
696     if (n_rates) {
697       GValue list = { 0, };
698 
699       g_value_init (&list, GST_TYPE_LIST);
700       for (i = 0; i < n_rates; i++) {
701         GValue v = { 0, };
702 
703         g_value_init (&v, G_TYPE_INT);
704         g_value_set_int (&v, rates[i]);
705         gst_value_list_append_value (&list, &v);
706         g_value_unset (&v);
707       }
708       gst_caps_set_value (caps, "rate", &list);
709       g_value_unset (&list);
710     } else if (codec && codec->supported_samplerates
711         && codec->supported_samplerates[0]) {
712       GValue va = { 0, };
713       GValue v = { 0, };
714 
715       if (!codec->supported_samplerates[1]) {
716         gst_caps_set_simple (caps, "rate", G_TYPE_INT,
717             codec->supported_samplerates[0], NULL);
718       } else {
719         const int *rates = codec->supported_samplerates;
720 
721         g_value_init (&va, GST_TYPE_LIST);
722         g_value_init (&v, G_TYPE_INT);
723 
724         while (*rates) {
725           g_value_set_int (&v, *rates);
726           gst_value_list_append_value (&va, &v);
727           rates++;
728         }
729         gst_caps_set_value (caps, "rate", &va);
730         g_value_unset (&va);
731         g_value_unset (&v);
732       }
733     } else {
734       gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
735     }
736   } else {
737     caps = gst_caps_new_empty_simple (mimetype);
738   }
739 
740   va_start (var_args, fieldname);
741   gst_caps_set_simple_valist (caps, fieldname, var_args);
742   va_end (var_args);
743 
744   return caps;
745 }
746 
747 /* Check if the given codec ID is an image format -- for now this is just
748  * anything whose caps is image/... */
749 gboolean
gst_ffmpeg_codecid_is_image(enum AVCodecID codec_id)750 gst_ffmpeg_codecid_is_image (enum AVCodecID codec_id)
751 {
752   switch (codec_id) {
753     case AV_CODEC_ID_MJPEG:
754     case AV_CODEC_ID_LJPEG:
755     case AV_CODEC_ID_GIF:
756     case AV_CODEC_ID_PPM:
757     case AV_CODEC_ID_PBM:
758     case AV_CODEC_ID_PCX:
759     case AV_CODEC_ID_SGI:
760     case AV_CODEC_ID_TARGA:
761     case AV_CODEC_ID_TIFF:
762     case AV_CODEC_ID_SUNRAST:
763     case AV_CODEC_ID_BMP:
764       return TRUE;
765 
766     default:
767       return FALSE;
768   }
769 }
770 
771 /* Convert a FFMPEG codec ID and optional AVCodecContext
772  * to a GstCaps. If the context is ommitted, no fixed values
773  * for video/audio size will be included in the GstCaps
774  *
775  * CodecID is primarily meant for compressed data GstCaps!
776  *
777  * encode is a special parameter. gstffmpegdec will say
778  * FALSE, gstffmpegenc will say TRUE. The output caps
779  * depends on this, in such a way that it will be very
780  * specific, defined, fixed and correct caps for encoders,
781  * yet very wide, "forgiving" caps for decoders. Example
782  * for mp3: decode: audio/mpeg,mpegversion=1,layer=[1-3]
783  * but encode: audio/mpeg,mpegversion=1,layer=3,bitrate=x,
784  * rate=x,channels=x.
785  */
786 
787 GstCaps *
gst_ffmpeg_codecid_to_caps(enum AVCodecID codec_id,AVCodecContext * context,gboolean encode)788 gst_ffmpeg_codecid_to_caps (enum AVCodecID codec_id,
789     AVCodecContext * context, gboolean encode)
790 {
791   GstCaps *caps = NULL;
792   gboolean buildcaps = FALSE;
793 
794   GST_LOG ("codec_id:%d, context:%p, encode:%d", codec_id, context, encode);
795 
796   switch (codec_id) {
797     case AV_CODEC_ID_MPEG1VIDEO:
798       /* FIXME: bitrate */
799       caps = gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
800           "mpegversion", G_TYPE_INT, 1,
801           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
802       break;
803 
804     case AV_CODEC_ID_MPEG2VIDEO:
805       if (encode) {
806         /* FIXME: bitrate */
807         caps =
808             gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
809             "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE,
810             NULL);
811       } else {
812         /* decode both MPEG-1 and MPEG-2; width/height/fps are all in
813          * the MPEG video stream headers, so may be omitted from caps. */
814         caps = gst_caps_new_simple ("video/mpeg",
815             "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
816             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
817       }
818       break;
819 
820     case AV_CODEC_ID_H263:
821       if (encode) {
822         caps =
823             gst_ff_vid_caps_new (context, NULL, codec_id, encode,
824             "video/x-h263", "variant", G_TYPE_STRING, "itu", "h263version",
825             G_TYPE_STRING, "h263", NULL);
826       } else {
827         /* don't pass codec_id, we can decode other variants with the H263
828          * decoder that don't have specific size requirements
829          */
830         caps =
831             gst_ff_vid_caps_new (context, NULL, AV_CODEC_ID_NONE, encode,
832             "video/x-h263", "variant", G_TYPE_STRING, "itu", NULL);
833       }
834       break;
835 
836     case AV_CODEC_ID_H263P:
837       caps =
838           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h263",
839           "variant", G_TYPE_STRING, "itu", "h263version", G_TYPE_STRING,
840           "h263p", NULL);
841       if (encode && context) {
842 
843         gst_caps_set_simple (caps,
844             "annex-f", G_TYPE_BOOLEAN, context->flags & AV_CODEC_FLAG_4MV,
845             "annex-j", G_TYPE_BOOLEAN,
846             context->flags & AV_CODEC_FLAG_LOOP_FILTER,
847             "annex-i", G_TYPE_BOOLEAN, context->flags & AV_CODEC_FLAG_AC_PRED,
848             "annex-t", G_TYPE_BOOLEAN, context->flags & AV_CODEC_FLAG_AC_PRED,
849             NULL);
850       }
851       break;
852 
853     case AV_CODEC_ID_H263I:
854       caps =
855           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
856           "video/x-intel-h263", "variant", G_TYPE_STRING, "intel", NULL);
857       break;
858 
859     case AV_CODEC_ID_H261:
860       caps =
861           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h261",
862           NULL);
863       break;
864 
865     case AV_CODEC_ID_RV10:
866     case AV_CODEC_ID_RV20:
867     case AV_CODEC_ID_RV30:
868     case AV_CODEC_ID_RV40:
869     {
870       gint version;
871 
872       switch (codec_id) {
873         case AV_CODEC_ID_RV40:
874           version = 4;
875           break;
876         case AV_CODEC_ID_RV30:
877           version = 3;
878           break;
879         case AV_CODEC_ID_RV20:
880           version = 2;
881           break;
882         default:
883           version = 1;
884           break;
885       }
886 
887       caps =
888           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
889           "video/x-pn-realvideo", "rmversion", G_TYPE_INT, version, NULL);
890       if (context) {
891         if (context->extradata_size >= 8) {
892           gst_caps_set_simple (caps,
893               "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
894               NULL);
895         }
896       }
897     }
898       break;
899 
900 #ifdef OHOS_OPT_COMPAT
901     /* ohos.opt.compat.0001 enable to use avdec_vorbis */
902     case AV_CODEC_ID_VORBIS:
903       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-vorbis", NULL);
904       break;
905 #endif
906     case AV_CODEC_ID_MP1:
907       /* FIXME: bitrate */
908       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
909           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
910       break;
911 
912     case AV_CODEC_ID_MP2:
913       /* FIXME: bitrate */
914       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
915           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
916       break;
917 
918     case AV_CODEC_ID_MP3:
919       if (encode) {
920         /* FIXME: bitrate */
921         caps =
922             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
923             "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
924       } else {
925         /* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
926          * in the MPEG audio header, so may be omitted from caps. */
927         caps = gst_caps_new_simple ("audio/mpeg",
928             "mpegversion", G_TYPE_INT, 1,
929             "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
930       }
931       break;
932 
933     case AV_CODEC_ID_MUSEPACK7:
934       caps =
935           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
936           "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
937           NULL);
938       break;
939 
940     case AV_CODEC_ID_MUSEPACK8:
941       caps =
942           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
943           "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
944           NULL);
945       break;
946 
947     case AV_CODEC_ID_AC3:
948       /* FIXME: bitrate */
949       caps =
950           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-ac3",
951           NULL);
952       break;
953 
954     case AV_CODEC_ID_EAC3:
955       /* FIXME: bitrate */
956       caps =
957           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-eac3",
958           NULL);
959       break;
960 
961     case AV_CODEC_ID_TRUEHD:
962       caps =
963           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
964           "audio/x-true-hd", NULL);
965       break;
966 
967     case AV_CODEC_ID_ATRAC1:
968       caps =
969           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
970           "audio/x-vnd.sony.atrac1", NULL);
971       break;
972 
973     case AV_CODEC_ID_ATRAC3:
974       caps =
975           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
976           "audio/x-vnd.sony.atrac3", NULL);
977       break;
978 
979     case AV_CODEC_ID_DTS:
980       caps =
981           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dts",
982           NULL);
983       break;
984 
985     case AV_CODEC_ID_APE:
986       caps =
987           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
988           "audio/x-ffmpeg-parsed-ape", NULL);
989       if (context) {
990         gst_caps_set_simple (caps,
991             "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
992       }
993       break;
994 
995     case AV_CODEC_ID_MLP:
996       caps =
997           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mlp",
998           NULL);
999       break;
1000 
1001     case AV_CODEC_ID_METASOUND:
1002       caps =
1003           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1004           "audio/x-voxware", NULL);
1005       break;
1006 
1007     case AV_CODEC_ID_IMC:
1008       caps =
1009           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-imc",
1010           NULL);
1011       break;
1012 
1013       /* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
1014        * is Quicktime's MJPEG-B. LJPEG is lossless JPEG. I don't know what
1015        * sp5x is, but it's apparently something JPEG... We don't separate
1016        * between those in GStreamer. Should we (at least between MJPEG,
1017        * MJPEG-B and sp5x decoding...)? */
1018     case AV_CODEC_ID_MJPEG:
1019     case AV_CODEC_ID_LJPEG:
1020       caps =
1021           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/jpeg",
1022           "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
1023       break;
1024 
1025     case AV_CODEC_ID_JPEG2000:
1026       caps =
1027           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-j2c",
1028           NULL);
1029       if (!encode) {
1030         gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1031                 encode, "image/x-jpc", NULL));
1032         gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1033                 encode, "image/jp2", NULL));
1034       }
1035       break;
1036 
1037     case AV_CODEC_ID_SP5X:
1038       caps =
1039           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/sp5x",
1040           NULL);
1041       break;
1042 
1043     case AV_CODEC_ID_MJPEGB:
1044       caps =
1045           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1046           "video/x-mjpeg-b", NULL);
1047       break;
1048 
1049     case AV_CODEC_ID_MPEG4:
1050       if (encode && context != NULL) {
1051         /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
1052          * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
1053         switch (context->codec_tag) {
1054           case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
1055             caps =
1056                 gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1057                 "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL);
1058             break;
1059           case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
1060           default:
1061             /* FIXME: bitrate. libav doesn't expose the used profile and level */
1062             caps =
1063                 gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1064                 "video/mpeg", "systemstream", G_TYPE_BOOLEAN, FALSE,
1065                 "mpegversion", G_TYPE_INT, 4, NULL);
1066             break;
1067         }
1068       } else {
1069         /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
1070         caps =
1071             gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
1072             "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE,
1073             NULL);
1074 
1075         if (encode) {
1076           GValue arr = { 0, };
1077           GValue item = { 0, };
1078 
1079           g_value_init (&arr, GST_TYPE_LIST);
1080           g_value_init (&item, G_TYPE_STRING);
1081           g_value_set_string (&item, "simple");
1082           gst_value_list_append_value (&arr, &item);
1083           g_value_set_string (&item, "advanced-simple");
1084           gst_value_list_append_value (&arr, &item);
1085           g_value_unset (&item);
1086 
1087           gst_caps_set_value (caps, "profile", &arr);
1088           g_value_unset (&arr);
1089 
1090           gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1091                   encode, "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
1092         } else {
1093           gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1094                   encode, "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4,
1095                   5, NULL));
1096         }
1097       }
1098       break;
1099 
1100     case AV_CODEC_ID_RAWVIDEO:
1101       caps =
1102           gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
1103       break;
1104 
1105     case AV_CODEC_ID_MSMPEG4V1:
1106     case AV_CODEC_ID_MSMPEG4V2:
1107     case AV_CODEC_ID_MSMPEG4V3:
1108     {
1109       gint version = 41 + codec_id - AV_CODEC_ID_MSMPEG4V1;
1110 
1111       /* encode-FIXME: bitrate */
1112       caps =
1113           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1114           "video/x-msmpeg", "msmpegversion", G_TYPE_INT, version, NULL);
1115       if (!encode && codec_id == AV_CODEC_ID_MSMPEG4V3) {
1116         gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1117                 encode, "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
1118       }
1119     }
1120       break;
1121 
1122     case AV_CODEC_ID_WMV1:
1123     case AV_CODEC_ID_WMV2:
1124     {
1125       gint version = (codec_id == AV_CODEC_ID_WMV1) ? 1 : 2;
1126 
1127       caps =
1128           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
1129           "wmvversion", G_TYPE_INT, version, NULL);
1130     }
1131       break;
1132 
1133     case AV_CODEC_ID_FLV1:
1134       caps =
1135           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1136           "video/x-flash-video", "flvversion", G_TYPE_INT, 1, NULL);
1137       break;
1138 
1139     case AV_CODEC_ID_SVQ1:
1140       caps =
1141           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
1142           "svqversion", G_TYPE_INT, 1, NULL);
1143       break;
1144 
1145     case AV_CODEC_ID_SVQ3:
1146       caps =
1147           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
1148           "svqversion", G_TYPE_INT, 3, NULL);
1149       break;
1150 
1151     case AV_CODEC_ID_DVAUDIO:
1152       caps =
1153           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dv",
1154           NULL);
1155       break;
1156 
1157     case AV_CODEC_ID_DVVIDEO:
1158     {
1159       if (encode && context) {
1160         const gchar *format;
1161 
1162         switch (context->pix_fmt) {
1163           case AV_PIX_FMT_YUYV422:
1164             format = "YUY2";
1165             break;
1166           case AV_PIX_FMT_YUV420P:
1167             format = "I420";
1168             break;
1169           case AV_PIX_FMT_YUVA420P:
1170             format = "A420";
1171             break;
1172           case AV_PIX_FMT_YUV411P:
1173             format = "Y41B";
1174             break;
1175           case AV_PIX_FMT_YUV422P:
1176             format = "Y42B";
1177             break;
1178           case AV_PIX_FMT_YUV410P:
1179             format = "YUV9";
1180             break;
1181           default:
1182             GST_WARNING
1183                 ("Couldnt' find format for pixfmt %d, defaulting to I420",
1184                 context->pix_fmt);
1185             format = "I420";
1186             break;
1187         }
1188         caps =
1189             gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
1190             "systemstream", G_TYPE_BOOLEAN, FALSE, "format", G_TYPE_STRING,
1191             format, NULL);
1192       } else {
1193         caps =
1194             gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
1195             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1196       }
1197     }
1198       break;
1199 
1200     case AV_CODEC_ID_WMAV1:
1201     case AV_CODEC_ID_WMAV2:
1202     {
1203       gint version = (codec_id == AV_CODEC_ID_WMAV1) ? 1 : 2;
1204 
1205       if (context) {
1206         caps =
1207             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
1208             "wmaversion", G_TYPE_INT, version, "block_align", G_TYPE_INT,
1209             context->block_align, "bitrate", G_TYPE_INT,
1210             (guint) context->bit_rate, NULL);
1211       } else {
1212         caps =
1213             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
1214             "wmaversion", G_TYPE_INT, version, "block_align",
1215             GST_TYPE_INT_RANGE, 0, G_MAXINT, "bitrate", GST_TYPE_INT_RANGE, 0,
1216             G_MAXINT, NULL);
1217       }
1218     }
1219       break;
1220     case AV_CODEC_ID_WMAPRO:
1221     {
1222       caps =
1223           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
1224           "wmaversion", G_TYPE_INT, 3, NULL);
1225       break;
1226     }
1227     case AV_CODEC_ID_WMALOSSLESS:
1228     {
1229       caps =
1230           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
1231           "wmaversion", G_TYPE_INT, 4, NULL);
1232       break;
1233     }
1234     case AV_CODEC_ID_WMAVOICE:
1235     {
1236       caps =
1237           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wms",
1238           NULL);
1239       break;
1240     }
1241 
1242     case AV_CODEC_ID_XMA1:
1243     {
1244       caps =
1245           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-xma",
1246           "xmaversion", G_TYPE_INT, 1, NULL);
1247       break;
1248     }
1249     case AV_CODEC_ID_XMA2:
1250     {
1251       caps =
1252           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-xma",
1253           "xmaversion", G_TYPE_INT, 2, NULL);
1254       break;
1255     }
1256 
1257     case AV_CODEC_ID_MACE3:
1258     case AV_CODEC_ID_MACE6:
1259     {
1260       gint version = (codec_id == AV_CODEC_ID_MACE3) ? 3 : 6;
1261 
1262       caps =
1263           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mace",
1264           "maceversion", G_TYPE_INT, version, NULL);
1265     }
1266       break;
1267 
1268     case AV_CODEC_ID_HUFFYUV:
1269       caps =
1270           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1271           "video/x-huffyuv", NULL);
1272       if (context) {
1273         gst_caps_set_simple (caps,
1274             "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
1275       }
1276       break;
1277 
1278     case AV_CODEC_ID_CYUV:
1279       caps =
1280           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1281           "video/x-compressed-yuv", NULL);
1282       break;
1283 
1284     case AV_CODEC_ID_H264:
1285 #ifdef OHOS_EXT_FUNC
1286       // ohos.ext.func.0013
1287       caps =
1288           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h264", NULL);
1289       if (!encode) {
1290         GValue arr = { 0, };
1291         GValue item = { 0, };
1292         GValue arralign = { 0, };
1293         GValue align = { 0, };
1294         g_value_init (&arr, GST_TYPE_LIST);
1295         g_value_init (&item, G_TYPE_STRING);
1296 
1297         g_value_init (&arralign, GST_TYPE_LIST);
1298         g_value_init (&align, G_TYPE_STRING);
1299 
1300         g_value_set_string (&align, "au");
1301         gst_value_list_append_value (&arralign, &align);
1302         g_value_set_string (&align, "nal");
1303         gst_value_list_append_value (&arralign, &align);
1304         g_value_unset (&align);
1305         gst_caps_set_value (caps, "alignment", &arralign);
1306         g_value_unset (&arralign);
1307 
1308 
1309         g_value_set_string (&item, "avc");
1310         gst_value_list_append_value (&arr, &item);
1311         g_value_set_string (&item, "byte-stream");
1312         gst_value_list_append_value (&arr, &item);
1313         g_value_unset (&item);
1314         gst_caps_set_value (caps, "stream-format", &arr);
1315         g_value_unset (&arr);
1316       }
1317       break;
1318 #else
1319      caps =
1320           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h264",
1321           "alignment", G_TYPE_STRING, "au", NULL);
1322       if (!encode) {
1323         GValue arr = { 0, };
1324         GValue item = { 0, };
1325         g_value_init (&arr, GST_TYPE_LIST);
1326         g_value_init (&item, G_TYPE_STRING);
1327         g_value_set_string (&item, "avc");
1328         gst_value_list_append_value (&arr, &item);
1329         g_value_set_string (&item, "byte-stream");
1330         gst_value_list_append_value (&arr, &item);
1331         g_value_unset (&item);
1332         gst_caps_set_value (caps, "stream-format", &arr);
1333         g_value_unset (&arr);
1334 
1335         gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
1336                 encode, "video/x-h264", "alignment", G_TYPE_STRING, "nal",
1337                 "stream-format", G_TYPE_STRING, "byte-stream", NULL));
1338 
1339       } else if (context) {
1340         /* FIXME: ffmpeg currently assumes AVC if there is extradata and
1341          * byte-stream otherwise. See for example the MOV or MPEG-TS code.
1342          * ffmpeg does not distinguish the different types of AVC. */
1343         if (context->extradata_size > 0) {
1344           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "avc",
1345               NULL);
1346         } else {
1347           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING,
1348               "byte-stream", NULL);
1349         }
1350       }
1351       break;
1352 #endif
1353     case AV_CODEC_ID_HEVC:
1354       caps =
1355           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h265",
1356           "alignment", G_TYPE_STRING, "au", NULL);
1357       if (!encode) {
1358         GValue arr = { 0, };
1359         GValue item = { 0, };
1360         g_value_init (&arr, GST_TYPE_LIST);
1361         g_value_init (&item, G_TYPE_STRING);
1362         g_value_set_string (&item, "hvc1");
1363         gst_value_list_append_value (&arr, &item);
1364         g_value_set_string (&item, "hev1");
1365         gst_value_list_append_value (&arr, &item);
1366         g_value_set_string (&item, "byte-stream");
1367         gst_value_list_append_value (&arr, &item);
1368         g_value_unset (&item);
1369         gst_caps_set_value (caps, "stream-format", &arr);
1370         g_value_unset (&arr);
1371       } else if (context) {
1372         /* FIXME: ffmpeg currently assumes HVC1 if there is extradata and
1373          * byte-stream otherwise. See for example the MOV or MPEG-TS code.
1374          * ffmpeg does not distinguish the different types: HVC1/HEV1/etc. */
1375         if (context->extradata_size > 0) {
1376           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "hvc1",
1377               NULL);
1378         } else {
1379           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING,
1380               "byte-stream", NULL);
1381         }
1382       }
1383       break;
1384 
1385     case AV_CODEC_ID_INDEO5:
1386       caps =
1387           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
1388           "indeoversion", G_TYPE_INT, 5, NULL);
1389       break;
1390 
1391     case AV_CODEC_ID_INDEO4:
1392       caps =
1393           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
1394           "indeoversion", G_TYPE_INT, 4, NULL);
1395       break;
1396 
1397     case AV_CODEC_ID_INDEO3:
1398       caps =
1399           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
1400           "indeoversion", G_TYPE_INT, 3, NULL);
1401       break;
1402 
1403     case AV_CODEC_ID_INDEO2:
1404       caps =
1405           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
1406           "indeoversion", G_TYPE_INT, 2, NULL);
1407       break;
1408 
1409     case AV_CODEC_ID_FLASHSV:
1410       caps =
1411           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1412           "video/x-flash-screen", NULL);
1413       break;
1414 
1415     case AV_CODEC_ID_FLASHSV2:
1416       caps =
1417           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1418           "video/x-flash-screen2", NULL);
1419       break;
1420 
1421     case AV_CODEC_ID_VP3:
1422       caps =
1423           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp3",
1424           NULL);
1425       break;
1426 
1427     case AV_CODEC_ID_VP5:
1428       caps =
1429           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp5",
1430           NULL);
1431       break;
1432 
1433     case AV_CODEC_ID_VP6:
1434       caps =
1435           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp6",
1436           NULL);
1437       break;
1438 
1439     case AV_CODEC_ID_VP6F:
1440       caps =
1441           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1442           "video/x-vp6-flash", NULL);
1443       break;
1444 
1445     case AV_CODEC_ID_VP6A:
1446       caps =
1447           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1448           "video/x-vp6-alpha", NULL);
1449       break;
1450 
1451     case AV_CODEC_ID_VP8:
1452       caps =
1453           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp8",
1454           NULL);
1455       break;
1456 
1457     case AV_CODEC_ID_VP9:
1458       caps =
1459           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp9",
1460           NULL);
1461       break;
1462 
1463     case AV_CODEC_ID_THEORA:
1464       caps =
1465           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1466           "video/x-theora", NULL);
1467       break;
1468 
1469     case AV_CODEC_ID_CFHD:
1470       caps =
1471           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1472           "video/x-cineform", NULL);
1473       break;
1474 
1475     case AV_CODEC_ID_SPEEDHQ:
1476       if (context && context->codec_tag) {
1477         gchar *variant = g_strdup_printf ("%" GST_FOURCC_FORMAT,
1478             GST_FOURCC_ARGS (context->codec_tag));
1479         caps =
1480             gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1481             "video/x-speedhq", "variant", G_TYPE_STRING, variant, NULL);
1482         g_free (variant);
1483       } else {
1484         caps =
1485             gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1486             "video/x-speedhq", NULL);
1487       }
1488       break;
1489 
1490     case AV_CODEC_ID_AAC:
1491     {
1492       caps =
1493           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
1494           NULL);
1495 
1496       if (!encode) {
1497         GValue arr = { 0, };
1498         GValue item = { 0, };
1499 
1500         g_value_init (&arr, GST_TYPE_LIST);
1501         g_value_init (&item, G_TYPE_INT);
1502         g_value_set_int (&item, 2);
1503         gst_value_list_append_value (&arr, &item);
1504         g_value_set_int (&item, 4);
1505         gst_value_list_append_value (&arr, &item);
1506         g_value_unset (&item);
1507 
1508         gst_caps_set_value (caps, "mpegversion", &arr);
1509         g_value_unset (&arr);
1510 
1511         g_value_init (&arr, GST_TYPE_LIST);
1512         g_value_init (&item, G_TYPE_STRING);
1513         g_value_set_string (&item, "raw");
1514         gst_value_list_append_value (&arr, &item);
1515         g_value_set_string (&item, "adts");
1516         gst_value_list_append_value (&arr, &item);
1517         g_value_set_string (&item, "adif");
1518         gst_value_list_append_value (&arr, &item);
1519         g_value_unset (&item);
1520 
1521         gst_caps_set_value (caps, "stream-format", &arr);
1522         g_value_unset (&arr);
1523       } else {
1524         gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 4,
1525             "base-profile", G_TYPE_STRING, "lc", NULL);
1526 
1527         /* FIXME: ffmpeg currently assumes raw if there is extradata and
1528          * ADTS otherwise. See for example the FDK AAC encoder. */
1529         if (context && context->extradata_size > 0) {
1530           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "raw",
1531               NULL);
1532           gst_codec_utils_aac_caps_set_level_and_profile (caps,
1533               context->extradata, context->extradata_size);
1534         } else if (context) {
1535           gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING, "adts",
1536               NULL);
1537         }
1538       }
1539 
1540       break;
1541     }
1542     case AV_CODEC_ID_AAC_LATM: /* LATM/LOAS AAC syntax */
1543       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
1544           "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "loas",
1545           NULL);
1546       break;
1547 
1548     case AV_CODEC_ID_ASV1:
1549       caps =
1550           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
1551           "asusversion", G_TYPE_INT, 1, NULL);
1552       break;
1553     case AV_CODEC_ID_ASV2:
1554       caps =
1555           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
1556           "asusversion", G_TYPE_INT, 2, NULL);
1557       break;
1558 
1559     case AV_CODEC_ID_FFV1:
1560       caps =
1561           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-ffv",
1562           "ffvversion", G_TYPE_INT, 1, NULL);
1563       break;
1564 
1565     case AV_CODEC_ID_4XM:
1566       caps =
1567           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-4xm",
1568           NULL);
1569       break;
1570 
1571     case AV_CODEC_ID_XAN_WC3:
1572     case AV_CODEC_ID_XAN_WC4:
1573       caps =
1574           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-xan",
1575           "wcversion", G_TYPE_INT, 3 - AV_CODEC_ID_XAN_WC3 + codec_id, NULL);
1576       break;
1577 
1578     case AV_CODEC_ID_CLJR:
1579       caps =
1580           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1581           "video/x-cirrus-logic-accupak", NULL);
1582       break;
1583 
1584     case AV_CODEC_ID_FRAPS:
1585       caps =
1586           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-fraps",
1587           NULL);
1588       break;
1589 
1590     case AV_CODEC_ID_MDEC:
1591     case AV_CODEC_ID_ROQ:
1592     case AV_CODEC_ID_INTERPLAY_VIDEO:
1593       buildcaps = TRUE;
1594       break;
1595 
1596     case AV_CODEC_ID_VCR1:
1597       caps =
1598           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1599           "video/x-ati-vcr", "vcrversion", G_TYPE_INT, 1, NULL);
1600       break;
1601 
1602     case AV_CODEC_ID_RPZA:
1603       caps =
1604           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1605           "video/x-apple-video", NULL);
1606       break;
1607 
1608     case AV_CODEC_ID_CINEPAK:
1609       caps =
1610           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1611           "video/x-cinepak", NULL);
1612       break;
1613 
1614       /* WS_VQA belogns here (order) */
1615 
1616     case AV_CODEC_ID_MSRLE:
1617       caps =
1618           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
1619           "layout", G_TYPE_STRING, "microsoft", NULL);
1620       if (context) {
1621         gst_caps_set_simple (caps,
1622             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1623       } else {
1624         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
1625       }
1626       break;
1627 
1628     case AV_CODEC_ID_QTRLE:
1629       caps =
1630           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
1631           "layout", G_TYPE_STRING, "quicktime", NULL);
1632       if (context) {
1633         gst_caps_set_simple (caps,
1634             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1635       } else {
1636         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
1637       }
1638       break;
1639 
1640     case AV_CODEC_ID_MSVIDEO1:
1641       caps =
1642           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1643           "video/x-msvideocodec", "msvideoversion", G_TYPE_INT, 1, NULL);
1644       break;
1645 
1646     case AV_CODEC_ID_MSS1:
1647       caps =
1648           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
1649           "wmvversion", G_TYPE_INT, 1, "format", G_TYPE_STRING, "MSS1", NULL);
1650       break;
1651 
1652     case AV_CODEC_ID_MSS2:
1653       caps =
1654           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
1655           "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "MSS2", NULL);
1656       break;
1657 
1658     case AV_CODEC_ID_WMV3:
1659       caps =
1660           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
1661           "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WMV3", NULL);
1662       break;
1663     case AV_CODEC_ID_VC1:
1664       caps =
1665           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
1666           "wmvversion", G_TYPE_INT, 3, NULL);
1667       if (!context && !encode) {
1668         GValue arr = { 0, };
1669         GValue item = { 0, };
1670 
1671         g_value_init (&arr, GST_TYPE_LIST);
1672         g_value_init (&item, G_TYPE_STRING);
1673         g_value_set_string (&item, "WVC1");
1674         gst_value_list_append_value (&arr, &item);
1675         g_value_set_string (&item, "WMVA");
1676         gst_value_list_append_and_take_value (&arr, &item);
1677         gst_caps_set_value (caps, "format", &arr);
1678         g_value_unset (&arr);
1679       } else {
1680         gst_caps_set_simple (caps, "format", G_TYPE_STRING, "WVC1", NULL);
1681       }
1682       break;
1683     case AV_CODEC_ID_QDM2:
1684       caps =
1685           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-qdm2",
1686           NULL);
1687       break;
1688 
1689     case AV_CODEC_ID_MSZH:
1690       caps =
1691           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-mszh",
1692           NULL);
1693       break;
1694 
1695     case AV_CODEC_ID_ZLIB:
1696       caps =
1697           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-zlib",
1698           NULL);
1699       break;
1700 
1701     case AV_CODEC_ID_TRUEMOTION1:
1702       caps =
1703           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1704           "video/x-truemotion", "trueversion", G_TYPE_INT, 1, NULL);
1705       break;
1706     case AV_CODEC_ID_TRUEMOTION2:
1707       caps =
1708           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1709           "video/x-truemotion", "trueversion", G_TYPE_INT, 2, NULL);
1710       break;
1711 
1712     case AV_CODEC_ID_ULTI:
1713       caps =
1714           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1715           "video/x-ultimotion", NULL);
1716       break;
1717 
1718     case AV_CODEC_ID_TSCC:
1719       caps =
1720           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1721           "video/x-camtasia", NULL);
1722       if (context) {
1723         gst_caps_set_simple (caps,
1724             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1725       } else {
1726         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
1727       }
1728       break;
1729 
1730     case AV_CODEC_ID_TSCC2:
1731       caps =
1732           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1733           "video/x-tscc", "tsccversion", G_TYPE_INT, 2, NULL);
1734       break;
1735 
1736     case AV_CODEC_ID_KMVC:
1737       caps =
1738           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-kmvc",
1739           NULL);
1740       break;
1741 
1742     case AV_CODEC_ID_NUV:
1743       caps =
1744           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-nuv",
1745           NULL);
1746       break;
1747 
1748     case AV_CODEC_ID_GIF:
1749       caps =
1750           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1751           "image/gst-libav-gif", "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
1752       break;
1753 
1754     case AV_CODEC_ID_PNG:
1755       caps =
1756           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/png",
1757           NULL);
1758       break;
1759 
1760     case AV_CODEC_ID_PPM:
1761       caps =
1762           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/ppm",
1763           NULL);
1764       break;
1765 
1766     case AV_CODEC_ID_PBM:
1767       caps =
1768           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/pbm",
1769           NULL);
1770       break;
1771 
1772     case AV_CODEC_ID_PAM:
1773       caps =
1774           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1775           "image/x-portable-anymap", NULL);
1776       break;
1777 
1778     case AV_CODEC_ID_PGM:
1779       caps =
1780           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1781           "image/x-portable-graymap", NULL);
1782       break;
1783 
1784     case AV_CODEC_ID_PCX:
1785       caps =
1786           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-pcx",
1787           NULL);
1788       break;
1789 
1790     case AV_CODEC_ID_SGI:
1791       caps =
1792           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-sgi",
1793           NULL);
1794       break;
1795 
1796     case AV_CODEC_ID_TARGA:
1797       caps =
1798           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-tga",
1799           NULL);
1800       break;
1801 
1802     case AV_CODEC_ID_TIFF:
1803       caps =
1804           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/tiff",
1805           NULL);
1806       break;
1807 
1808     case AV_CODEC_ID_SUNRAST:
1809       caps =
1810           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1811           "image/x-sun-raster", NULL);
1812       break;
1813 
1814     case AV_CODEC_ID_SMC:
1815       caps =
1816           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-smc",
1817           NULL);
1818       break;
1819 
1820     case AV_CODEC_ID_QDRAW:
1821       caps =
1822           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-qdrw",
1823           NULL);
1824       break;
1825 
1826     case AV_CODEC_ID_DNXHD:
1827       caps =
1828           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dnxhd",
1829           NULL);
1830       break;
1831 
1832     case AV_CODEC_ID_PRORES:
1833       caps =
1834           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1835           "video/x-prores", NULL);
1836       if (context) {
1837         switch (context->codec_tag) {
1838           case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
1839             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "proxy", NULL);
1840             break;
1841           case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
1842             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "lt", NULL);
1843             break;
1844           default:
1845           case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
1846             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "standard",
1847                 NULL);
1848             break;
1849           case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
1850             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "hq", NULL);
1851             break;
1852           case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
1853             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "4444", NULL);
1854             break;
1855           case GST_MAKE_FOURCC ('a', 'p', '4', 'x'):
1856             gst_caps_set_simple (caps, "variant", G_TYPE_STRING, "4444xq",
1857                 NULL);
1858             break;
1859         }
1860       }
1861       break;
1862 
1863     case AV_CODEC_ID_MIMIC:
1864       caps =
1865           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-mimic",
1866           NULL);
1867       break;
1868 
1869     case AV_CODEC_ID_VMNC:
1870       caps =
1871           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vmnc",
1872           NULL);
1873       break;
1874 
1875     case AV_CODEC_ID_TRUESPEECH:
1876       caps =
1877           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1878           "audio/x-truespeech", NULL);
1879       break;
1880 
1881     case AV_CODEC_ID_QCELP:
1882       caps =
1883           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/qcelp",
1884           NULL);
1885       break;
1886 
1887     case AV_CODEC_ID_AMV:
1888       caps =
1889           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-amv",
1890           NULL);
1891       break;
1892 
1893     case AV_CODEC_ID_AASC:
1894       caps =
1895           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-aasc",
1896           NULL);
1897       break;
1898 
1899     case AV_CODEC_ID_LOCO:
1900       caps =
1901           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-loco",
1902           NULL);
1903       break;
1904 
1905     case AV_CODEC_ID_ZMBV:
1906       caps =
1907           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-zmbv",
1908           NULL);
1909       break;
1910 
1911     case AV_CODEC_ID_LAGARITH:
1912       caps =
1913           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1914           "video/x-lagarith", NULL);
1915       break;
1916 
1917     case AV_CODEC_ID_CSCD:
1918       caps =
1919           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1920           "video/x-camstudio", NULL);
1921       if (context) {
1922         gst_caps_set_simple (caps,
1923             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1924       } else {
1925         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
1926       }
1927       break;
1928 
1929     case AV_CODEC_ID_AIC:
1930       caps =
1931           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1932           "video/x-apple-intermediate-codec", NULL);
1933       break;
1934 
1935     case AV_CODEC_ID_CAVS:
1936       caps =
1937           gst_ff_vid_caps_new (context, NULL, codec_id, encode,
1938           "video/x-cavs", NULL);
1939       break;
1940 
1941     case AV_CODEC_ID_WS_VQA:
1942     case AV_CODEC_ID_IDCIN:
1943     case AV_CODEC_ID_8BPS:
1944     case AV_CODEC_ID_FLIC:
1945     case AV_CODEC_ID_VMDVIDEO:
1946     case AV_CODEC_ID_VMDAUDIO:
1947     case AV_CODEC_ID_VIXL:
1948     case AV_CODEC_ID_QPEG:
1949     case AV_CODEC_ID_PGMYUV:
1950     case AV_CODEC_ID_FFVHUFF:
1951     case AV_CODEC_ID_WNV1:
1952     case AV_CODEC_ID_MP3ADU:
1953     case AV_CODEC_ID_MP3ON4:
1954     case AV_CODEC_ID_WESTWOOD_SND1:
1955     case AV_CODEC_ID_MMVIDEO:
1956     case AV_CODEC_ID_AVS:
1957       buildcaps = TRUE;
1958       break;
1959 
1960       /* weird quasi-codecs for the demuxers only */
1961     case AV_CODEC_ID_PCM_S16LE:
1962     case AV_CODEC_ID_PCM_S16BE:
1963     case AV_CODEC_ID_PCM_U16LE:
1964     case AV_CODEC_ID_PCM_U16BE:
1965     case AV_CODEC_ID_PCM_S8:
1966     case AV_CODEC_ID_PCM_U8:
1967 #ifdef OHOS_OPT_COMPAT
1968     /* ohos.opt.compat.xxxx enable s24le */
1969     case AV_CODEC_ID_PCM_S24LE:
1970     /* ohos.opt.compat.xxxx enable s32le */
1971     case AV_CODEC_ID_PCM_S32LE:
1972     /* ohos.opt.compat.xxxx enable f32le */
1973     case AV_CODEC_ID_PCM_F32LE:
1974 #endif
1975     {
1976       GstAudioFormat format;
1977 
1978       switch (codec_id) {
1979         case AV_CODEC_ID_PCM_S16LE:
1980           format = GST_AUDIO_FORMAT_S16LE;
1981           break;
1982         case AV_CODEC_ID_PCM_S16BE:
1983           format = GST_AUDIO_FORMAT_S16BE;
1984           break;
1985         case AV_CODEC_ID_PCM_U16LE:
1986           format = GST_AUDIO_FORMAT_U16LE;
1987           break;
1988         case AV_CODEC_ID_PCM_U16BE:
1989           format = GST_AUDIO_FORMAT_U16BE;
1990           break;
1991         case AV_CODEC_ID_PCM_S8:
1992           format = GST_AUDIO_FORMAT_S8;
1993           break;
1994         case AV_CODEC_ID_PCM_U8:
1995           format = GST_AUDIO_FORMAT_U8;
1996           break;
1997 #ifdef OHOS_OPT_COMPAT
1998        /* ohos.opt.compat.xxxx enable s24le */
1999         case AV_CODEC_ID_PCM_S24LE:
2000           format = GST_AUDIO_FORMAT_S24LE;
2001           break;
2002        /* ohos.opt.compat.xxxx enable s32le */
2003         case AV_CODEC_ID_PCM_S32LE:
2004           format = GST_AUDIO_FORMAT_S32LE;
2005           break;
2006         /* ohos.opt.compat.xxxx enable f32le */
2007         case AV_CODEC_ID_PCM_F32LE:
2008           format = GST_AUDIO_FORMAT_F32LE;
2009           break;
2010 #endif
2011         default:
2012           format = 0;
2013           g_assert (0);         /* don't worry, we never get here */
2014           break;
2015       }
2016 
2017       caps =
2018           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-raw",
2019           "format", G_TYPE_STRING, gst_audio_format_to_string (format),
2020           "layout", G_TYPE_STRING, "interleaved", NULL);
2021     }
2022       break;
2023 
2024     case AV_CODEC_ID_PCM_MULAW:
2025       caps =
2026           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mulaw",
2027           NULL);
2028       break;
2029 
2030     case AV_CODEC_ID_PCM_ALAW:
2031       caps =
2032           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alaw",
2033           NULL);
2034       break;
2035 
2036     case AV_CODEC_ID_ADPCM_G722:
2037       caps =
2038           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/G722",
2039           NULL);
2040       if (context)
2041         gst_caps_set_simple (caps,
2042             "block_align", G_TYPE_INT, context->block_align,
2043             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2044       break;
2045 
2046     case AV_CODEC_ID_ADPCM_G726:
2047     {
2048       /* the G726 decoder can also handle G721 */
2049       caps =
2050           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
2051           "layout", G_TYPE_STRING, "g726", NULL);
2052       if (context)
2053         gst_caps_set_simple (caps,
2054             "block_align", G_TYPE_INT, context->block_align,
2055             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2056 
2057       if (!encode) {
2058         gst_caps_append (caps, gst_caps_new_simple ("audio/x-adpcm",
2059                 "layout", G_TYPE_STRING, "g721",
2060                 "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL));
2061       }
2062       break;
2063     }
2064     case AV_CODEC_ID_ADPCM_IMA_QT:
2065     case AV_CODEC_ID_ADPCM_IMA_WAV:
2066     case AV_CODEC_ID_ADPCM_IMA_DK3:
2067     case AV_CODEC_ID_ADPCM_IMA_DK4:
2068     case AV_CODEC_ID_ADPCM_IMA_OKI:
2069     case AV_CODEC_ID_ADPCM_IMA_WS:
2070     case AV_CODEC_ID_ADPCM_IMA_SMJPEG:
2071     case AV_CODEC_ID_ADPCM_IMA_AMV:
2072     case AV_CODEC_ID_ADPCM_IMA_ISS:
2073     case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
2074     case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
2075     case AV_CODEC_ID_ADPCM_MS:
2076     case AV_CODEC_ID_ADPCM_4XM:
2077     case AV_CODEC_ID_ADPCM_XA:
2078     case AV_CODEC_ID_ADPCM_ADX:
2079     case AV_CODEC_ID_ADPCM_EA:
2080     case AV_CODEC_ID_ADPCM_CT:
2081     case AV_CODEC_ID_ADPCM_SWF:
2082     case AV_CODEC_ID_ADPCM_YAMAHA:
2083     case AV_CODEC_ID_ADPCM_SBPRO_2:
2084     case AV_CODEC_ID_ADPCM_SBPRO_3:
2085     case AV_CODEC_ID_ADPCM_SBPRO_4:
2086     case AV_CODEC_ID_ADPCM_EA_R1:
2087     case AV_CODEC_ID_ADPCM_EA_R2:
2088     case AV_CODEC_ID_ADPCM_EA_R3:
2089     case AV_CODEC_ID_ADPCM_EA_MAXIS_XA:
2090     case AV_CODEC_ID_ADPCM_EA_XAS:
2091     case AV_CODEC_ID_ADPCM_THP:
2092     {
2093       const gchar *layout = NULL;
2094 
2095       switch (codec_id) {
2096         case AV_CODEC_ID_ADPCM_IMA_QT:
2097           layout = "quicktime";
2098           break;
2099         case AV_CODEC_ID_ADPCM_IMA_WAV:
2100           layout = "dvi";
2101           break;
2102         case AV_CODEC_ID_ADPCM_IMA_DK3:
2103           layout = "dk3";
2104           break;
2105         case AV_CODEC_ID_ADPCM_IMA_DK4:
2106           layout = "dk4";
2107           break;
2108         case AV_CODEC_ID_ADPCM_IMA_OKI:
2109           layout = "oki";
2110           break;
2111         case AV_CODEC_ID_ADPCM_IMA_WS:
2112           layout = "westwood";
2113           break;
2114         case AV_CODEC_ID_ADPCM_IMA_SMJPEG:
2115           layout = "smjpeg";
2116           break;
2117         case AV_CODEC_ID_ADPCM_IMA_AMV:
2118           layout = "amv";
2119           break;
2120         case AV_CODEC_ID_ADPCM_IMA_ISS:
2121           layout = "iss";
2122           break;
2123         case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
2124           layout = "ea-eacs";
2125           break;
2126         case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
2127           layout = "ea-sead";
2128           break;
2129         case AV_CODEC_ID_ADPCM_MS:
2130           layout = "microsoft";
2131           break;
2132         case AV_CODEC_ID_ADPCM_4XM:
2133           layout = "4xm";
2134           break;
2135         case AV_CODEC_ID_ADPCM_XA:
2136           layout = "xa";
2137           break;
2138         case AV_CODEC_ID_ADPCM_ADX:
2139           layout = "adx";
2140           break;
2141         case AV_CODEC_ID_ADPCM_EA:
2142           layout = "ea";
2143           break;
2144         case AV_CODEC_ID_ADPCM_CT:
2145           layout = "ct";
2146           break;
2147         case AV_CODEC_ID_ADPCM_SWF:
2148           layout = "swf";
2149           break;
2150         case AV_CODEC_ID_ADPCM_YAMAHA:
2151           layout = "yamaha";
2152           break;
2153         case AV_CODEC_ID_ADPCM_SBPRO_2:
2154           layout = "sbpro2";
2155           break;
2156         case AV_CODEC_ID_ADPCM_SBPRO_3:
2157           layout = "sbpro3";
2158           break;
2159         case AV_CODEC_ID_ADPCM_SBPRO_4:
2160           layout = "sbpro4";
2161           break;
2162         case AV_CODEC_ID_ADPCM_EA_R1:
2163           layout = "ea-r1";
2164           break;
2165         case AV_CODEC_ID_ADPCM_EA_R2:
2166           layout = "ea-r3";
2167           break;
2168         case AV_CODEC_ID_ADPCM_EA_R3:
2169           layout = "ea-r3";
2170           break;
2171         case AV_CODEC_ID_ADPCM_EA_MAXIS_XA:
2172           layout = "ea-maxis-xa";
2173           break;
2174         case AV_CODEC_ID_ADPCM_EA_XAS:
2175           layout = "ea-xas";
2176           break;
2177         case AV_CODEC_ID_ADPCM_THP:
2178           layout = "thp";
2179           break;
2180         default:
2181           g_assert (0);         /* don't worry, we never get here */
2182           break;
2183       }
2184 
2185       /* FIXME: someone please check whether we need additional properties
2186        * in this caps definition. */
2187       caps =
2188           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
2189           "layout", G_TYPE_STRING, layout, NULL);
2190       if (context)
2191         gst_caps_set_simple (caps,
2192             "block_align", G_TYPE_INT, context->block_align,
2193             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2194     }
2195       break;
2196 
2197     case AV_CODEC_ID_AMR_NB:
2198       caps =
2199           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR",
2200           NULL);
2201       break;
2202 
2203     case AV_CODEC_ID_AMR_WB:
2204       caps =
2205           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR-WB",
2206           NULL);
2207       break;
2208 
2209     case AV_CODEC_ID_GSM:
2210       caps =
2211           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-gsm",
2212           NULL);
2213       break;
2214 
2215     case AV_CODEC_ID_GSM_MS:
2216       caps =
2217           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/ms-gsm",
2218           NULL);
2219       break;
2220 
2221     case AV_CODEC_ID_NELLYMOSER:
2222       caps =
2223           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2224           "audio/x-nellymoser", NULL);
2225       break;
2226 
2227     case AV_CODEC_ID_SIPR:
2228     {
2229       caps =
2230           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-sipro",
2231           NULL);
2232       if (context) {
2233         gst_caps_set_simple (caps,
2234             "leaf_size", G_TYPE_INT, context->block_align,
2235             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2236       }
2237     }
2238       break;
2239 
2240     case AV_CODEC_ID_RA_144:
2241     case AV_CODEC_ID_RA_288:
2242     case AV_CODEC_ID_COOK:
2243     {
2244       gint version = 0;
2245 
2246       switch (codec_id) {
2247         case AV_CODEC_ID_RA_144:
2248           version = 1;
2249           break;
2250         case AV_CODEC_ID_RA_288:
2251           version = 2;
2252           break;
2253         case AV_CODEC_ID_COOK:
2254           version = 8;
2255           break;
2256         default:
2257           break;
2258       }
2259 
2260       /* FIXME: properties? */
2261       caps =
2262           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2263           "audio/x-pn-realaudio", "raversion", G_TYPE_INT, version, NULL);
2264       if (context) {
2265         gst_caps_set_simple (caps,
2266             "leaf_size", G_TYPE_INT, context->block_align,
2267             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2268       }
2269     }
2270       break;
2271 
2272     case AV_CODEC_ID_ROQ_DPCM:
2273     case AV_CODEC_ID_INTERPLAY_DPCM:
2274     case AV_CODEC_ID_XAN_DPCM:
2275     case AV_CODEC_ID_SOL_DPCM:
2276     {
2277       const gchar *layout = NULL;
2278 
2279       switch (codec_id) {
2280         case AV_CODEC_ID_ROQ_DPCM:
2281           layout = "roq";
2282           break;
2283         case AV_CODEC_ID_INTERPLAY_DPCM:
2284           layout = "interplay";
2285           break;
2286         case AV_CODEC_ID_XAN_DPCM:
2287           layout = "xan";
2288           break;
2289         case AV_CODEC_ID_SOL_DPCM:
2290           layout = "sol";
2291           break;
2292         default:
2293           g_assert (0);         /* don't worry, we never get here */
2294           break;
2295       }
2296 
2297       /* FIXME: someone please check whether we need additional properties
2298        * in this caps definition. */
2299       caps =
2300           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dpcm",
2301           "layout", G_TYPE_STRING, layout, NULL);
2302       if (context)
2303         gst_caps_set_simple (caps,
2304             "block_align", G_TYPE_INT, context->block_align,
2305             "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2306     }
2307       break;
2308 
2309     case AV_CODEC_ID_SHORTEN:
2310       caps = gst_caps_new_empty_simple ("audio/x-shorten");
2311       break;
2312 
2313     case AV_CODEC_ID_ALAC:
2314       caps =
2315           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alac",
2316           NULL);
2317       if (context) {
2318         gst_caps_set_simple (caps,
2319             "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
2320       }
2321       break;
2322 
2323     case AV_CODEC_ID_FLAC:
2324       /* Note that ffmpeg has no encoder yet, but just for safety. In the
2325        * encoder case, we want to add things like samplerate, channels... */
2326       if (!encode) {
2327         caps = gst_caps_new_empty_simple ("audio/x-flac");
2328       }
2329       break;
2330 
2331     case AV_CODEC_ID_OPUS:
2332 #ifdef OHOS_EXT_FUNC
2333       // ohos.ext.func.0023
2334       caps = gst_caps_new_empty_simple ("audio/x-opus");
2335       break;
2336 #else
2337       /* Note that ffmpeg has no encoder yet, but just for safety. In the
2338        * encoder case, we want to add things like samplerate, channels... */
2339       if (!encode) {
2340         /* FIXME: can ffmpeg handle multichannel Opus? */
2341         caps = gst_caps_new_simple ("audio/x-opus",
2342             "channel-mapping-family", G_TYPE_INT, 0, NULL);
2343       }
2344       break;
2345 #endif
2346 
2347     case AV_CODEC_ID_S302M:
2348       caps = gst_caps_new_empty_simple ("audio/x-smpte-302m");
2349       break;
2350 
2351     case AV_CODEC_ID_DVD_SUBTITLE:
2352     case AV_CODEC_ID_DVB_SUBTITLE:
2353       caps = NULL;
2354       break;
2355     case AV_CODEC_ID_BMP:
2356       caps = gst_caps_new_empty_simple ("image/bmp");
2357       break;
2358     case AV_CODEC_ID_TTA:
2359       caps =
2360           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-tta",
2361           NULL);
2362       if (context) {
2363         gst_caps_set_simple (caps,
2364             "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
2365       }
2366       break;
2367     case AV_CODEC_ID_TWINVQ:
2368       caps =
2369           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2370           "audio/x-twin-vq", NULL);
2371       break;
2372     case AV_CODEC_ID_G729:
2373       caps =
2374           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/G729",
2375           NULL);
2376       break;
2377     case AV_CODEC_ID_DSD_LSBF:
2378       caps =
2379           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
2380           NULL);
2381       gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
2382           TRUE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
2383       break;
2384     case AV_CODEC_ID_DSD_MSBF:
2385       caps =
2386           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
2387           NULL);
2388       gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
2389           FALSE, "planar", G_TYPE_BOOLEAN, FALSE, NULL);
2390       break;
2391     case AV_CODEC_ID_DSD_LSBF_PLANAR:
2392       caps =
2393           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
2394           NULL);
2395       gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
2396           TRUE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
2397       break;
2398     case AV_CODEC_ID_DSD_MSBF_PLANAR:
2399       caps =
2400           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dsd",
2401           NULL);
2402       gst_caps_set_simple (caps, "lsbf", G_TYPE_BOOLEAN,
2403           FALSE, "planar", G_TYPE_BOOLEAN, TRUE, NULL);
2404       break;
2405     case AV_CODEC_ID_APTX:
2406       caps =
2407           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/aptx",
2408           NULL);
2409       break;
2410     case AV_CODEC_ID_APTX_HD:
2411       caps =
2412           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/aptx-hd",
2413           NULL);
2414       break;
2415     case AV_CODEC_ID_AV1:
2416       caps =
2417           gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-av1",
2418           NULL);
2419       break;
2420     default:
2421       GST_DEBUG ("Unknown codec ID %d, please add mapping here", codec_id);
2422       break;
2423   }
2424 
2425   if (buildcaps) {
2426     const AVCodec *codec;
2427 
2428     if ((codec = avcodec_find_decoder (codec_id)) ||
2429         (codec = avcodec_find_encoder (codec_id))) {
2430       gchar *mime = NULL;
2431 
2432       GST_LOG ("Could not create stream format caps for %s", codec->name);
2433 
2434       switch (codec->type) {
2435         case AVMEDIA_TYPE_VIDEO:
2436           mime = g_strdup_printf ("video/x-gst-av-%s", codec->name);
2437           caps =
2438               gst_ff_vid_caps_new (context, NULL, codec_id, encode, mime, NULL);
2439           g_free (mime);
2440           break;
2441         case AVMEDIA_TYPE_AUDIO:
2442           mime = g_strdup_printf ("audio/x-gst-av-%s", codec->name);
2443           caps =
2444               gst_ff_aud_caps_new (context, NULL, codec_id, encode, mime, NULL);
2445           if (context)
2446             gst_caps_set_simple (caps,
2447                 "block_align", G_TYPE_INT, context->block_align,
2448                 "bitrate", G_TYPE_INT, (guint) context->bit_rate, NULL);
2449           g_free (mime);
2450           break;
2451         default:
2452           break;
2453       }
2454     }
2455   }
2456 
2457   if (caps != NULL) {
2458 
2459     /* set private data */
2460     if (context && context->extradata_size > 0) {
2461       GstBuffer *data = gst_buffer_new_and_alloc (context->extradata_size);
2462 
2463       gst_buffer_fill (data, 0, context->extradata, context->extradata_size);
2464       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, data, NULL);
2465       gst_buffer_unref (data);
2466     }
2467 
2468     GST_LOG ("caps for codec_id=%d: %" GST_PTR_FORMAT, codec_id, caps);
2469 
2470   } else {
2471     GST_LOG ("No caps found for codec_id=%d", codec_id);
2472   }
2473 
2474   return caps;
2475 }
2476 
2477 /* Convert a FFMPEG Pixel Format and optional AVCodecContext
2478  * to a GstCaps. If the context is ommitted, no fixed values
2479  * for video/audio size will be included in the GstCaps
2480  *
2481  * See below for usefullness
2482  */
2483 
2484 static GstCaps *
gst_ffmpeg_pixfmt_to_caps(enum AVPixelFormat pix_fmt,AVCodecContext * context,enum AVCodecID codec_id)2485 gst_ffmpeg_pixfmt_to_caps (enum AVPixelFormat pix_fmt, AVCodecContext * context,
2486     enum AVCodecID codec_id)
2487 {
2488   GstCaps *caps = NULL;
2489   GstVideoFormat format;
2490 
2491   format = gst_ffmpeg_pixfmt_to_videoformat (pix_fmt);
2492 
2493   if (format != GST_VIDEO_FORMAT_UNKNOWN) {
2494     caps = gst_ff_vid_caps_new (context, NULL, codec_id, TRUE, "video/x-raw",
2495         "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
2496   }
2497 
2498   if (caps != NULL) {
2499     GST_DEBUG ("caps for pix_fmt=%d: %" GST_PTR_FORMAT, pix_fmt, caps);
2500   } else {
2501     GST_LOG ("No caps found for pix_fmt=%d", pix_fmt);
2502   }
2503 
2504   return caps;
2505 }
2506 
2507 GstAudioFormat
gst_ffmpeg_smpfmt_to_audioformat(enum AVSampleFormat sample_fmt,GstAudioLayout * layout)2508 gst_ffmpeg_smpfmt_to_audioformat (enum AVSampleFormat sample_fmt,
2509     GstAudioLayout * layout)
2510 {
2511   if (layout)
2512     *layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
2513 
2514   switch (sample_fmt) {
2515     case AV_SAMPLE_FMT_U8:
2516       if (layout)
2517         *layout = GST_AUDIO_LAYOUT_INTERLEAVED;
2518     case AV_SAMPLE_FMT_U8P:
2519       return GST_AUDIO_FORMAT_U8;
2520       break;
2521 
2522     case AV_SAMPLE_FMT_S16:
2523       if (layout)
2524         *layout = GST_AUDIO_LAYOUT_INTERLEAVED;
2525     case AV_SAMPLE_FMT_S16P:
2526       return GST_AUDIO_FORMAT_S16;
2527       break;
2528 
2529     case AV_SAMPLE_FMT_S32:
2530       if (layout)
2531         *layout = GST_AUDIO_LAYOUT_INTERLEAVED;
2532     case AV_SAMPLE_FMT_S32P:
2533       return GST_AUDIO_FORMAT_S32;
2534       break;
2535     case AV_SAMPLE_FMT_FLT:
2536       if (layout)
2537         *layout = GST_AUDIO_LAYOUT_INTERLEAVED;
2538     case AV_SAMPLE_FMT_FLTP:
2539       return GST_AUDIO_FORMAT_F32;
2540       break;
2541 
2542     case AV_SAMPLE_FMT_DBL:
2543       if (layout)
2544         *layout = GST_AUDIO_LAYOUT_INTERLEAVED;
2545     case AV_SAMPLE_FMT_DBLP:
2546       return GST_AUDIO_FORMAT_F64;
2547       break;
2548 
2549     default:
2550       /* .. */
2551       return GST_AUDIO_FORMAT_UNKNOWN;
2552       break;
2553   }
2554 }
2555 
2556 /* Convert a FFMPEG Sample Format and optional AVCodecContext
2557  * to a GstCaps. If the context is ommitted, no fixed values
2558  * for video/audio size will be included in the GstCaps
2559  *
2560  * See below for usefullness
2561  */
2562 
2563 static GstCaps *
gst_ffmpeg_smpfmt_to_caps(enum AVSampleFormat sample_fmt,AVCodecContext * context,AVCodec * codec,enum AVCodecID codec_id)2564 gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
2565     AVCodecContext * context, AVCodec * codec, enum AVCodecID codec_id)
2566 {
2567   GstCaps *caps = NULL;
2568   GstAudioFormat format;
2569   GstAudioLayout layout;
2570 
2571   format = gst_ffmpeg_smpfmt_to_audioformat (sample_fmt, &layout);
2572 
2573   if (format != GST_AUDIO_FORMAT_UNKNOWN) {
2574     caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
2575         "format", G_TYPE_STRING, gst_audio_format_to_string (format),
2576         "layout", G_TYPE_STRING,
2577         (layout == GST_AUDIO_LAYOUT_INTERLEAVED) ?
2578         "interleaved" : "non-interleaved", NULL);
2579     GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
2580   } else {
2581     GST_LOG ("No caps found for sample_fmt=%d", sample_fmt);
2582   }
2583 
2584   return caps;
2585 }
2586 
2587 static gboolean
caps_has_field(GstCaps * caps,const gchar * field)2588 caps_has_field (GstCaps * caps, const gchar * field)
2589 {
2590   guint i, n;
2591 
2592   n = gst_caps_get_size (caps);
2593   for (i = 0; i < n; i++) {
2594     GstStructure *s = gst_caps_get_structure (caps, i);
2595 
2596     if (gst_structure_has_field (s, field))
2597       return TRUE;
2598   }
2599 
2600   return FALSE;
2601 }
2602 
2603 GstCaps *
gst_ffmpeg_codectype_to_audio_caps(AVCodecContext * context,enum AVCodecID codec_id,gboolean encode,AVCodec * codec)2604 gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
2605     enum AVCodecID codec_id, gboolean encode, AVCodec * codec)
2606 {
2607   GstCaps *caps = NULL;
2608 
2609   GST_DEBUG ("context:%p, codec_id:%d, encode:%d, codec:%p",
2610       context, codec_id, encode, codec);
2611   if (codec)
2612     GST_DEBUG ("sample_fmts:%p, samplerates:%p",
2613         codec->sample_fmts, codec->supported_samplerates);
2614 
2615   if (context) {
2616     /* Specific codec context */
2617     caps =
2618         gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec,
2619         codec_id);
2620   } else {
2621     caps = gst_ff_aud_caps_new (context, codec, codec_id, encode, "audio/x-raw",
2622         NULL);
2623     if (!caps_has_field (caps, "format"))
2624       gst_ffmpeg_audio_set_sample_fmts (caps,
2625           codec ? codec->sample_fmts : NULL, encode);
2626   }
2627 
2628   return caps;
2629 }
2630 
2631 GstCaps *
gst_ffmpeg_codectype_to_video_caps(AVCodecContext * context,enum AVCodecID codec_id,gboolean encode,AVCodec * codec)2632 gst_ffmpeg_codectype_to_video_caps (AVCodecContext * context,
2633     enum AVCodecID codec_id, gboolean encode, AVCodec * codec)
2634 {
2635   GstCaps *caps;
2636 
2637   GST_LOG ("context:%p, codec_id:%d, encode:%d, codec:%p",
2638       context, codec_id, encode, codec);
2639 
2640   if (context) {
2641     caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
2642   } else {
2643     caps =
2644         gst_ff_vid_caps_new (context, codec, codec_id, encode, "video/x-raw",
2645         NULL);
2646     if (!caps_has_field (caps, "format"))
2647       gst_ffmpeg_video_set_pix_fmts (caps, codec ? codec->pix_fmts : NULL);
2648   }
2649   return caps;
2650 }
2651 
2652 /* Convert a GstCaps (audio/raw) to a FFMPEG SampleFmt
2653  * and other audio properties in a AVCodecContext.
2654  *
2655  * For usefullness, see below
2656  */
2657 
2658 static void
gst_ffmpeg_caps_to_smpfmt(const GstCaps * caps,AVCodecContext * context,gboolean raw)2659 gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps,
2660     AVCodecContext * context, gboolean raw)
2661 {
2662   GstStructure *structure;
2663   const gchar *fmt;
2664   GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
2665   gint bitrate;
2666   const gchar *layout;
2667   gboolean interleaved;
2668 
2669   g_return_if_fail (gst_caps_get_size (caps) == 1);
2670 
2671   structure = gst_caps_get_structure (caps, 0);
2672 
2673   gst_structure_get_int (structure, "channels", &context->channels);
2674   gst_structure_get_int (structure, "rate", &context->sample_rate);
2675   gst_structure_get_int (structure, "block_align", &context->block_align);
2676   if (gst_structure_get_int (structure, "bitrate", &bitrate))
2677     context->bit_rate = bitrate;
2678 
2679   if (!raw)
2680     return;
2681 
2682   if (gst_structure_has_name (structure, "audio/x-raw")) {
2683     if ((fmt = gst_structure_get_string (structure, "format"))) {
2684       format = gst_audio_format_from_string (fmt);
2685     }
2686   }
2687 
2688   layout = gst_structure_get_string (structure, "layout");
2689   interleaved = ! !g_strcmp0 (layout, "non-interleaved");
2690 
2691   switch (format) {
2692     case GST_AUDIO_FORMAT_F32:
2693       context->sample_fmt =
2694           interleaved ? AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_FLTP;
2695       break;
2696     case GST_AUDIO_FORMAT_F64:
2697       context->sample_fmt =
2698           interleaved ? AV_SAMPLE_FMT_DBL : AV_SAMPLE_FMT_DBLP;
2699       break;
2700     case GST_AUDIO_FORMAT_S32:
2701       context->sample_fmt =
2702           interleaved ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S32P;
2703       break;
2704     case GST_AUDIO_FORMAT_S16:
2705       context->sample_fmt =
2706           interleaved ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_S16P;
2707       break;
2708     default:
2709       break;
2710   }
2711 }
2712 
2713 /* Convert a GstCaps (video/raw) to a FFMPEG PixFmt
2714  * and other video properties in a AVCodecContext.
2715  *
2716  * For usefullness, see below
2717  */
2718 
2719 static void
gst_ffmpeg_caps_to_pixfmt(const GstCaps * caps,AVCodecContext * context,gboolean raw)2720 gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
2721     AVCodecContext * context, gboolean raw)
2722 {
2723   GstStructure *structure;
2724   const GValue *fps;
2725   const GValue *par = NULL;
2726   const gchar *fmt;
2727   GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
2728   const gchar *s;
2729 
2730   GST_DEBUG ("converting caps %" GST_PTR_FORMAT, caps);
2731   g_return_if_fail (gst_caps_get_size (caps) == 1);
2732   structure = gst_caps_get_structure (caps, 0);
2733 
2734   gst_structure_get_int (structure, "width", &context->width);
2735   gst_structure_get_int (structure, "height", &context->height);
2736   gst_structure_get_int (structure, "bpp", &context->bits_per_coded_sample);
2737 
2738   fps = gst_structure_get_value (structure, "framerate");
2739   if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
2740 
2741     int num = gst_value_get_fraction_numerator (fps);
2742     int den = gst_value_get_fraction_denominator (fps);
2743 
2744     if (num > 0 && den > 0) {
2745       /* somehow these seem mixed up.. */
2746       /* they're fine, this is because it does period=1/frequency */
2747       context->time_base.den = gst_value_get_fraction_numerator (fps);
2748       context->time_base.num = gst_value_get_fraction_denominator (fps);
2749       context->ticks_per_frame = 1;
2750 
2751       GST_DEBUG ("setting framerate %d/%d = %lf",
2752           context->time_base.den, context->time_base.num,
2753           1. * context->time_base.den / context->time_base.num);
2754     } else {
2755       GST_INFO ("ignoring framerate %d/%d (probably variable framerate)",
2756           context->time_base.num, context->time_base.den);
2757     }
2758   }
2759 
2760   par = gst_structure_get_value (structure, "pixel-aspect-ratio");
2761   if (par && GST_VALUE_HOLDS_FRACTION (par)) {
2762 
2763     int num = gst_value_get_fraction_numerator (par);
2764     int den = gst_value_get_fraction_denominator (par);
2765 
2766     if (num > 0 && den > 0) {
2767       context->sample_aspect_ratio.num = num;
2768       context->sample_aspect_ratio.den = den;
2769 
2770       GST_DEBUG ("setting pixel-aspect-ratio %d/%d = %lf",
2771           context->sample_aspect_ratio.num, context->sample_aspect_ratio.den,
2772           1. * context->sample_aspect_ratio.num /
2773           context->sample_aspect_ratio.den);
2774     } else {
2775       GST_WARNING ("ignoring insane pixel-aspect-ratio %d/%d",
2776           context->sample_aspect_ratio.num, context->sample_aspect_ratio.den);
2777     }
2778   }
2779 
2780   if (!raw)
2781     return;
2782 
2783   g_return_if_fail (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps));
2784 
2785   if (gst_structure_has_name (structure, "video/x-raw")) {
2786     if ((fmt = gst_structure_get_string (structure, "format"))) {
2787       format = gst_video_format_from_string (fmt);
2788     }
2789   }
2790 
2791   switch (format) {
2792     case GST_VIDEO_FORMAT_YUY2:
2793       context->pix_fmt = AV_PIX_FMT_YUYV422;
2794       break;
2795     case GST_VIDEO_FORMAT_I420:
2796       context->pix_fmt = AV_PIX_FMT_YUV420P;
2797       break;
2798     case GST_VIDEO_FORMAT_A420:
2799       context->pix_fmt = AV_PIX_FMT_YUVA420P;
2800       break;
2801     case GST_VIDEO_FORMAT_Y41B:
2802       context->pix_fmt = AV_PIX_FMT_YUV411P;
2803       break;
2804     case GST_VIDEO_FORMAT_Y42B:
2805       context->pix_fmt = AV_PIX_FMT_YUV422P;
2806       break;
2807     case GST_VIDEO_FORMAT_YUV9:
2808       context->pix_fmt = AV_PIX_FMT_YUV410P;
2809       break;
2810     case GST_VIDEO_FORMAT_Y444:
2811       context->pix_fmt = AV_PIX_FMT_YUV444P;
2812       break;
2813     case GST_VIDEO_FORMAT_GRAY8:
2814       context->pix_fmt = AV_PIX_FMT_GRAY8;
2815       break;
2816     case GST_VIDEO_FORMAT_xRGB:
2817 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
2818       context->pix_fmt = AV_PIX_FMT_RGB32;
2819 #endif
2820       break;
2821     case GST_VIDEO_FORMAT_BGRx:
2822 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
2823       context->pix_fmt = AV_PIX_FMT_RGB32;
2824 #endif
2825       break;
2826     case GST_VIDEO_FORMAT_RGB:
2827       context->pix_fmt = AV_PIX_FMT_RGB24;
2828       break;
2829     case GST_VIDEO_FORMAT_BGR:
2830       context->pix_fmt = AV_PIX_FMT_BGR24;
2831       break;
2832     case GST_VIDEO_FORMAT_RGB16:
2833       context->pix_fmt = AV_PIX_FMT_RGB565;
2834       break;
2835     case GST_VIDEO_FORMAT_RGB15:
2836       context->pix_fmt = AV_PIX_FMT_RGB555;
2837       break;
2838     case GST_VIDEO_FORMAT_RGB8P:
2839       context->pix_fmt = AV_PIX_FMT_PAL8;
2840       break;
2841     default:
2842       break;
2843   }
2844 
2845   s = gst_structure_get_string (structure, "interlace-mode");
2846   if (s) {
2847     if (strcmp (s, "progressive") == 0) {
2848       context->field_order = AV_FIELD_PROGRESSIVE;
2849     } else if (strcmp (s, "interleaved") == 0) {
2850       s = gst_structure_get_string (structure, "field-order");
2851       if (s) {
2852         if (strcmp (s, "top-field-first") == 0) {
2853           context->field_order = AV_FIELD_TT;
2854         } else if (strcmp (s, "bottom-field-first") == 0) {
2855           context->field_order = AV_FIELD_TB;
2856         }
2857       }
2858     }
2859   }
2860 }
2861 
2862 typedef struct
2863 {
2864   GstVideoFormat format;
2865   enum AVPixelFormat pixfmt;
2866 } PixToFmt;
2867 
2868 /* FIXME : FILLME */
2869 static const PixToFmt pixtofmttable[] = {
2870   /* GST_VIDEO_FORMAT_I420, */
2871   {GST_VIDEO_FORMAT_I420, AV_PIX_FMT_YUV420P},
2872   /* Note : this should use a different chroma placement */
2873   {GST_VIDEO_FORMAT_I420, AV_PIX_FMT_YUVJ420P},
2874 
2875   /* GST_VIDEO_FORMAT_YV12, */
2876   /* GST_VIDEO_FORMAT_YUY2, */
2877   {GST_VIDEO_FORMAT_YUY2, AV_PIX_FMT_YUYV422},
2878   /* GST_VIDEO_FORMAT_UYVY, */
2879   {GST_VIDEO_FORMAT_UYVY, AV_PIX_FMT_UYVY422},
2880   /* GST_VIDEO_FORMAT_AYUV, */
2881   /* GST_VIDEO_FORMAT_RGBx, */
2882   {GST_VIDEO_FORMAT_RGBx, AV_PIX_FMT_RGB0},
2883   /* GST_VIDEO_FORMAT_BGRx, */
2884   {GST_VIDEO_FORMAT_BGRx, AV_PIX_FMT_BGR0},
2885   /* GST_VIDEO_FORMAT_xRGB, */
2886   {GST_VIDEO_FORMAT_xRGB, AV_PIX_FMT_0RGB},
2887   /* GST_VIDEO_FORMAT_xBGR, */
2888   {GST_VIDEO_FORMAT_xBGR, AV_PIX_FMT_0BGR},
2889   /* GST_VIDEO_FORMAT_RGBA, */
2890   {GST_VIDEO_FORMAT_RGBA, AV_PIX_FMT_RGBA},
2891   /* GST_VIDEO_FORMAT_BGRA, */
2892   {GST_VIDEO_FORMAT_BGRA, AV_PIX_FMT_BGRA},
2893   /* GST_VIDEO_FORMAT_ARGB, */
2894   {GST_VIDEO_FORMAT_ARGB, AV_PIX_FMT_ARGB},
2895   /* GST_VIDEO_FORMAT_ABGR, */
2896   {GST_VIDEO_FORMAT_ABGR, AV_PIX_FMT_ABGR},
2897   /* GST_VIDEO_FORMAT_RGB, */
2898   {GST_VIDEO_FORMAT_RGB, AV_PIX_FMT_RGB24},
2899   /* GST_VIDEO_FORMAT_BGR, */
2900   {GST_VIDEO_FORMAT_BGR, AV_PIX_FMT_BGR24},
2901   /* GST_VIDEO_FORMAT_Y41B, */
2902   {GST_VIDEO_FORMAT_Y41B, AV_PIX_FMT_YUV411P},
2903   /* GST_VIDEO_FORMAT_Y42B, */
2904   {GST_VIDEO_FORMAT_Y42B, AV_PIX_FMT_YUV422P},
2905   {GST_VIDEO_FORMAT_Y42B, AV_PIX_FMT_YUVJ422P},
2906   /* GST_VIDEO_FORMAT_YVYU, */
2907   /* GST_VIDEO_FORMAT_Y444, */
2908   {GST_VIDEO_FORMAT_Y444, AV_PIX_FMT_YUV444P},
2909   {GST_VIDEO_FORMAT_Y444, AV_PIX_FMT_YUVJ444P},
2910   /* GST_VIDEO_FORMAT_v210, */
2911   /* GST_VIDEO_FORMAT_v216, */
2912   /* GST_VIDEO_FORMAT_NV12, */
2913   {GST_VIDEO_FORMAT_NV12, AV_PIX_FMT_NV12},
2914   /* GST_VIDEO_FORMAT_NV21, */
2915   {GST_VIDEO_FORMAT_NV21, AV_PIX_FMT_NV21},
2916   /* GST_VIDEO_FORMAT_GRAY8, */
2917   {GST_VIDEO_FORMAT_GRAY8, AV_PIX_FMT_GRAY8},
2918   /* GST_VIDEO_FORMAT_GRAY16_BE, */
2919   {GST_VIDEO_FORMAT_GRAY16_BE, AV_PIX_FMT_GRAY16BE},
2920   /* GST_VIDEO_FORMAT_GRAY16_LE, */
2921   {GST_VIDEO_FORMAT_GRAY16_LE, AV_PIX_FMT_GRAY16LE},
2922   /* GST_VIDEO_FORMAT_v308, */
2923   /* GST_VIDEO_FORMAT_Y800, */
2924   /* GST_VIDEO_FORMAT_Y16, */
2925   /* GST_VIDEO_FORMAT_RGB16, */
2926   {GST_VIDEO_FORMAT_RGB16, AV_PIX_FMT_RGB565},
2927   /* GST_VIDEO_FORMAT_BGR16, */
2928   /* GST_VIDEO_FORMAT_RGB15, */
2929   {GST_VIDEO_FORMAT_RGB15, AV_PIX_FMT_RGB555},
2930   /* GST_VIDEO_FORMAT_BGR15, */
2931   /* GST_VIDEO_FORMAT_UYVP, */
2932   /* GST_VIDEO_FORMAT_A420, */
2933   {GST_VIDEO_FORMAT_A420, AV_PIX_FMT_YUVA420P},
2934   /* GST_VIDEO_FORMAT_RGB8_PALETTED, */
2935   {GST_VIDEO_FORMAT_RGB8P, AV_PIX_FMT_PAL8},
2936   /* GST_VIDEO_FORMAT_YUV9, */
2937   {GST_VIDEO_FORMAT_YUV9, AV_PIX_FMT_YUV410P},
2938   /* GST_VIDEO_FORMAT_YVU9, */
2939   /* GST_VIDEO_FORMAT_IYU1, */
2940   /* GST_VIDEO_FORMAT_ARGB64, */
2941   /* GST_VIDEO_FORMAT_AYUV64, */
2942   /* GST_VIDEO_FORMAT_r210, */
2943   {GST_VIDEO_FORMAT_I420_10LE, AV_PIX_FMT_YUV420P10LE},
2944   {GST_VIDEO_FORMAT_I420_10BE, AV_PIX_FMT_YUV420P10BE},
2945   {GST_VIDEO_FORMAT_I422_10LE, AV_PIX_FMT_YUV422P10LE},
2946   {GST_VIDEO_FORMAT_I422_10BE, AV_PIX_FMT_YUV422P10BE},
2947   {GST_VIDEO_FORMAT_Y444_10LE, AV_PIX_FMT_YUV444P10LE},
2948   {GST_VIDEO_FORMAT_Y444_10BE, AV_PIX_FMT_YUV444P10BE},
2949   {GST_VIDEO_FORMAT_GBR, AV_PIX_FMT_GBRP},
2950   {GST_VIDEO_FORMAT_GBRA, AV_PIX_FMT_GBRAP},
2951   {GST_VIDEO_FORMAT_GBR_10LE, AV_PIX_FMT_GBRP10LE},
2952   {GST_VIDEO_FORMAT_GBR_10BE, AV_PIX_FMT_GBRP10BE},
2953   {GST_VIDEO_FORMAT_GBRA_10LE, AV_PIX_FMT_GBRAP10LE},
2954   {GST_VIDEO_FORMAT_GBRA_10BE, AV_PIX_FMT_GBRAP10BE},
2955   {GST_VIDEO_FORMAT_GBR_12LE, AV_PIX_FMT_GBRP12LE},
2956   {GST_VIDEO_FORMAT_GBR_12BE, AV_PIX_FMT_GBRP12BE},
2957   {GST_VIDEO_FORMAT_GBRA_12LE, AV_PIX_FMT_GBRAP12LE},
2958   {GST_VIDEO_FORMAT_GBRA_12BE, AV_PIX_FMT_GBRAP12BE},
2959   {GST_VIDEO_FORMAT_A420_10LE, AV_PIX_FMT_YUVA420P10LE},
2960   {GST_VIDEO_FORMAT_A420_10BE, AV_PIX_FMT_YUVA420P10BE},
2961   {GST_VIDEO_FORMAT_A422_10LE, AV_PIX_FMT_YUVA422P10LE},
2962   {GST_VIDEO_FORMAT_A422_10BE, AV_PIX_FMT_YUVA422P10BE},
2963   {GST_VIDEO_FORMAT_A444_10LE, AV_PIX_FMT_YUVA444P10LE},
2964   {GST_VIDEO_FORMAT_A444_10BE, AV_PIX_FMT_YUVA444P10BE},
2965   {GST_VIDEO_FORMAT_I420_12LE, AV_PIX_FMT_YUV420P12LE},
2966   {GST_VIDEO_FORMAT_I420_12BE, AV_PIX_FMT_YUV420P12BE},
2967   {GST_VIDEO_FORMAT_I422_12LE, AV_PIX_FMT_YUV422P12LE},
2968   {GST_VIDEO_FORMAT_I422_12BE, AV_PIX_FMT_YUV422P12BE},
2969   {GST_VIDEO_FORMAT_Y444_12LE, AV_PIX_FMT_YUV444P12LE},
2970   {GST_VIDEO_FORMAT_Y444_12BE, AV_PIX_FMT_YUV444P12BE},
2971 };
2972 
2973 GstVideoFormat
gst_ffmpeg_pixfmt_to_videoformat(enum AVPixelFormat pixfmt)2974 gst_ffmpeg_pixfmt_to_videoformat (enum AVPixelFormat pixfmt)
2975 {
2976   guint i;
2977 
2978   for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++)
2979     if (pixtofmttable[i].pixfmt == pixfmt)
2980       return pixtofmttable[i].format;
2981 
2982   GST_DEBUG ("Unknown pixel format %d", pixfmt);
2983   return GST_VIDEO_FORMAT_UNKNOWN;
2984 }
2985 
2986 static enum AVPixelFormat
gst_ffmpeg_videoformat_to_pixfmt_for_codec(GstVideoFormat format,const AVCodec * codec)2987 gst_ffmpeg_videoformat_to_pixfmt_for_codec (GstVideoFormat format,
2988     const AVCodec * codec)
2989 {
2990   guint i;
2991 
2992   for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++) {
2993     if (pixtofmttable[i].format == format) {
2994       gint j;
2995 
2996       if (codec && codec->pix_fmts) {
2997         for (j = 0; codec->pix_fmts[j] != -1; j++) {
2998           if (pixtofmttable[i].pixfmt == codec->pix_fmts[j])
2999             return pixtofmttable[i].pixfmt;
3000         }
3001       } else {
3002         return pixtofmttable[i].pixfmt;
3003       }
3004     }
3005   }
3006 
3007   return AV_PIX_FMT_NONE;
3008 }
3009 
3010 enum AVPixelFormat
gst_ffmpeg_videoformat_to_pixfmt(GstVideoFormat format)3011 gst_ffmpeg_videoformat_to_pixfmt (GstVideoFormat format)
3012 {
3013   return gst_ffmpeg_videoformat_to_pixfmt_for_codec (format, NULL);
3014 }
3015 
3016 void
gst_ffmpeg_videoinfo_to_context(GstVideoInfo * info,AVCodecContext * context)3017 gst_ffmpeg_videoinfo_to_context (GstVideoInfo * info, AVCodecContext * context)
3018 {
3019   gint i, bpp = 0;
3020 
3021   context->width = GST_VIDEO_INFO_WIDTH (info);
3022   context->height = GST_VIDEO_INFO_HEIGHT (info);
3023   for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
3024     bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
3025   context->bits_per_coded_sample = bpp;
3026 
3027   context->ticks_per_frame = 1;
3028   if (GST_VIDEO_INFO_FPS_N (info) == 0) {
3029     GST_DEBUG ("Using 25/1 framerate");
3030     context->time_base.den = 25;
3031     context->time_base.num = 1;
3032   } else {
3033     context->time_base.den = GST_VIDEO_INFO_FPS_N (info);
3034     context->time_base.num = GST_VIDEO_INFO_FPS_D (info);
3035   }
3036 
3037   context->sample_aspect_ratio.num = GST_VIDEO_INFO_PAR_N (info);
3038   context->sample_aspect_ratio.den = GST_VIDEO_INFO_PAR_D (info);
3039 
3040   context->pix_fmt =
3041       gst_ffmpeg_videoformat_to_pixfmt_for_codec (GST_VIDEO_INFO_FORMAT (info),
3042       context->codec);
3043 
3044   switch (info->chroma_site) {
3045     case GST_VIDEO_CHROMA_SITE_MPEG2:
3046       context->chroma_sample_location = AVCHROMA_LOC_LEFT;
3047       break;
3048     case GST_VIDEO_CHROMA_SITE_JPEG:
3049       context->chroma_sample_location = AVCHROMA_LOC_CENTER;
3050       break;
3051     case GST_VIDEO_CHROMA_SITE_DV:
3052       context->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
3053       break;
3054     case GST_VIDEO_CHROMA_SITE_V_COSITED:
3055       context->chroma_sample_location = AVCHROMA_LOC_TOP;
3056       break;
3057     default:
3058       break;
3059   }
3060 
3061   context->color_primaries =
3062       gst_video_color_primaries_to_iso (info->colorimetry.primaries);
3063   context->color_trc =
3064       gst_video_transfer_function_to_iso (info->colorimetry.transfer);
3065   context->colorspace =
3066       gst_video_color_matrix_to_iso (info->colorimetry.matrix);
3067 
3068   if (info->colorimetry.range == GST_VIDEO_COLOR_RANGE_0_255) {
3069     context->color_range = AVCOL_RANGE_JPEG;
3070   } else {
3071     context->color_range = AVCOL_RANGE_MPEG;
3072     context->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL;
3073   }
3074 }
3075 
3076 void
gst_ffmpeg_audioinfo_to_context(GstAudioInfo * info,AVCodecContext * context)3077 gst_ffmpeg_audioinfo_to_context (GstAudioInfo * info, AVCodecContext * context)
3078 {
3079   const AVCodec *codec;
3080   const enum AVSampleFormat *smpl_fmts;
3081   enum AVSampleFormat smpl_fmt = -1;
3082 
3083   context->channels = info->channels;
3084   context->sample_rate = info->rate;
3085   context->channel_layout =
3086       gst_ffmpeg_channel_positions_to_layout (info->position, info->channels);
3087 
3088   codec = context->codec;
3089 
3090   smpl_fmts = codec->sample_fmts;
3091 
3092   switch (info->finfo->format) {
3093     case GST_AUDIO_FORMAT_F32:
3094       if (smpl_fmts) {
3095         while (*smpl_fmts != -1) {
3096           if (*smpl_fmts == AV_SAMPLE_FMT_FLT) {
3097             smpl_fmt = *smpl_fmts;
3098             break;
3099           } else if (*smpl_fmts == AV_SAMPLE_FMT_FLTP) {
3100             smpl_fmt = *smpl_fmts;
3101           }
3102 
3103           smpl_fmts++;
3104         }
3105       } else {
3106         smpl_fmt = AV_SAMPLE_FMT_FLT;
3107       }
3108       break;
3109     case GST_AUDIO_FORMAT_F64:
3110       if (smpl_fmts) {
3111         while (*smpl_fmts != -1) {
3112           if (*smpl_fmts == AV_SAMPLE_FMT_DBL) {
3113             smpl_fmt = *smpl_fmts;
3114             break;
3115           } else if (*smpl_fmts == AV_SAMPLE_FMT_DBLP) {
3116             smpl_fmt = *smpl_fmts;
3117           }
3118 
3119           smpl_fmts++;
3120         }
3121       } else {
3122         smpl_fmt = AV_SAMPLE_FMT_DBL;
3123       }
3124       break;
3125     case GST_AUDIO_FORMAT_S32:
3126       if (smpl_fmts) {
3127         while (*smpl_fmts != -1) {
3128           if (*smpl_fmts == AV_SAMPLE_FMT_S32) {
3129             smpl_fmt = *smpl_fmts;
3130             break;
3131           } else if (*smpl_fmts == AV_SAMPLE_FMT_S32P) {
3132             smpl_fmt = *smpl_fmts;
3133           }
3134 
3135           smpl_fmts++;
3136         }
3137       } else {
3138         smpl_fmt = AV_SAMPLE_FMT_S32;
3139       }
3140       break;
3141     case GST_AUDIO_FORMAT_S16:
3142       if (smpl_fmts) {
3143         while (*smpl_fmts != -1) {
3144           if (*smpl_fmts == AV_SAMPLE_FMT_S16) {
3145             smpl_fmt = *smpl_fmts;
3146             break;
3147           } else if (*smpl_fmts == AV_SAMPLE_FMT_S16P) {
3148             smpl_fmt = *smpl_fmts;
3149           }
3150 
3151           smpl_fmts++;
3152         }
3153       } else {
3154         smpl_fmt = AV_SAMPLE_FMT_S16;
3155       }
3156       break;
3157     case GST_AUDIO_FORMAT_U8:
3158       if (smpl_fmts) {
3159         while (*smpl_fmts != -1) {
3160           if (*smpl_fmts == AV_SAMPLE_FMT_U8) {
3161             smpl_fmt = *smpl_fmts;
3162             break;
3163           } else if (*smpl_fmts == AV_SAMPLE_FMT_U8P) {
3164             smpl_fmt = *smpl_fmts;
3165           }
3166 
3167           smpl_fmts++;
3168         }
3169       } else {
3170         smpl_fmt = AV_SAMPLE_FMT_U8;
3171       }
3172       break;
3173     default:
3174       break;
3175   }
3176 
3177   g_assert (smpl_fmt != -1);
3178 
3179   context->sample_fmt = smpl_fmt;
3180 }
3181 
3182 /* Convert a GstCaps and a FFMPEG codec Type to a
3183  * AVCodecContext. If the context is ommitted, no fixed values
3184  * for video/audio size will be included in the context
3185  *
3186  * AVMediaType is primarily meant for uncompressed data GstCaps!
3187  */
3188 
3189 void
gst_ffmpeg_caps_with_codectype(enum AVMediaType type,const GstCaps * caps,AVCodecContext * context)3190 gst_ffmpeg_caps_with_codectype (enum AVMediaType type,
3191     const GstCaps * caps, AVCodecContext * context)
3192 {
3193   if (context == NULL)
3194     return;
3195 
3196   switch (type) {
3197     case AVMEDIA_TYPE_VIDEO:
3198       gst_ffmpeg_caps_to_pixfmt (caps, context, TRUE);
3199       break;
3200 
3201     case AVMEDIA_TYPE_AUDIO:
3202       gst_ffmpeg_caps_to_smpfmt (caps, context, TRUE);
3203       break;
3204 
3205     default:
3206       /* unknown */
3207       break;
3208   }
3209 }
3210 
3211 #if 0
3212 static void
3213 nal_escape (guint8 * dst, guint8 * src, guint size, guint * destsize)
3214 {
3215   guint8 *dstp = dst;
3216   guint8 *srcp = src;
3217   guint8 *end = src + size;
3218   gint count = 0;
3219 
3220   while (srcp < end) {
3221     if (count == 2 && *srcp <= 0x03) {
3222       GST_DEBUG ("added escape code");
3223       *dstp++ = 0x03;
3224       count = 0;
3225     }
3226     if (*srcp == 0)
3227       count++;
3228     else
3229       count = 0;
3230 
3231     GST_DEBUG ("copy %02x, count %d", *srcp, count);
3232     *dstp++ = *srcp++;
3233   }
3234   *destsize = dstp - dst;
3235 }
3236 
3237 /* copy the config, escaping NAL units as we iterate them, if something fails we
3238  * copy everything and hope for the best. */
3239 static void
3240 copy_config (guint8 * dst, guint8 * src, guint size, guint * destsize)
3241 {
3242   guint8 *dstp = dst;
3243   guint8 *srcp = src;
3244   gint cnt, i;
3245   guint nalsize, esize;
3246 
3247   /* check size */
3248   if (size < 7)
3249     goto full_copy;
3250 
3251   /* check version */
3252   if (*srcp != 1)
3253     goto full_copy;
3254 
3255   cnt = *(srcp + 5) & 0x1f;     /* Number of sps */
3256 
3257   GST_DEBUG ("num SPS %d", cnt);
3258 
3259   memcpy (dstp, srcp, 6);
3260   srcp += 6;
3261   dstp += 6;
3262 
3263   for (i = 0; i < cnt; i++) {
3264     GST_DEBUG ("copy SPS %d", i);
3265     nalsize = (srcp[0] << 8) | srcp[1];
3266     nal_escape (dstp + 2, srcp + 2, nalsize, &esize);
3267     dstp[0] = esize >> 8;
3268     dstp[1] = esize & 0xff;
3269     dstp += esize + 2;
3270     srcp += nalsize + 2;
3271   }
3272 
3273   cnt = *(dstp++) = *(srcp++);  /* Number of pps */
3274 
3275   GST_DEBUG ("num PPS %d", cnt);
3276 
3277   for (i = 0; i < cnt; i++) {
3278     GST_DEBUG ("copy PPS %d", i);
3279     nalsize = (srcp[0] << 8) | srcp[1];
3280     nal_escape (dstp + 2, srcp + 2, nalsize, &esize);
3281     dstp[0] = esize >> 8;
3282     dstp[1] = esize & 0xff;
3283     dstp += esize + 2;
3284     srcp += nalsize + 2;
3285   }
3286   *destsize = dstp - dst;
3287 
3288   return;
3289 
3290 full_copy:
3291   {
3292     GST_DEBUG ("something unexpected, doing full copy");
3293     memcpy (dst, src, size);
3294     *destsize = size;
3295     return;
3296   }
3297 }
3298 #endif
3299 
3300 /*
3301  * caps_with_codecid () transforms a GstCaps for a known codec
3302  * ID into a filled-in context.
3303  * codec_data from caps will override possible extradata already in the context
3304  */
3305 
3306 void
gst_ffmpeg_caps_with_codecid(enum AVCodecID codec_id,enum AVMediaType codec_type,const GstCaps * caps,AVCodecContext * context)3307 gst_ffmpeg_caps_with_codecid (enum AVCodecID codec_id,
3308     enum AVMediaType codec_type, const GstCaps * caps, AVCodecContext * context)
3309 {
3310   GstStructure *str;
3311   const GValue *value;
3312   GstBuffer *buf;
3313 
3314   GST_LOG ("codec_id:%d, codec_type:%d, caps:%" GST_PTR_FORMAT " context:%p",
3315       codec_id, codec_type, caps, context);
3316 
3317   if (!context || !gst_caps_get_size (caps))
3318     return;
3319 
3320   str = gst_caps_get_structure (caps, 0);
3321 
3322   /* extradata parsing (esds [mpeg4], wma/wmv, msmpeg4v1/2/3, etc.) */
3323   if ((value = gst_structure_get_value (str, "codec_data"))) {
3324     GstMapInfo map;
3325 
3326     buf = gst_value_get_buffer (value);
3327     gst_buffer_map (buf, &map, GST_MAP_READ);
3328 
3329     /* free the old one if it is there */
3330     if (context->extradata)
3331       av_free (context->extradata);
3332 
3333 #if 0
3334     if (codec_id == AV_CODEC_ID_H264) {
3335       guint extrasize;
3336 
3337       GST_DEBUG ("copy, escaping codec_data %d", size);
3338       /* ffmpeg h264 expects the codec_data to be escaped, there is no real
3339        * reason for this but let's just escape it for now. Start by allocating
3340        * enough space, x2 is more than enough.
3341        *
3342        * FIXME, we disabled escaping because some file already contain escaped
3343        * codec_data and then we escape twice and fail. It's better to leave it
3344        * as is, as that is what most players do. */
3345       context->extradata =
3346           av_mallocz (GST_ROUND_UP_16 (size * 2 +
3347               AV_INPUT_BUFFER_PADDING_SIZE));
3348       copy_config (context->extradata, data, size, &extrasize);
3349       GST_DEBUG ("escaped size: %d", extrasize);
3350       context->extradata_size = extrasize;
3351     } else
3352 #endif
3353     {
3354       /* allocate with enough padding */
3355       GST_DEBUG ("copy codec_data");
3356       context->extradata =
3357           av_mallocz (GST_ROUND_UP_16 (map.size +
3358               AV_INPUT_BUFFER_PADDING_SIZE));
3359       memcpy (context->extradata, map.data, map.size);
3360       context->extradata_size = map.size;
3361     }
3362 
3363     /* Hack for VC1. Sometimes the first (length) byte is 0 for some files */
3364     if (codec_id == AV_CODEC_ID_VC1 && map.size > 0 && map.data[0] == 0) {
3365       context->extradata[0] = (guint8) map.size;
3366     }
3367 
3368     GST_DEBUG ("have codec data of size %" G_GSIZE_FORMAT, map.size);
3369 
3370     gst_buffer_unmap (buf, &map);
3371   } else {
3372     context->extradata = NULL;
3373     context->extradata_size = 0;
3374     GST_DEBUG ("no codec data");
3375   }
3376 
3377   switch (codec_id) {
3378     case AV_CODEC_ID_MPEG4:
3379     {
3380       const gchar *mime = gst_structure_get_name (str);
3381 
3382       context->flags |= AV_CODEC_FLAG_4MV;
3383 
3384       if (!strcmp (mime, "video/x-divx"))
3385         context->codec_tag = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
3386       else if (!strcmp (mime, "video/mpeg")) {
3387         const gchar *profile;
3388 
3389         context->codec_tag = GST_MAKE_FOURCC ('m', 'p', '4', 'v');
3390 
3391         profile = gst_structure_get_string (str, "profile");
3392         if (profile) {
3393           if (g_strcmp0 (profile, "advanced-simple") == 0)
3394             context->flags |= AV_CODEC_FLAG_QPEL;
3395         }
3396       }
3397       break;
3398     }
3399 
3400     case AV_CODEC_ID_SVQ3:
3401       /* FIXME: this is a workaround for older gst-plugins releases
3402        * (<= 0.8.9). This should be removed at some point, because
3403        * it causes wrong decoded frame order. */
3404       if (!context->extradata) {
3405         gint halfpel_flag, thirdpel_flag, low_delay, unknown_svq3_flag;
3406         guint16 flags;
3407 
3408         if (gst_structure_get_int (str, "halfpel_flag", &halfpel_flag) &&
3409             gst_structure_get_int (str, "thirdpel_flag", &thirdpel_flag) &&
3410             gst_structure_get_int (str, "low_delay", &low_delay) &&
3411             gst_structure_get_int (str, "unknown_svq3_flag",
3412                 &unknown_svq3_flag)) {
3413           context->extradata = (guint8 *) av_mallocz (0x64);
3414           g_stpcpy ((gchar *) context->extradata, "SVQ3");
3415           flags = 1 << 3;
3416           flags |= low_delay;
3417           flags = flags << 2;
3418           flags |= unknown_svq3_flag;
3419           flags = flags << 6;
3420           flags |= halfpel_flag;
3421           flags = flags << 1;
3422           flags |= thirdpel_flag;
3423           flags = flags << 3;
3424 
3425           flags = GUINT16_FROM_LE (flags);
3426 
3427           memcpy ((gchar *) context->extradata + 0x62, &flags, 2);
3428           context->extradata_size = 0x64;
3429         }
3430       }
3431       break;
3432 
3433     case AV_CODEC_ID_MSRLE:
3434     case AV_CODEC_ID_QTRLE:
3435     case AV_CODEC_ID_TSCC:
3436     case AV_CODEC_ID_CSCD:
3437     case AV_CODEC_ID_APE:
3438     {
3439       gint depth;
3440 
3441       if (gst_structure_get_int (str, "depth", &depth)) {
3442         context->bits_per_coded_sample = depth;
3443       } else {
3444         GST_WARNING ("No depth field in caps %" GST_PTR_FORMAT, caps);
3445       }
3446 
3447     }
3448       break;
3449 
3450     case AV_CODEC_ID_COOK:
3451     case AV_CODEC_ID_RA_288:
3452     case AV_CODEC_ID_RA_144:
3453     case AV_CODEC_ID_SIPR:
3454     {
3455       gint leaf_size;
3456       gint bitrate;
3457 
3458       if (gst_structure_get_int (str, "leaf_size", &leaf_size))
3459         context->block_align = leaf_size;
3460       if (gst_structure_get_int (str, "bitrate", &bitrate))
3461         context->bit_rate = bitrate;
3462     }
3463       break;
3464     case AV_CODEC_ID_ALAC:
3465       gst_structure_get_int (str, "samplesize",
3466           &context->bits_per_coded_sample);
3467       break;
3468 
3469     case AV_CODEC_ID_DVVIDEO:
3470     {
3471       const gchar *format;
3472 
3473       if ((format = gst_structure_get_string (str, "format"))) {
3474 
3475         if (g_str_equal (format, "YUY2"))
3476           context->pix_fmt = AV_PIX_FMT_YUYV422;
3477         else if (g_str_equal (format, "I420"))
3478           context->pix_fmt = AV_PIX_FMT_YUV420P;
3479         else if (g_str_equal (format, "A420"))
3480           context->pix_fmt = AV_PIX_FMT_YUVA420P;
3481         else if (g_str_equal (format, "Y41B"))
3482           context->pix_fmt = AV_PIX_FMT_YUV411P;
3483         else if (g_str_equal (format, "Y42B"))
3484           context->pix_fmt = AV_PIX_FMT_YUV422P;
3485         else if (g_str_equal (format, "YUV9"))
3486           context->pix_fmt = AV_PIX_FMT_YUV410P;
3487         else {
3488           GST_WARNING ("couldn't convert format %s" " to a pixel format",
3489               format);
3490         }
3491       } else
3492         GST_WARNING ("No specified format");
3493       break;
3494     }
3495     case AV_CODEC_ID_H263P:
3496     {
3497       gboolean val;
3498 
3499       if (!gst_structure_get_boolean (str, "annex-f", &val) || val)
3500         context->flags |= AV_CODEC_FLAG_4MV;
3501       else
3502         context->flags &= ~AV_CODEC_FLAG_4MV;
3503       if ((!gst_structure_get_boolean (str, "annex-i", &val) || val) &&
3504           (!gst_structure_get_boolean (str, "annex-t", &val) || val))
3505         context->flags |= AV_CODEC_FLAG_AC_PRED;
3506       else
3507         context->flags &= ~AV_CODEC_FLAG_AC_PRED;
3508       if (!gst_structure_get_boolean (str, "annex-j", &val) || val)
3509         context->flags |= AV_CODEC_FLAG_LOOP_FILTER;
3510       else
3511         context->flags &= ~AV_CODEC_FLAG_LOOP_FILTER;
3512       break;
3513     }
3514     case AV_CODEC_ID_ADPCM_G726:
3515     {
3516       const gchar *layout;
3517 
3518       if ((layout = gst_structure_get_string (str, "layout"))) {
3519         if (!strcmp (layout, "g721")) {
3520           context->sample_rate = 8000;
3521           context->channels = 1;
3522           context->bit_rate = 32000;
3523         }
3524       }
3525       break;
3526     }
3527     case AV_CODEC_ID_SPEEDHQ:
3528     {
3529       const gchar *variant;
3530 
3531       if (context && (variant = gst_structure_get_string (str, "variant"))
3532           && strlen (variant) == 4) {
3533 
3534         context->codec_tag =
3535             GST_MAKE_FOURCC (variant[0], variant[1], variant[2], variant[3]);
3536       }
3537       break;
3538     }
3539     default:
3540       break;
3541   }
3542 
3543   if (!gst_caps_is_fixed (caps))
3544     return;
3545 
3546   /* common properties (width, height, fps) */
3547   switch (codec_type) {
3548     case AVMEDIA_TYPE_VIDEO:
3549       gst_ffmpeg_caps_to_pixfmt (caps, context,
3550           codec_id == AV_CODEC_ID_RAWVIDEO);
3551       break;
3552     case AVMEDIA_TYPE_AUDIO:
3553       gst_ffmpeg_caps_to_smpfmt (caps, context, FALSE);
3554       break;
3555     default:
3556       break;
3557   }
3558 
3559   /* fixup of default settings */
3560   switch (codec_id) {
3561     case AV_CODEC_ID_QCELP:
3562       /* QCELP is always mono, no matter what the caps say */
3563       context->channels = 1;
3564       break;
3565     case AV_CODEC_ID_ADPCM_G726:
3566       if (context->sample_rate && context->bit_rate)
3567         context->bits_per_coded_sample =
3568             context->bit_rate / context->sample_rate;
3569       break;
3570     default:
3571       break;
3572   }
3573 }
3574 
3575 /* _formatid_to_caps () is meant for muxers/demuxers, it
3576  * transforms a name (ffmpeg way of ID'ing these, why don't
3577  * they have unique numerical IDs?) to the corresponding
3578  * caps belonging to that mux-format
3579  *
3580  * Note: we don't need any additional info because the caps
3581  * isn't supposed to contain any useful info besides the
3582  * media type anyway
3583  */
3584 
3585 GstCaps *
gst_ffmpeg_formatid_to_caps(const gchar * format_name)3586 gst_ffmpeg_formatid_to_caps (const gchar * format_name)
3587 {
3588   GstCaps *caps = NULL;
3589 
3590   if (!strcmp (format_name, "mpeg")) {
3591     caps = gst_caps_new_simple ("video/mpeg",
3592         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
3593   } else if (!strcmp (format_name, "mpegts")) {
3594     caps = gst_caps_new_simple ("video/mpegts",
3595         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
3596   } else if (!strcmp (format_name, "rm")) {
3597     caps = gst_caps_new_simple ("application/x-pn-realmedia",
3598         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
3599   } else if (!strcmp (format_name, "asf")) {
3600     caps = gst_caps_new_empty_simple ("video/x-ms-asf");
3601   } else if (!strcmp (format_name, "avi")) {
3602     caps = gst_caps_new_empty_simple ("video/x-msvideo");
3603   } else if (!strcmp (format_name, "wav")) {
3604     caps = gst_caps_new_empty_simple ("audio/x-wav");
3605   } else if (!strcmp (format_name, "ape")) {
3606     caps = gst_caps_new_empty_simple ("application/x-ape");
3607   } else if (!strcmp (format_name, "swf")) {
3608     caps = gst_caps_new_empty_simple ("application/x-shockwave-flash");
3609   } else if (!strcmp (format_name, "au")) {
3610     caps = gst_caps_new_empty_simple ("audio/x-au");
3611   } else if (!strcmp (format_name, "dv")) {
3612     caps = gst_caps_new_simple ("video/x-dv",
3613         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
3614   } else if (!strcmp (format_name, "4xm")) {
3615     caps = gst_caps_new_empty_simple ("video/x-4xm");
3616   } else if (!strcmp (format_name, "matroska")) {
3617     caps = gst_caps_new_empty_simple ("video/x-matroska");
3618   } else if (!strcmp (format_name, "ivf")) {
3619     caps = gst_caps_new_empty_simple ("video/x-ivf");
3620   } else if (!strcmp (format_name, "mp3")) {
3621     caps = gst_caps_new_empty_simple ("application/x-id3");
3622   } else if (!strcmp (format_name, "flic")) {
3623     caps = gst_caps_new_empty_simple ("video/x-fli");
3624   } else if (!strcmp (format_name, "flv")) {
3625     caps = gst_caps_new_empty_simple ("video/x-flv");
3626   } else if (!strcmp (format_name, "tta")) {
3627     caps = gst_caps_new_empty_simple ("audio/x-ttafile");
3628   } else if (!strcmp (format_name, "aiff")) {
3629     caps = gst_caps_new_empty_simple ("audio/x-aiff");
3630   } else if (!strcmp (format_name, "mov_mp4_m4a_3gp_3g2")) {
3631     caps =
3632         gst_caps_from_string
3633         ("application/x-3gp; video/quicktime; audio/x-m4a");
3634   } else if (!strcmp (format_name, "mov")) {
3635     caps = gst_caps_from_string ("video/quicktime,variant=(string)apple");
3636   } else if (!strcmp (format_name, "mp4")) {
3637     caps = gst_caps_from_string ("video/quicktime,variant=(string)iso");
3638   } else if (!strcmp (format_name, "3gp")) {
3639     caps = gst_caps_from_string ("video/quicktime,variant=(string)3gpp");
3640   } else if (!strcmp (format_name, "3g2")) {
3641     caps = gst_caps_from_string ("video/quicktime,variant=(string)3g2");
3642   } else if (!strcmp (format_name, "psp")) {
3643     caps = gst_caps_from_string ("video/quicktime,variant=(string)psp");
3644   } else if (!strcmp (format_name, "ipod")) {
3645     caps = gst_caps_from_string ("video/quicktime,variant=(string)ipod");
3646   } else if (!strcmp (format_name, "aac")) {
3647     caps = gst_caps_new_simple ("audio/mpeg",
3648         "mpegversion", G_TYPE_INT, 4, NULL);
3649   } else if (!strcmp (format_name, "gif")) {
3650     caps = gst_caps_from_string ("image/gif");
3651   } else if (!strcmp (format_name, "ogg")) {
3652 #ifdef OHOS_OPT_COMPAT
3653     /* ohos.opt.compat.0031 fix caps, enable to use avdemux_ogg for pure audio scene */
3654     caps = gst_caps_from_string ("application/ogg; audio/ogg");
3655 #else
3656     caps = gst_caps_from_string ("application/ogg");
3657 #endif
3658   } else if (!strcmp (format_name, "mxf") || !strcmp (format_name, "mxf_d10")) {
3659     caps = gst_caps_from_string ("application/mxf");
3660   } else if (!strcmp (format_name, "gxf")) {
3661     caps = gst_caps_from_string ("application/gxf");
3662   } else if (!strcmp (format_name, "yuv4mpegpipe")) {
3663     caps = gst_caps_new_simple ("application/x-yuv4mpeg",
3664         "y4mversion", G_TYPE_INT, 2, NULL);
3665   } else if (!strcmp (format_name, "mpc")) {
3666     caps = gst_caps_from_string ("audio/x-musepack, streamversion = (int) 7");
3667   } else if (!strcmp (format_name, "mpc8")) {
3668     caps = gst_caps_from_string ("audio/x-musepack, streamversion = (int) 8");
3669   } else if (!strcmp (format_name, "vqf")) {
3670     caps = gst_caps_from_string ("audio/x-vqf");
3671   } else if (!strcmp (format_name, "nsv")) {
3672     caps = gst_caps_from_string ("video/x-nsv");
3673   } else if (!strcmp (format_name, "amr")) {
3674     caps = gst_caps_from_string ("audio/x-amr-nb-sh");
3675   } else if (!strcmp (format_name, "webm")) {
3676     caps = gst_caps_from_string ("video/webm");
3677   } else if (!strcmp (format_name, "voc")) {
3678     caps = gst_caps_from_string ("audio/x-voc");
3679   } else if (!strcmp (format_name, "pva")) {
3680     caps = gst_caps_from_string ("video/x-pva");
3681   } else if (!strcmp (format_name, "brstm")) {
3682     caps = gst_caps_from_string ("audio/x-brstm");
3683   } else if (!strcmp (format_name, "bfstm")) {
3684     caps = gst_caps_from_string ("audio/x-bfstm");
3685   } else {
3686     gchar *name;
3687 
3688     GST_LOG ("Could not create stream format caps for %s", format_name);
3689     name = g_strdup_printf ("application/x-gst-av-%s", format_name);
3690     caps = gst_caps_new_empty_simple (name);
3691     g_free (name);
3692   }
3693 
3694   return caps;
3695 }
3696 
3697 gboolean
gst_ffmpeg_formatid_get_codecids(const gchar * format_name,enum AVCodecID ** video_codec_list,enum AVCodecID ** audio_codec_list,AVOutputFormat * plugin)3698 gst_ffmpeg_formatid_get_codecids (const gchar * format_name,
3699     enum AVCodecID ** video_codec_list, enum AVCodecID ** audio_codec_list,
3700     AVOutputFormat * plugin)
3701 {
3702   static enum AVCodecID tmp_vlist[] = {
3703     AV_CODEC_ID_NONE,
3704     AV_CODEC_ID_NONE
3705   };
3706   static enum AVCodecID tmp_alist[] = {
3707     AV_CODEC_ID_NONE,
3708     AV_CODEC_ID_NONE
3709   };
3710 
3711   GST_LOG ("format_name : %s", format_name);
3712 
3713   if (!strcmp (format_name, "mp4")) {
3714     static enum AVCodecID mp4_video_list[] = {
3715       AV_CODEC_ID_MPEG4, AV_CODEC_ID_H264,
3716       AV_CODEC_ID_MJPEG,
3717       AV_CODEC_ID_NONE
3718     };
3719     static enum AVCodecID mp4_audio_list[] = {
3720       AV_CODEC_ID_AAC, AV_CODEC_ID_MP3,
3721       AV_CODEC_ID_NONE
3722     };
3723 
3724     *video_codec_list = mp4_video_list;
3725     *audio_codec_list = mp4_audio_list;
3726   } else if (!strcmp (format_name, "mpeg")) {
3727     static enum AVCodecID mpeg_video_list[] = { AV_CODEC_ID_MPEG1VIDEO,
3728       AV_CODEC_ID_MPEG2VIDEO,
3729       AV_CODEC_ID_H264,
3730       AV_CODEC_ID_NONE
3731     };
3732     static enum AVCodecID mpeg_audio_list[] = { AV_CODEC_ID_MP1,
3733       AV_CODEC_ID_MP2,
3734       AV_CODEC_ID_MP3,
3735       AV_CODEC_ID_NONE
3736     };
3737 
3738     *video_codec_list = mpeg_video_list;
3739     *audio_codec_list = mpeg_audio_list;
3740   } else if (!strcmp (format_name, "dvd")) {
3741     static enum AVCodecID mpeg_video_list[] = { AV_CODEC_ID_MPEG2VIDEO,
3742       AV_CODEC_ID_NONE
3743     };
3744     static enum AVCodecID mpeg_audio_list[] = { AV_CODEC_ID_MP2,
3745       AV_CODEC_ID_AC3,
3746       AV_CODEC_ID_DTS,
3747       AV_CODEC_ID_PCM_S16BE,
3748       AV_CODEC_ID_NONE
3749     };
3750 
3751     *video_codec_list = mpeg_video_list;
3752     *audio_codec_list = mpeg_audio_list;
3753   } else if (!strcmp (format_name, "mpegts")) {
3754     static enum AVCodecID mpegts_video_list[] = { AV_CODEC_ID_MPEG1VIDEO,
3755       AV_CODEC_ID_MPEG2VIDEO,
3756       AV_CODEC_ID_H264,
3757       AV_CODEC_ID_NONE
3758     };
3759     static enum AVCodecID mpegts_audio_list[] = { AV_CODEC_ID_MP2,
3760       AV_CODEC_ID_MP3,
3761       AV_CODEC_ID_AC3,
3762       AV_CODEC_ID_DTS,
3763       AV_CODEC_ID_AAC,
3764       AV_CODEC_ID_NONE
3765     };
3766 
3767     *video_codec_list = mpegts_video_list;
3768     *audio_codec_list = mpegts_audio_list;
3769   } else if (!strcmp (format_name, "vob")) {
3770     static enum AVCodecID vob_video_list[] =
3771         { AV_CODEC_ID_MPEG2VIDEO, AV_CODEC_ID_NONE };
3772     static enum AVCodecID vob_audio_list[] = { AV_CODEC_ID_MP2, AV_CODEC_ID_AC3,
3773       AV_CODEC_ID_DTS, AV_CODEC_ID_NONE
3774     };
3775 
3776     *video_codec_list = vob_video_list;
3777     *audio_codec_list = vob_audio_list;
3778   } else if (!strcmp (format_name, "flv")) {
3779     static enum AVCodecID flv_video_list[] =
3780         { AV_CODEC_ID_FLV1, AV_CODEC_ID_NONE };
3781     static enum AVCodecID flv_audio_list[] =
3782         { AV_CODEC_ID_MP3, AV_CODEC_ID_NONE };
3783 
3784     *video_codec_list = flv_video_list;
3785     *audio_codec_list = flv_audio_list;
3786   } else if (!strcmp (format_name, "asf")) {
3787     static enum AVCodecID asf_video_list[] =
3788         { AV_CODEC_ID_WMV1, AV_CODEC_ID_WMV2, AV_CODEC_ID_MSMPEG4V3,
3789       AV_CODEC_ID_NONE
3790     };
3791     static enum AVCodecID asf_audio_list[] =
3792         { AV_CODEC_ID_WMAV1, AV_CODEC_ID_WMAV2, AV_CODEC_ID_MP3,
3793       AV_CODEC_ID_NONE
3794     };
3795 
3796     *video_codec_list = asf_video_list;
3797     *audio_codec_list = asf_audio_list;
3798   } else if (!strcmp (format_name, "dv")) {
3799     static enum AVCodecID dv_video_list[] =
3800         { AV_CODEC_ID_DVVIDEO, AV_CODEC_ID_NONE };
3801     static enum AVCodecID dv_audio_list[] =
3802         { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_NONE };
3803 
3804     *video_codec_list = dv_video_list;
3805     *audio_codec_list = dv_audio_list;
3806   } else if (!strcmp (format_name, "mov")) {
3807     static enum AVCodecID mov_video_list[] = {
3808       AV_CODEC_ID_SVQ1, AV_CODEC_ID_SVQ3, AV_CODEC_ID_MPEG4,
3809       AV_CODEC_ID_H263, AV_CODEC_ID_H263P,
3810       AV_CODEC_ID_H264, AV_CODEC_ID_DVVIDEO,
3811       AV_CODEC_ID_MJPEG,
3812       AV_CODEC_ID_NONE
3813     };
3814     static enum AVCodecID mov_audio_list[] = {
3815       AV_CODEC_ID_PCM_MULAW, AV_CODEC_ID_PCM_ALAW, AV_CODEC_ID_ADPCM_IMA_QT,
3816       AV_CODEC_ID_MACE3, AV_CODEC_ID_MACE6, AV_CODEC_ID_AAC,
3817       AV_CODEC_ID_AMR_NB, AV_CODEC_ID_AMR_WB,
3818       AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE,
3819       AV_CODEC_ID_MP3, AV_CODEC_ID_NONE
3820     };
3821 
3822     *video_codec_list = mov_video_list;
3823     *audio_codec_list = mov_audio_list;
3824   } else if ((!strcmp (format_name, "3gp") || !strcmp (format_name, "3g2"))) {
3825     static enum AVCodecID tgp_video_list[] = {
3826       AV_CODEC_ID_MPEG4, AV_CODEC_ID_H263, AV_CODEC_ID_H263P, AV_CODEC_ID_H264,
3827       AV_CODEC_ID_NONE
3828     };
3829     static enum AVCodecID tgp_audio_list[] = {
3830       AV_CODEC_ID_AMR_NB, AV_CODEC_ID_AMR_WB,
3831       AV_CODEC_ID_AAC,
3832       AV_CODEC_ID_NONE
3833     };
3834 
3835     *video_codec_list = tgp_video_list;
3836     *audio_codec_list = tgp_audio_list;
3837   } else if (!strcmp (format_name, "mmf")) {
3838     static enum AVCodecID mmf_audio_list[] = {
3839       AV_CODEC_ID_ADPCM_YAMAHA, AV_CODEC_ID_NONE
3840     };
3841     *video_codec_list = NULL;
3842     *audio_codec_list = mmf_audio_list;
3843   } else if (!strcmp (format_name, "amr")) {
3844     static enum AVCodecID amr_audio_list[] = {
3845       AV_CODEC_ID_AMR_NB, AV_CODEC_ID_AMR_WB,
3846       AV_CODEC_ID_NONE
3847     };
3848     *video_codec_list = NULL;
3849     *audio_codec_list = amr_audio_list;
3850   } else if (!strcmp (format_name, "gif")) {
3851     static enum AVCodecID gif_image_list[] = {
3852       AV_CODEC_ID_RAWVIDEO, AV_CODEC_ID_NONE
3853     };
3854     *video_codec_list = gif_image_list;
3855     *audio_codec_list = NULL;
3856   } else if ((!strcmp (format_name, "pva"))) {
3857     static enum AVCodecID pga_video_list[] = {
3858       AV_CODEC_ID_MPEG2VIDEO,
3859       AV_CODEC_ID_NONE
3860     };
3861     static enum AVCodecID pga_audio_list[] = {
3862       AV_CODEC_ID_MP2,
3863       AV_CODEC_ID_NONE
3864     };
3865 
3866     *video_codec_list = pga_video_list;
3867     *audio_codec_list = pga_audio_list;
3868   } else if ((!strcmp (format_name, "ivf"))) {
3869     static enum AVCodecID ivf_video_list[] = {
3870       AV_CODEC_ID_VP8,
3871       AV_CODEC_ID_VP9,
3872       AV_CODEC_ID_AV1,
3873       AV_CODEC_ID_NONE
3874     };
3875     static enum AVCodecID ivf_audio_list[] = {
3876       AV_CODEC_ID_NONE
3877     };
3878 
3879     *video_codec_list = ivf_video_list;
3880     *audio_codec_list = ivf_audio_list;
3881   } else if ((plugin->audio_codec != AV_CODEC_ID_NONE) ||
3882       (plugin->video_codec != AV_CODEC_ID_NONE)) {
3883     tmp_vlist[0] = plugin->video_codec;
3884     tmp_alist[0] = plugin->audio_codec;
3885 
3886     *video_codec_list = tmp_vlist;
3887     *audio_codec_list = tmp_alist;
3888   } else {
3889     GST_LOG ("Format %s not found", format_name);
3890     return FALSE;
3891   }
3892 
3893   return TRUE;
3894 }
3895 
3896 /* Convert a GstCaps to a FFMPEG codec ID. Size et all
3897  * are omitted, that can be queried by the user itself,
3898  * we're not eating the GstCaps or anything
3899  * A pointer to an allocated context is also needed for
3900  * optional extra info
3901  */
3902 
3903 enum AVCodecID
gst_ffmpeg_caps_to_codecid(const GstCaps * caps,AVCodecContext * context)3904 gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
3905 {
3906   enum AVCodecID id = AV_CODEC_ID_NONE;
3907   const gchar *mimetype;
3908   const GstStructure *structure;
3909   gboolean video = FALSE, audio = FALSE;        /* we want to be sure! */
3910 
3911   g_return_val_if_fail (caps != NULL, AV_CODEC_ID_NONE);
3912   g_return_val_if_fail (gst_caps_get_size (caps) == 1, AV_CODEC_ID_NONE);
3913   structure = gst_caps_get_structure (caps, 0);
3914 
3915   mimetype = gst_structure_get_name (structure);
3916 
3917   if (!strcmp (mimetype, "video/x-raw")) {
3918     id = AV_CODEC_ID_RAWVIDEO;
3919     video = TRUE;
3920   } else if (!strcmp (mimetype, "audio/x-raw")) {
3921     GstAudioInfo info;
3922 
3923     if (gst_audio_info_from_caps (&info, caps)) {
3924       switch (GST_AUDIO_INFO_FORMAT (&info)) {
3925         case GST_AUDIO_FORMAT_S8:
3926           id = AV_CODEC_ID_PCM_S8;
3927           break;
3928         case GST_AUDIO_FORMAT_U8:
3929           id = AV_CODEC_ID_PCM_U8;
3930           break;
3931         case GST_AUDIO_FORMAT_S16LE:
3932           id = AV_CODEC_ID_PCM_S16LE;
3933           break;
3934         case GST_AUDIO_FORMAT_S16BE:
3935           id = AV_CODEC_ID_PCM_S16BE;
3936           break;
3937         case GST_AUDIO_FORMAT_U16LE:
3938           id = AV_CODEC_ID_PCM_U16LE;
3939           break;
3940         case GST_AUDIO_FORMAT_U16BE:
3941           id = AV_CODEC_ID_PCM_U16BE;
3942           break;
3943         default:
3944           break;
3945       }
3946       if (id != AV_CODEC_ID_NONE)
3947         audio = TRUE;
3948     }
3949   } else if (!strcmp (mimetype, "audio/x-mulaw")) {
3950     id = AV_CODEC_ID_PCM_MULAW;
3951     audio = TRUE;
3952   } else if (!strcmp (mimetype, "audio/x-alaw")) {
3953     id = AV_CODEC_ID_PCM_ALAW;
3954     audio = TRUE;
3955   } else if (!strcmp (mimetype, "video/x-dv")) {
3956     gboolean sys_strm;
3957 
3958     if (gst_structure_get_boolean (structure, "systemstream", &sys_strm) &&
3959         !sys_strm) {
3960       id = AV_CODEC_ID_DVVIDEO;
3961       video = TRUE;
3962     }
3963   } else if (!strcmp (mimetype, "audio/x-dv")) {        /* ??? */
3964     id = AV_CODEC_ID_DVAUDIO;
3965     audio = TRUE;
3966   } else if (!strcmp (mimetype, "video/x-h263")) {
3967     const gchar *h263version =
3968         gst_structure_get_string (structure, "h263version");
3969     if (h263version && !strcmp (h263version, "h263p"))
3970       id = AV_CODEC_ID_H263P;
3971     else
3972       id = AV_CODEC_ID_H263;
3973     video = TRUE;
3974   } else if (!strcmp (mimetype, "video/x-intel-h263")) {
3975     id = AV_CODEC_ID_H263I;
3976     video = TRUE;
3977   } else if (!strcmp (mimetype, "video/x-h261")) {
3978     id = AV_CODEC_ID_H261;
3979     video = TRUE;
3980   } else if (!strcmp (mimetype, "video/mpeg")) {
3981     gboolean sys_strm;
3982     gint mpegversion;
3983 
3984     if (gst_structure_get_boolean (structure, "systemstream", &sys_strm) &&
3985         gst_structure_get_int (structure, "mpegversion", &mpegversion) &&
3986         !sys_strm) {
3987       switch (mpegversion) {
3988         case 1:
3989           id = AV_CODEC_ID_MPEG1VIDEO;
3990           break;
3991         case 2:
3992           id = AV_CODEC_ID_MPEG2VIDEO;
3993           break;
3994         case 4:
3995           id = AV_CODEC_ID_MPEG4;
3996           break;
3997       }
3998     }
3999     if (id != AV_CODEC_ID_NONE)
4000       video = TRUE;
4001   } else if (!strcmp (mimetype, "image/jpeg")) {
4002     id = AV_CODEC_ID_MJPEG;     /* A... B... */
4003     video = TRUE;
4004   } else if (!strcmp (mimetype, "video/x-jpeg-b")) {
4005     id = AV_CODEC_ID_MJPEGB;
4006     video = TRUE;
4007   } else if (!strcmp (mimetype, "video/x-wmv")) {
4008     gint wmvversion = 0;
4009 
4010     if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
4011       switch (wmvversion) {
4012         case 1:
4013           id = AV_CODEC_ID_WMV1;
4014           break;
4015         case 2:
4016           id = AV_CODEC_ID_WMV2;
4017           break;
4018         case 3:
4019         {
4020           const gchar *format;
4021 
4022           /* WMV3 unless the fourcc exists and says otherwise */
4023           id = AV_CODEC_ID_WMV3;
4024 
4025           if ((format = gst_structure_get_string (structure, "format")) &&
4026               (g_str_equal (format, "WVC1") || g_str_equal (format, "WMVA")))
4027             id = AV_CODEC_ID_VC1;
4028 
4029           break;
4030         }
4031       }
4032     }
4033     if (id != AV_CODEC_ID_NONE)
4034       video = TRUE;
4035   } else if (!strcmp (mimetype, "audio/x-vorbis")) {
4036     id = AV_CODEC_ID_VORBIS;
4037     audio = TRUE;
4038   } else if (!strcmp (mimetype, "audio/x-qdm2")) {
4039     id = AV_CODEC_ID_QDM2;
4040     audio = TRUE;
4041   } else if (!strcmp (mimetype, "audio/mpeg")) {
4042     gint layer = 0;
4043     gint mpegversion = 0;
4044 
4045     if (gst_structure_get_int (structure, "mpegversion", &mpegversion)) {
4046       switch (mpegversion) {
4047         case 2:                /* ffmpeg uses faad for both... */
4048         case 4:
4049           id = AV_CODEC_ID_AAC;
4050           break;
4051         case 1:
4052           if (gst_structure_get_int (structure, "layer", &layer)) {
4053             switch (layer) {
4054               case 1:
4055                 id = AV_CODEC_ID_MP1;
4056                 break;
4057               case 2:
4058                 id = AV_CODEC_ID_MP2;
4059                 break;
4060               case 3:
4061                 id = AV_CODEC_ID_MP3;
4062                 break;
4063             }
4064           }
4065       }
4066     }
4067     if (id != AV_CODEC_ID_NONE)
4068       audio = TRUE;
4069   } else if (!strcmp (mimetype, "audio/x-musepack")) {
4070     gint streamversion = -1;
4071 
4072     if (gst_structure_get_int (structure, "streamversion", &streamversion)) {
4073       if (streamversion == 7)
4074         id = AV_CODEC_ID_MUSEPACK7;
4075     } else {
4076       id = AV_CODEC_ID_MUSEPACK7;
4077     }
4078   } else if (!strcmp (mimetype, "audio/x-wma")) {
4079     gint wmaversion = 0;
4080 
4081     if (gst_structure_get_int (structure, "wmaversion", &wmaversion)) {
4082       switch (wmaversion) {
4083         case 1:
4084           id = AV_CODEC_ID_WMAV1;
4085           break;
4086         case 2:
4087           id = AV_CODEC_ID_WMAV2;
4088           break;
4089         case 3:
4090           id = AV_CODEC_ID_WMAPRO;
4091           break;
4092       }
4093     }
4094     if (id != AV_CODEC_ID_NONE)
4095       audio = TRUE;
4096   } else if (!strcmp (mimetype, "audio/x-xma")) {
4097     gint xmaversion = 0;
4098 
4099     if (gst_structure_get_int (structure, "xmaversion", &xmaversion)) {
4100       switch (xmaversion) {
4101         case 1:
4102           id = AV_CODEC_ID_XMA1;
4103           break;
4104         case 2:
4105           id = AV_CODEC_ID_XMA2;
4106           break;
4107       }
4108     }
4109     if (id != AV_CODEC_ID_NONE)
4110       audio = TRUE;
4111   } else if (!strcmp (mimetype, "audio/x-wms")) {
4112     id = AV_CODEC_ID_WMAVOICE;
4113     audio = TRUE;
4114   } else if (!strcmp (mimetype, "audio/x-ac3")) {
4115     id = AV_CODEC_ID_AC3;
4116     audio = TRUE;
4117   } else if (!strcmp (mimetype, "audio/x-eac3")) {
4118     id = AV_CODEC_ID_EAC3;
4119     audio = TRUE;
4120   } else if (!strcmp (mimetype, "audio/x-vnd.sony.atrac3") ||
4121       !strcmp (mimetype, "audio/atrac3")) {
4122     id = AV_CODEC_ID_ATRAC3;
4123     audio = TRUE;
4124   } else if (!strcmp (mimetype, "audio/x-dts")) {
4125     id = AV_CODEC_ID_DTS;
4126     audio = TRUE;
4127   } else if (!strcmp (mimetype, "application/x-ape")) {
4128     id = AV_CODEC_ID_APE;
4129     audio = TRUE;
4130   } else if (!strcmp (mimetype, "video/x-msmpeg")) {
4131     gint msmpegversion = 0;
4132 
4133     if (gst_structure_get_int (structure, "msmpegversion", &msmpegversion)) {
4134       switch (msmpegversion) {
4135         case 41:
4136           id = AV_CODEC_ID_MSMPEG4V1;
4137           break;
4138         case 42:
4139           id = AV_CODEC_ID_MSMPEG4V2;
4140           break;
4141         case 43:
4142           id = AV_CODEC_ID_MSMPEG4V3;
4143           break;
4144       }
4145     }
4146     if (id != AV_CODEC_ID_NONE)
4147       video = TRUE;
4148   } else if (!strcmp (mimetype, "video/x-svq")) {
4149     gint svqversion = 0;
4150 
4151     if (gst_structure_get_int (structure, "svqversion", &svqversion)) {
4152       switch (svqversion) {
4153         case 1:
4154           id = AV_CODEC_ID_SVQ1;
4155           break;
4156         case 3:
4157           id = AV_CODEC_ID_SVQ3;
4158           break;
4159       }
4160     }
4161     if (id != AV_CODEC_ID_NONE)
4162       video = TRUE;
4163   } else if (!strcmp (mimetype, "video/x-huffyuv")) {
4164     id = AV_CODEC_ID_HUFFYUV;
4165     video = TRUE;
4166   } else if (!strcmp (mimetype, "audio/x-mace")) {
4167     gint maceversion = 0;
4168 
4169     if (gst_structure_get_int (structure, "maceversion", &maceversion)) {
4170       switch (maceversion) {
4171         case 3:
4172           id = AV_CODEC_ID_MACE3;
4173           break;
4174         case 6:
4175           id = AV_CODEC_ID_MACE6;
4176           break;
4177       }
4178     }
4179     if (id != AV_CODEC_ID_NONE)
4180       audio = TRUE;
4181   } else if (!strcmp (mimetype, "video/x-theora")) {
4182     id = AV_CODEC_ID_THEORA;
4183     video = TRUE;
4184   } else if (!strcmp (mimetype, "video/x-vp3")) {
4185     id = AV_CODEC_ID_VP3;
4186     video = TRUE;
4187   } else if (!strcmp (mimetype, "video/x-vp5")) {
4188     id = AV_CODEC_ID_VP5;
4189     video = TRUE;
4190   } else if (!strcmp (mimetype, "video/x-vp6")) {
4191     id = AV_CODEC_ID_VP6;
4192     video = TRUE;
4193   } else if (!strcmp (mimetype, "video/x-vp6-flash")) {
4194     id = AV_CODEC_ID_VP6F;
4195     video = TRUE;
4196   } else if (!strcmp (mimetype, "video/x-vp6-alpha")) {
4197     id = AV_CODEC_ID_VP6A;
4198     video = TRUE;
4199   } else if (!strcmp (mimetype, "video/x-vp8")) {
4200     id = AV_CODEC_ID_VP8;
4201     video = TRUE;
4202   } else if (!strcmp (mimetype, "video/x-vp9")) {
4203     id = AV_CODEC_ID_VP9;
4204     video = TRUE;
4205   } else if (!strcmp (mimetype, "video/x-flash-screen")) {
4206     id = AV_CODEC_ID_FLASHSV;
4207     video = TRUE;
4208   } else if (!strcmp (mimetype, "video/x-flash-screen2")) {
4209     id = AV_CODEC_ID_FLASHSV2;
4210     video = TRUE;
4211   } else if (!strcmp (mimetype, "video/x-cineform")) {
4212     id = AV_CODEC_ID_CFHD;
4213     video = TRUE;
4214   } else if (!strcmp (mimetype, "video/x-speedhq")) {
4215     id = AV_CODEC_ID_SPEEDHQ;
4216     video = TRUE;
4217   } else if (!strcmp (mimetype, "video/x-indeo")) {
4218     gint indeoversion = 0;
4219 
4220     if (gst_structure_get_int (structure, "indeoversion", &indeoversion)) {
4221       switch (indeoversion) {
4222         case 5:
4223           id = AV_CODEC_ID_INDEO5;
4224           break;
4225         case 4:
4226           id = AV_CODEC_ID_INDEO4;
4227           break;
4228         case 3:
4229           id = AV_CODEC_ID_INDEO3;
4230           break;
4231         case 2:
4232           id = AV_CODEC_ID_INDEO2;
4233           break;
4234       }
4235       if (id != AV_CODEC_ID_NONE)
4236         video = TRUE;
4237     }
4238   } else if (!strcmp (mimetype, "video/x-divx")) {
4239     gint divxversion = 0;
4240 
4241     if (gst_structure_get_int (structure, "divxversion", &divxversion)) {
4242       switch (divxversion) {
4243         case 3:
4244           id = AV_CODEC_ID_MSMPEG4V3;
4245           break;
4246         case 4:
4247         case 5:
4248           id = AV_CODEC_ID_MPEG4;
4249           break;
4250       }
4251     }
4252     if (id != AV_CODEC_ID_NONE)
4253       video = TRUE;
4254   } else if (!strcmp (mimetype, "video/x-ffv")) {
4255     gint ffvversion = 0;
4256 
4257     if (gst_structure_get_int (structure, "ffvversion", &ffvversion) &&
4258         ffvversion == 1) {
4259       id = AV_CODEC_ID_FFV1;
4260       video = TRUE;
4261     }
4262   } else if (!strcmp (mimetype, "video/x-apple-intermediate-codec")) {
4263     id = AV_CODEC_ID_AIC;
4264     video = TRUE;
4265   } else if (!strcmp (mimetype, "audio/x-adpcm")) {
4266     const gchar *layout;
4267 
4268     layout = gst_structure_get_string (structure, "layout");
4269     if (layout == NULL) {
4270       /* break */
4271     } else if (!strcmp (layout, "quicktime")) {
4272       id = AV_CODEC_ID_ADPCM_IMA_QT;
4273     } else if (!strcmp (layout, "microsoft")) {
4274       id = AV_CODEC_ID_ADPCM_MS;
4275     } else if (!strcmp (layout, "dvi")) {
4276       id = AV_CODEC_ID_ADPCM_IMA_WAV;
4277     } else if (!strcmp (layout, "4xm")) {
4278       id = AV_CODEC_ID_ADPCM_4XM;
4279     } else if (!strcmp (layout, "smjpeg")) {
4280       id = AV_CODEC_ID_ADPCM_IMA_SMJPEG;
4281     } else if (!strcmp (layout, "dk3")) {
4282       id = AV_CODEC_ID_ADPCM_IMA_DK3;
4283     } else if (!strcmp (layout, "dk4")) {
4284       id = AV_CODEC_ID_ADPCM_IMA_DK4;
4285     } else if (!strcmp (layout, "oki")) {
4286       id = AV_CODEC_ID_ADPCM_IMA_OKI;
4287     } else if (!strcmp (layout, "westwood")) {
4288       id = AV_CODEC_ID_ADPCM_IMA_WS;
4289     } else if (!strcmp (layout, "iss")) {
4290       id = AV_CODEC_ID_ADPCM_IMA_ISS;
4291     } else if (!strcmp (layout, "xa")) {
4292       id = AV_CODEC_ID_ADPCM_XA;
4293     } else if (!strcmp (layout, "adx")) {
4294       id = AV_CODEC_ID_ADPCM_ADX;
4295     } else if (!strcmp (layout, "ea")) {
4296       id = AV_CODEC_ID_ADPCM_EA;
4297     } else if (!strcmp (layout, "g726")) {
4298       id = AV_CODEC_ID_ADPCM_G726;
4299     } else if (!strcmp (layout, "g721")) {
4300       id = AV_CODEC_ID_ADPCM_G726;
4301     } else if (!strcmp (layout, "ct")) {
4302       id = AV_CODEC_ID_ADPCM_CT;
4303     } else if (!strcmp (layout, "swf")) {
4304       id = AV_CODEC_ID_ADPCM_SWF;
4305     } else if (!strcmp (layout, "yamaha")) {
4306       id = AV_CODEC_ID_ADPCM_YAMAHA;
4307     } else if (!strcmp (layout, "sbpro2")) {
4308       id = AV_CODEC_ID_ADPCM_SBPRO_2;
4309     } else if (!strcmp (layout, "sbpro3")) {
4310       id = AV_CODEC_ID_ADPCM_SBPRO_3;
4311     } else if (!strcmp (layout, "sbpro4")) {
4312       id = AV_CODEC_ID_ADPCM_SBPRO_4;
4313     }
4314     if (id != AV_CODEC_ID_NONE)
4315       audio = TRUE;
4316   } else if (!strcmp (mimetype, "video/x-4xm")) {
4317     id = AV_CODEC_ID_4XM;
4318     video = TRUE;
4319   } else if (!strcmp (mimetype, "audio/x-dpcm")) {
4320     const gchar *layout;
4321 
4322     layout = gst_structure_get_string (structure, "layout");
4323     if (!layout) {
4324       /* .. */
4325     } else if (!strcmp (layout, "roq")) {
4326       id = AV_CODEC_ID_ROQ_DPCM;
4327     } else if (!strcmp (layout, "interplay")) {
4328       id = AV_CODEC_ID_INTERPLAY_DPCM;
4329     } else if (!strcmp (layout, "xan")) {
4330       id = AV_CODEC_ID_XAN_DPCM;
4331     } else if (!strcmp (layout, "sol")) {
4332       id = AV_CODEC_ID_SOL_DPCM;
4333     }
4334     if (id != AV_CODEC_ID_NONE)
4335       audio = TRUE;
4336   } else if (!strcmp (mimetype, "audio/x-flac")) {
4337     id = AV_CODEC_ID_FLAC;
4338     audio = TRUE;
4339   } else if (!strcmp (mimetype, "audio/x-shorten")) {
4340     id = AV_CODEC_ID_SHORTEN;
4341     audio = TRUE;
4342   } else if (!strcmp (mimetype, "audio/x-alac")) {
4343     id = AV_CODEC_ID_ALAC;
4344     audio = TRUE;
4345   } else if (!strcmp (mimetype, "video/x-cinepak")) {
4346     id = AV_CODEC_ID_CINEPAK;
4347     video = TRUE;
4348   } else if (!strcmp (mimetype, "video/x-pn-realvideo")) {
4349     gint rmversion;
4350 
4351     if (gst_structure_get_int (structure, "rmversion", &rmversion)) {
4352       switch (rmversion) {
4353         case 1:
4354           id = AV_CODEC_ID_RV10;
4355           break;
4356         case 2:
4357           id = AV_CODEC_ID_RV20;
4358           break;
4359         case 3:
4360           id = AV_CODEC_ID_RV30;
4361           break;
4362         case 4:
4363           id = AV_CODEC_ID_RV40;
4364           break;
4365       }
4366     }
4367     if (id != AV_CODEC_ID_NONE)
4368       video = TRUE;
4369   } else if (!strcmp (mimetype, "audio/x-sipro")) {
4370     id = AV_CODEC_ID_SIPR;
4371     audio = TRUE;
4372   } else if (!strcmp (mimetype, "audio/x-pn-realaudio")) {
4373     gint raversion;
4374 
4375     if (gst_structure_get_int (structure, "raversion", &raversion)) {
4376       switch (raversion) {
4377         case 1:
4378           id = AV_CODEC_ID_RA_144;
4379           break;
4380         case 2:
4381           id = AV_CODEC_ID_RA_288;
4382           break;
4383         case 8:
4384           id = AV_CODEC_ID_COOK;
4385           break;
4386       }
4387     }
4388     if (id != AV_CODEC_ID_NONE)
4389       audio = TRUE;
4390   } else if (!strcmp (mimetype, "video/x-rle")) {
4391     const gchar *layout;
4392 
4393     if ((layout = gst_structure_get_string (structure, "layout"))) {
4394       if (!strcmp (layout, "microsoft")) {
4395         id = AV_CODEC_ID_MSRLE;
4396         video = TRUE;
4397       }
4398     }
4399   } else if (!strcmp (mimetype, "video/x-xan")) {
4400     gint wcversion = 0;
4401 
4402     if ((gst_structure_get_int (structure, "wcversion", &wcversion))) {
4403       switch (wcversion) {
4404         case 3:
4405           id = AV_CODEC_ID_XAN_WC3;
4406           video = TRUE;
4407           break;
4408         case 4:
4409           id = AV_CODEC_ID_XAN_WC4;
4410           video = TRUE;
4411           break;
4412         default:
4413           break;
4414       }
4415     }
4416   } else if (!strcmp (mimetype, "audio/AMR")) {
4417     audio = TRUE;
4418     id = AV_CODEC_ID_AMR_NB;
4419   } else if (!strcmp (mimetype, "audio/AMR-WB")) {
4420     id = AV_CODEC_ID_AMR_WB;
4421     audio = TRUE;
4422   } else if (!strcmp (mimetype, "audio/qcelp")) {
4423     id = AV_CODEC_ID_QCELP;
4424     audio = TRUE;
4425   } else if (!strcmp (mimetype, "video/x-h264")) {
4426     id = AV_CODEC_ID_H264;
4427     video = TRUE;
4428   } else if (!strcmp (mimetype, "video/x-h265")) {
4429     id = AV_CODEC_ID_HEVC;
4430     video = TRUE;
4431   } else if (!strcmp (mimetype, "video/x-flash-video")) {
4432     gint flvversion = 0;
4433 
4434     if ((gst_structure_get_int (structure, "flvversion", &flvversion))) {
4435       switch (flvversion) {
4436         case 1:
4437           id = AV_CODEC_ID_FLV1;
4438           video = TRUE;
4439           break;
4440         default:
4441           break;
4442       }
4443     }
4444 
4445   } else if (!strcmp (mimetype, "audio/x-nellymoser")) {
4446     id = AV_CODEC_ID_NELLYMOSER;
4447     audio = TRUE;
4448   } else if (!strncmp (mimetype, "audio/x-gst-av-", 15)) {
4449     gchar ext[16];
4450     const AVCodec *codec;
4451 
4452     if (strlen (mimetype) <= 30 &&
4453         sscanf (mimetype, "audio/x-gst-av-%s", ext) == 1) {
4454       if ((codec = avcodec_find_decoder_by_name (ext)) ||
4455           (codec = avcodec_find_encoder_by_name (ext))) {
4456         id = codec->id;
4457         audio = TRUE;
4458       }
4459     }
4460   } else if (!strncmp (mimetype, "video/x-gst-av-", 15)) {
4461     gchar ext[16];
4462     const AVCodec *codec;
4463 
4464     if (strlen (mimetype) <= 30 &&
4465         sscanf (mimetype, "video/x-gst-av-%s", ext) == 1) {
4466       if ((codec = avcodec_find_decoder_by_name (ext)) ||
4467           (codec = avcodec_find_encoder_by_name (ext))) {
4468         id = codec->id;
4469         video = TRUE;
4470       }
4471     }
4472   }
4473 
4474   if (context != NULL) {
4475     if (video == TRUE) {
4476       context->codec_type = AVMEDIA_TYPE_VIDEO;
4477     } else if (audio == TRUE) {
4478       context->codec_type = AVMEDIA_TYPE_AUDIO;
4479     } else {
4480       context->codec_type = AVMEDIA_TYPE_UNKNOWN;
4481     }
4482     context->codec_id = id;
4483     gst_ffmpeg_caps_with_codecid (id, context->codec_type, caps, context);
4484   }
4485 
4486   if (id != AV_CODEC_ID_NONE) {
4487     GST_DEBUG ("The id=%d belongs to the caps %" GST_PTR_FORMAT, id, caps);
4488   } else {
4489     GST_WARNING ("Couldn't figure out the id for caps %" GST_PTR_FORMAT, caps);
4490   }
4491 
4492   return id;
4493 }
4494