avaudenc: Reorder audio channels if necessary and add proper support for channel...
[platform/upstream/gst-libav.git] / ext / libav / gstavcodecmap.c
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
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   for (i = 0; i < channels; i++) {
81     for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) {
82       if (_ff_to_gst_layout[j].gst == pos[i]) {
83         ret |= _ff_to_gst_layout[i].ff;
84         channels_found++;
85         break;
86       }
87     }
88   }
89
90   if (channels_found != channels)
91     return 0;
92   return ret;
93 }
94
95 gboolean
96 gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
97     GstAudioChannelPosition * pos)
98 {
99   guint nchannels = 0;
100   gboolean none_layout = FALSE;
101
102   if (channel_layout == 0) {
103     nchannels = channels;
104     none_layout = TRUE;
105   } else {
106     guint i, j;
107
108     for (i = 0; i < 64; i++) {
109       if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
110         nchannels++;
111       }
112     }
113
114     if (nchannels != channels) {
115       GST_ERROR ("Number of channels is different (%u != %u)", channels,
116           nchannels);
117       nchannels = channels;
118       none_layout = TRUE;
119     } else {
120
121       for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
122         if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
123           pos[j++] = _ff_to_gst_layout[i].gst;
124
125           if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE)
126             none_layout = TRUE;
127         }
128       }
129
130       if (j != nchannels) {
131         GST_WARNING
132             ("Unknown channels in channel layout - assuming NONE layout");
133         none_layout = TRUE;
134       }
135     }
136   }
137
138   if (!none_layout
139       && !gst_audio_check_valid_channel_positions (pos, nchannels, FALSE)) {
140     GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
141         " - assuming NONE layout", channel_layout);
142     none_layout = TRUE;
143   }
144
145   if (none_layout) {
146     if (nchannels == 1) {
147       pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
148     } else if (nchannels == 2) {
149       pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
150       pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
151     } else {
152       guint i;
153
154       for (i = 0; i < nchannels; i++)
155         pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
156     }
157   }
158
159   return TRUE;
160 }
161
162 /* this macro makes a caps width fixed or unfixed width/height
163  * properties depending on whether we've got a context.
164  *
165  * See below for why we use this.
166  *
167  * We should actually do this stuff at the end, like in riff-media.c,
168  * but I'm too lazy today. Maybe later.
169  */
170 static GstCaps *
171 gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
172     gboolean encode, const char *mimetype, const char *fieldname, ...)
173 {
174   GstStructure *structure = NULL;
175   GstCaps *caps = NULL;
176   va_list var_args;
177   gint i;
178
179   GST_LOG ("context:%p, codec_id:%d, mimetype:%s", context, codec_id, mimetype);
180
181   /* fixed, non probing context */
182   if (context != NULL && context->width != -1) {
183     gint num, denom;
184
185     caps = gst_caps_new_simple (mimetype,
186         "width", G_TYPE_INT, context->width,
187         "height", G_TYPE_INT, context->height, NULL);
188
189     num = context->time_base.den / context->ticks_per_frame;
190     denom = context->time_base.num;
191
192     if (!denom) {
193       GST_LOG ("invalid framerate: %d/0, -> %d/1", num, num);
194       denom = 1;
195     }
196     if (gst_util_fraction_compare (num, denom, 1000, 1) > 0) {
197       GST_LOG ("excessive framerate: %d/%d, -> 0/1", num, denom);
198       num = 0;
199       denom = 1;
200     }
201     GST_LOG ("setting framerate: %d/%d", num, denom);
202     gst_caps_set_simple (caps,
203         "framerate", GST_TYPE_FRACTION, num, denom, NULL);
204   } else if (encode) {
205     /* so we are after restricted caps in this case */
206     switch (codec_id) {
207       case CODEC_ID_H261:
208       {
209         caps = gst_caps_new_simple (mimetype,
210             "width", G_TYPE_INT, 352,
211             "height", G_TYPE_INT, 288,
212             "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
213         gst_caps_append (caps, gst_caps_new_simple (mimetype,
214                 "width", G_TYPE_INT, 176,
215                 "height", G_TYPE_INT, 144,
216                 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
217         break;
218       }
219       case CODEC_ID_H263:
220       {
221         /* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
222          * because we want automatic negotiation to go as close to 320x240 as
223          * possible. */
224         const static gint widths[] = { 352, 704, 176, 1408, 128 };
225         const static gint heights[] = { 288, 576, 144, 1152, 96 };
226         GstCaps *temp;
227         gint n_sizes = G_N_ELEMENTS (widths);
228
229         caps = gst_caps_new_empty ();
230         for (i = 0; i < n_sizes; i++) {
231           temp = gst_caps_new_simple (mimetype,
232               "width", G_TYPE_INT, widths[i],
233               "height", G_TYPE_INT, heights[i],
234               "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
235
236           gst_caps_append (caps, temp);
237         }
238         break;
239       }
240       case CODEC_ID_DVVIDEO:
241       {
242         static struct
243         {
244           guint32 csp;
245           gint width, height;
246           gint par_n, par_d;
247           gint framerate_n, framerate_d;
248         } profiles[] = {
249           {
250           GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 10, 11, 30000, 1001}, {
251           GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 40, 33, 30000, 1001}, {
252           GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 59, 54, 25, 1}, {
253           GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 118, 81, 25, 1}, {
254           GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 59, 54, 25, 1}, {
255           GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 118, 81, 25, 1}
256         };
257         GstCaps *temp;
258         gint n_sizes = G_N_ELEMENTS (profiles);
259
260         caps = gst_caps_new_empty ();
261         for (i = 0; i < n_sizes; i++) {
262           temp = gst_caps_new_simple (mimetype,
263               "width", G_TYPE_INT, profiles[i].width,
264               "height", G_TYPE_INT, profiles[i].height,
265               "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
266               profiles[i].framerate_d, "pixel-aspect-ratio", GST_TYPE_FRACTION,
267               profiles[i].par_n, profiles[i].par_d, NULL);
268
269           gst_caps_append (caps, temp);
270         }
271         break;
272       }
273       case CODEC_ID_DNXHD:
274       {
275         caps = gst_caps_new_simple (mimetype,
276             "width", G_TYPE_INT, 1920,
277             "height", G_TYPE_INT, 1080,
278             "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
279         gst_caps_append (caps, gst_caps_new_simple (mimetype,
280                 "width", G_TYPE_INT, 1280,
281                 "height", G_TYPE_INT, 720,
282                 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
283         break;
284       }
285       default:
286         break;
287     }
288   }
289
290   /* no fixed caps or special restrictions applied;
291    * default unfixed setting */
292   if (!caps) {
293     GST_DEBUG ("Creating default caps");
294     caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
295   }
296
297   for (i = 0; i < gst_caps_get_size (caps); i++) {
298     va_start (var_args, fieldname);
299     structure = gst_caps_get_structure (caps, i);
300     gst_structure_set_valist (structure, fieldname, var_args);
301     va_end (var_args);
302   }
303
304   return caps;
305 }
306
307 static gint
308 get_nbits_set (guint64 n)
309 {
310   gint i, x;
311
312   x = 0;
313   for (i = 0; i < 64; i++) {
314     if ((n & (G_GUINT64_CONSTANT (1) << i)))
315       x++;
316   }
317
318   return x;
319 }
320
321 /* same for audio - now with channels/sample rate
322  */
323 static GstCaps *
324 gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
325     enum CodecID codec_id, gboolean encode, const char *mimetype,
326     const char *fieldname, ...)
327 {
328   GstCaps *caps = NULL;
329   gint i;
330   va_list var_args;
331
332   /* fixed, non-probing context */
333   if (context != NULL && context->channels != -1) {
334     GstAudioChannelPosition pos[64];
335
336     caps = gst_caps_new_simple (mimetype,
337         "rate", G_TYPE_INT, context->sample_rate,
338         "channels", G_TYPE_INT, context->channels, NULL);
339
340     if (gst_ffmpeg_channel_layout_to_gst (context->channel_layout,
341             context->channels, pos)) {
342       guint64 mask;
343
344       if (gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
345               &mask)) {
346         gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, mask,
347             NULL);
348       }
349     }
350   } else if (encode) {
351     gint maxchannels = 2;
352     const gint *rates = NULL;
353     gint n_rates = 0;
354
355     /* so we must be after restricted caps in this case */
356     switch (codec_id) {
357       case CODEC_ID_AAC:
358       case CODEC_ID_AAC_LATM:
359       case CODEC_ID_DTS:
360         maxchannels = 6;
361         break;
362       case CODEC_ID_MP2:
363       {
364         const static gint l_rates[] =
365             { 48000, 44100, 32000, 24000, 22050, 16000 };
366         n_rates = G_N_ELEMENTS (l_rates);
367         rates = l_rates;
368         break;
369       }
370       case CODEC_ID_EAC3:
371       case CODEC_ID_AC3:
372       {
373         const static gint l_rates[] = { 48000, 44100, 32000 };
374         maxchannels = 6;
375         n_rates = G_N_ELEMENTS (l_rates);
376         rates = l_rates;
377         break;
378       }
379       case CODEC_ID_ADPCM_G722:
380       {
381         const static gint l_rates[] = { 16000 };
382         n_rates = G_N_ELEMENTS (l_rates);
383         rates = l_rates;
384         maxchannels = 1;
385         break;
386       }
387       case CODEC_ID_ADPCM_G726:
388       {
389         const static gint l_rates[] = { 8000 };
390         n_rates = G_N_ELEMENTS (l_rates);
391         rates = l_rates;
392         maxchannels = 1;
393         break;
394       }
395       case CODEC_ID_ADPCM_SWF:
396       {
397         const static gint l_rates[] = { 11025, 22050, 44100 };
398         n_rates = G_N_ELEMENTS (l_rates);
399         rates = l_rates;
400         break;
401       }
402       case CODEC_ID_ROQ_DPCM:
403       {
404         const static gint l_rates[] = { 22050 };
405         n_rates = G_N_ELEMENTS (l_rates);
406         rates = l_rates;
407         break;
408       }
409       case CODEC_ID_AMR_NB:
410       {
411         const static gint l_rates[] = { 8000 };
412         maxchannels = 1;
413         n_rates = G_N_ELEMENTS (l_rates);
414         rates = l_rates;
415         break;
416       }
417       case CODEC_ID_AMR_WB:
418       {
419         const static gint l_rates[] = { 16000 };
420         maxchannels = 1;
421         n_rates = G_N_ELEMENTS (l_rates);
422         rates = l_rates;
423         break;
424       }
425       default:
426         break;
427     }
428
429     /* regardless of encode/decode, open up channels if applicable */
430     /* Until decoders/encoders expose the maximum number of channels
431      * they support, we whitelist them here. */
432     switch (codec_id) {
433       case CODEC_ID_WMAPRO:
434       case CODEC_ID_TRUEHD:
435         maxchannels = 8;
436         break;
437       default:
438         break;
439     }
440
441     if (codec && codec->channel_layouts) {
442       const uint64_t *layouts = codec->channel_layouts;
443       GstAudioChannelPosition pos[64];
444
445       caps = gst_caps_new_empty ();
446       while (*layouts) {
447         gint nbits_set = get_nbits_set (*layouts);
448
449         if (gst_ffmpeg_channel_layout_to_gst (*layouts, nbits_set, pos)) {
450           guint64 mask;
451
452           if (gst_audio_channel_positions_to_mask (pos, nbits_set, FALSE,
453                   &mask)) {
454             GstCaps *tmp =
455                 gst_caps_new_simple (mimetype, "channel-mask", GST_TYPE_BITMASK,
456                 mask,
457                 "channels", G_TYPE_INT, nbits_set, NULL);
458
459             gst_caps_append (caps, tmp);
460           }
461         }
462         layouts++;
463       }
464     } else {
465       if (maxchannels == 1)
466         caps = gst_caps_new_simple (mimetype,
467             "channels", G_TYPE_INT, maxchannels, NULL);
468       else
469         caps = gst_caps_new_simple (mimetype,
470             "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
471     }
472
473     if (n_rates) {
474       GValue list = { 0, };
475
476       g_value_init (&list, GST_TYPE_LIST);
477       for (i = 0; i < n_rates; i++) {
478         GValue v = { 0, };
479
480         g_value_init (&v, G_TYPE_INT);
481         g_value_set_int (&v, rates[i]);
482         gst_value_list_append_value (&list, &v);
483         g_value_unset (&v);
484       }
485       gst_caps_set_value (caps, "rate", &list);
486       g_value_unset (&list);
487     } else if (codec && codec->supported_samplerates
488         && codec->supported_samplerates[0]) {
489       GValue va = { 0, };
490       GValue v = { 0, };
491
492       if (!codec->supported_samplerates[1]) {
493         gst_caps_set_simple (caps, "rate", G_TYPE_INT,
494             codec->supported_samplerates[0], NULL);
495       } else {
496         const int *rates = codec->supported_samplerates;
497
498         g_value_init (&va, GST_TYPE_LIST);
499         g_value_init (&v, G_TYPE_INT);
500
501         while (*rates) {
502           g_value_set_int (&v, *rates);
503           gst_value_list_append_value (&va, &v);
504           rates++;
505         }
506         gst_caps_set_value (caps, "rate", &va);
507         g_value_unset (&va);
508         g_value_unset (&v);
509       }
510     } else {
511       gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
512     }
513   } else {
514     caps = gst_caps_new_empty_simple (mimetype);
515   }
516
517   va_start (var_args, fieldname);
518   gst_caps_set_simple_valist (caps, fieldname, var_args);
519   va_end (var_args);
520
521   return caps;
522 }
523
524 /* Convert a FFMPEG codec ID and optional AVCodecContext
525  * to a GstCaps. If the context is ommitted, no fixed values
526  * for video/audio size will be included in the GstCaps
527  *
528  * CodecID is primarily meant for compressed data GstCaps!
529  *
530  * encode is a special parameter. gstffmpegdec will say
531  * FALSE, gstffmpegenc will say TRUE. The output caps
532  * depends on this, in such a way that it will be very
533  * specific, defined, fixed and correct caps for encoders,
534  * yet very wide, "forgiving" caps for decoders. Example
535  * for mp3: decode: audio/mpeg,mpegversion=1,layer=[1-3]
536  * but encode: audio/mpeg,mpegversion=1,layer=3,bitrate=x,
537  * rate=x,channels=x.
538  */
539
540 GstCaps *
541 gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
542     AVCodecContext * context, gboolean encode)
543 {
544   GstCaps *caps = NULL;
545   gboolean buildcaps = FALSE;
546
547   GST_LOG ("codec_id:%d, context:%p, encode:%d", codec_id, context, encode);
548
549   switch (codec_id) {
550     case CODEC_ID_MPEG1VIDEO:
551       /* FIXME: bitrate */
552       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
553           "mpegversion", G_TYPE_INT, 1,
554           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
555       break;
556
557     case CODEC_ID_MPEG2VIDEO:
558       if (encode) {
559         /* FIXME: bitrate */
560         caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
561             "mpegversion", G_TYPE_INT, 2,
562             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
563       } else {
564         /* decode both MPEG-1 and MPEG-2; width/height/fps are all in
565          * the MPEG video stream headers, so may be omitted from caps. */
566         caps = gst_caps_new_simple ("video/mpeg",
567             "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
568             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
569       }
570       break;
571
572     case CODEC_ID_MPEG2VIDEO_XVMC:
573       /* this is a special ID - don't need it in GStreamer, I think */
574       break;
575
576     case CODEC_ID_H263:
577       if (encode) {
578         caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
579             "variant", G_TYPE_STRING, "itu",
580             "h263version", G_TYPE_STRING, "h263", NULL);
581       } else {
582         /* don't pass codec_id, we can decode other variants with the H263
583          * decoder that don't have specific size requirements
584          */
585         caps =
586             gst_ff_vid_caps_new (context, CODEC_ID_NONE, encode, "video/x-h263",
587             "variant", G_TYPE_STRING, "itu", NULL);
588       }
589       break;
590
591     case CODEC_ID_H263P:
592       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
593           "variant", G_TYPE_STRING, "itu",
594           "h263version", G_TYPE_STRING, "h263p", NULL);
595       if (encode && context) {
596
597         gst_caps_set_simple (caps,
598             "annex-f", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_4MV,
599             "annex-j", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_LOOP_FILTER,
600             "annex-i", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_AC_PRED,
601             "annex-t", G_TYPE_BOOLEAN, context->flags & CODEC_FLAG_AC_PRED,
602             NULL);
603       }
604       break;
605
606     case CODEC_ID_H263I:
607       caps =
608           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-intel-h263",
609           "variant", G_TYPE_STRING, "intel", NULL);
610       break;
611
612     case CODEC_ID_H261:
613       caps =
614           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h261", NULL);
615       break;
616
617     case CODEC_ID_RV10:
618     case CODEC_ID_RV20:
619     case CODEC_ID_RV30:
620     case CODEC_ID_RV40:
621     {
622       gint version;
623
624       switch (codec_id) {
625         case CODEC_ID_RV40:
626           version = 4;
627           break;
628         case CODEC_ID_RV30:
629           version = 3;
630           break;
631         case CODEC_ID_RV20:
632           version = 2;
633           break;
634         default:
635           version = 1;
636           break;
637       }
638
639       /* FIXME: context->sub_id must be filled in during decoding */
640       caps =
641           gst_ff_vid_caps_new (context, codec_id, encode,
642           "video/x-pn-realvideo", "systemstream", G_TYPE_BOOLEAN, FALSE,
643           "rmversion", G_TYPE_INT, version, NULL);
644       if (context) {
645         gst_caps_set_simple (caps, "format", G_TYPE_INT, context->sub_id, NULL);
646         if (context->extradata_size >= 8) {
647           gst_caps_set_simple (caps,
648               "subformat", G_TYPE_INT, GST_READ_UINT32_BE (context->extradata),
649               NULL);
650         }
651       }
652     }
653       break;
654
655     case CODEC_ID_MP1:
656       /* FIXME: bitrate */
657       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
658           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
659       break;
660
661     case CODEC_ID_MP2:
662       /* FIXME: bitrate */
663       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
664           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
665       break;
666
667     case CODEC_ID_MP3:
668       if (encode) {
669         /* FIXME: bitrate */
670         caps =
671             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
672             "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
673       } else {
674         /* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
675          * in the MPEG audio header, so may be omitted from caps. */
676         caps = gst_caps_new_simple ("audio/mpeg",
677             "mpegversion", G_TYPE_INT, 1,
678             "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
679       }
680       break;
681
682     case CODEC_ID_MUSEPACK7:
683       caps =
684           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
685           "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
686           NULL);
687       break;
688
689     case CODEC_ID_MUSEPACK8:
690       caps =
691           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
692           "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
693           NULL);
694       break;
695
696     case CODEC_ID_AC3:
697       /* FIXME: bitrate */
698       caps =
699           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-ac3",
700           NULL);
701       break;
702
703     case CODEC_ID_EAC3:
704       /* FIXME: bitrate */
705       caps =
706           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-eac3",
707           NULL);
708       break;
709
710     case CODEC_ID_TRUEHD:
711       caps =
712           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
713           "audio/x-true-hd", NULL);
714       break;
715
716     case CODEC_ID_ATRAC1:
717       caps =
718           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
719           "audio/x-vnd.sony.atrac1", NULL);
720       break;
721
722     case CODEC_ID_ATRAC3:
723       caps =
724           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
725           "audio/x-vnd.sony.atrac3", NULL);
726       break;
727
728     case CODEC_ID_DTS:
729       caps =
730           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dts",
731           NULL);
732       break;
733
734     case CODEC_ID_APE:
735       caps =
736           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
737           "audio/x-ffmpeg-parsed-ape", NULL);
738       if (context) {
739         gst_caps_set_simple (caps,
740             "depth", G_TYPE_INT, context->bits_per_coded_sample, NULL);
741       }
742       break;
743
744     case CODEC_ID_MLP:
745       caps =
746           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mlp",
747           NULL);
748       break;
749
750     case CODEC_ID_IMC:
751       caps =
752           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-imc",
753           NULL);
754       break;
755
756       /* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
757        * is Quicktime's MJPEG-B. LJPEG is lossless JPEG. I don't know what
758        * sp5x is, but it's apparently something JPEG... We don't separate
759        * between those in GStreamer. Should we (at least between MJPEG,
760        * MJPEG-B and sp5x decoding...)? */
761     case CODEC_ID_MJPEG:
762     case CODEC_ID_LJPEG:
763       caps =
764           gst_ff_vid_caps_new (context, codec_id, encode, "image/jpeg", NULL);
765       break;
766
767     case CODEC_ID_SP5X:
768       caps =
769           gst_ff_vid_caps_new (context, codec_id, encode, "video/sp5x", NULL);
770       break;
771
772     case CODEC_ID_MJPEGB:
773       caps =
774           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mjpeg-b",
775           NULL);
776       break;
777
778     case CODEC_ID_MPEG4:
779       if (encode && context != NULL) {
780         /* I'm not exactly sure what ffmpeg outputs... ffmpeg itself uses
781          * the AVI fourcc 'DIVX', but 'mp4v' for Quicktime... */
782         switch (context->codec_tag) {
783           case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
784             caps =
785                 gst_ff_vid_caps_new (context, codec_id, encode, "video/x-divx",
786                 "divxversion", G_TYPE_INT, 5, NULL);
787             break;
788           case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
789           default:
790             /* FIXME: bitrate */
791             caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
792                 "systemstream", G_TYPE_BOOLEAN, FALSE,
793                 "mpegversion", G_TYPE_INT, 4, NULL);
794             break;
795         }
796       } else {
797         /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
798         caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
799             "mpegversion", G_TYPE_INT, 4,
800             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
801         if (encode) {
802           gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
803                   "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
804         } else {
805           gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
806                   "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5,
807                   NULL));
808           gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
809                   "video/x-xvid", NULL));
810           gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
811                   "video/x-3ivx", NULL));
812         }
813       }
814       break;
815
816     case CODEC_ID_RAWVIDEO:
817       caps =
818           gst_ffmpeg_codectype_to_caps (AVMEDIA_TYPE_VIDEO, context, codec_id,
819           encode);
820       break;
821
822     case CODEC_ID_MSMPEG4V1:
823     case CODEC_ID_MSMPEG4V2:
824     case CODEC_ID_MSMPEG4V3:
825     {
826       gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;
827
828       /* encode-FIXME: bitrate */
829       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-msmpeg",
830           "msmpegversion", G_TYPE_INT, version, NULL);
831       if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
832         gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
833                 "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
834       }
835     }
836       break;
837
838     case CODEC_ID_WMV1:
839     case CODEC_ID_WMV2:
840     {
841       gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
842
843       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
844           "wmvversion", G_TYPE_INT, version, NULL);
845     }
846       break;
847
848     case CODEC_ID_FLV1:
849       caps =
850           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-flash-video",
851           "flvversion", G_TYPE_INT, 1, NULL);
852       break;
853
854     case CODEC_ID_SVQ1:
855       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
856           "svqversion", G_TYPE_INT, 1, NULL);
857       break;
858
859     case CODEC_ID_SVQ3:
860       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
861           "svqversion", G_TYPE_INT, 3, NULL);
862       break;
863
864     case CODEC_ID_DVAUDIO:
865       caps =
866           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dv",
867           NULL);
868       break;
869
870     case CODEC_ID_DVVIDEO:
871     {
872       if (encode && context) {
873         const gchar *format;
874
875         switch (context->pix_fmt) {
876           case PIX_FMT_YUYV422:
877             format = "YUY2";
878             break;
879           case PIX_FMT_YUV420P:
880             format = "I420";
881             break;
882           case PIX_FMT_YUVA420P:
883             format = "A420";
884             break;
885           case PIX_FMT_YUV411P:
886             format = "Y41B";
887             break;
888           case PIX_FMT_YUV422P:
889             format = "Y42B";
890             break;
891           case PIX_FMT_YUV410P:
892             format = "YUV9";
893             break;
894           default:
895             GST_WARNING
896                 ("Couldnt' find format for pixfmt %d, defaulting to I420",
897                 context->pix_fmt);
898             format = "I420";
899             break;
900         }
901         caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
902             "systemstream", G_TYPE_BOOLEAN, FALSE,
903             "format", G_TYPE_STRING, format, NULL);
904       } else {
905         caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
906             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
907       }
908     }
909       break;
910
911     case CODEC_ID_WMAV1:
912     case CODEC_ID_WMAV2:
913     {
914       gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
915
916       if (context) {
917         caps =
918             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
919             "wmaversion", G_TYPE_INT, version, "block_align", G_TYPE_INT,
920             context->block_align, "bitrate", G_TYPE_INT, context->bit_rate,
921             NULL);
922       } else {
923         caps =
924             gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
925             "wmaversion", G_TYPE_INT, version, "block_align",
926             GST_TYPE_INT_RANGE, 0, G_MAXINT, "bitrate", GST_TYPE_INT_RANGE, 0,
927             G_MAXINT, NULL);
928       }
929     }
930       break;
931     case CODEC_ID_WMAPRO:
932     {
933       caps =
934           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
935           "wmaversion", G_TYPE_INT, 3, NULL);
936       break;
937     }
938
939     case CODEC_ID_WMAVOICE:
940     {
941       caps =
942           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wms",
943           NULL);
944       break;
945     }
946
947     case CODEC_ID_MACE3:
948     case CODEC_ID_MACE6:
949     {
950       gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
951
952       caps =
953           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mace",
954           "maceversion", G_TYPE_INT, version, NULL);
955     }
956       break;
957
958     case CODEC_ID_HUFFYUV:
959       caps =
960           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-huffyuv",
961           NULL);
962       if (context) {
963         gst_caps_set_simple (caps,
964             "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
965       }
966       break;
967
968     case CODEC_ID_CYUV:
969       caps =
970           gst_ff_vid_caps_new (context, codec_id, encode,
971           "video/x-compressed-yuv", NULL);
972       break;
973
974     case CODEC_ID_H264:
975       caps =
976           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h264",
977           "alignment", G_TYPE_STRING, "au", NULL);
978       break;
979
980     case CODEC_ID_INDEO5:
981       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
982           "indeoversion", G_TYPE_INT, 5, NULL);
983       break;
984
985     case CODEC_ID_INDEO4:
986       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
987           "indeoversion", G_TYPE_INT, 4, NULL);
988       break;
989
990     case CODEC_ID_INDEO3:
991       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
992           "indeoversion", G_TYPE_INT, 3, NULL);
993       break;
994
995     case CODEC_ID_INDEO2:
996       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
997           "indeoversion", G_TYPE_INT, 2, NULL);
998       break;
999
1000     case CODEC_ID_FLASHSV:
1001       caps =
1002           gst_ff_vid_caps_new (context, codec_id, encode,
1003           "video/x-flash-screen", NULL);
1004       break;
1005
1006     case CODEC_ID_VP3:
1007       caps =
1008           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp3", NULL);
1009       break;
1010
1011     case CODEC_ID_VP5:
1012       caps =
1013           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp5", NULL);
1014       break;
1015
1016     case CODEC_ID_VP6:
1017       caps =
1018           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6", NULL);
1019       break;
1020
1021     case CODEC_ID_VP6F:
1022       caps =
1023           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-flash",
1024           NULL);
1025       break;
1026
1027     case CODEC_ID_VP6A:
1028       caps =
1029           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-alpha",
1030           NULL);
1031       break;
1032
1033     case CODEC_ID_VP8:
1034       caps =
1035           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp8", NULL);
1036       break;
1037
1038     case CODEC_ID_THEORA:
1039       caps =
1040           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-theora",
1041           NULL);
1042       break;
1043
1044     case CODEC_ID_AAC:
1045     {
1046       caps =
1047           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
1048           NULL);
1049
1050       if (!encode) {
1051         GValue arr = { 0, };
1052         GValue item = { 0, };
1053
1054         g_value_init (&arr, GST_TYPE_LIST);
1055         g_value_init (&item, G_TYPE_INT);
1056         g_value_set_int (&item, 2);
1057         gst_value_list_append_value (&arr, &item);
1058         g_value_set_int (&item, 4);
1059         gst_value_list_append_value (&arr, &item);
1060         g_value_unset (&item);
1061
1062         gst_caps_set_value (caps, "mpegversion", &arr);
1063         g_value_unset (&arr);
1064
1065         g_value_init (&arr, GST_TYPE_LIST);
1066         g_value_init (&item, G_TYPE_STRING);
1067         g_value_set_string (&item, "raw");
1068         gst_value_list_append_value (&arr, &item);
1069         g_value_set_string (&item, "adts");
1070         gst_value_list_append_value (&arr, &item);
1071         g_value_set_string (&item, "adif");
1072         gst_value_list_append_value (&arr, &item);
1073         g_value_unset (&item);
1074
1075         gst_caps_set_value (caps, "stream-format", &arr);
1076         g_value_unset (&arr);
1077       } else {
1078         gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 4,
1079             "stream-format", G_TYPE_STRING, "raw",
1080             "base-profile", G_TYPE_STRING, "lc", NULL);
1081
1082         if (context && context->extradata_size > 0)
1083           gst_codec_utils_aac_caps_set_level_and_profile (caps,
1084               context->extradata, context->extradata_size);
1085       }
1086
1087       break;
1088     }
1089     case CODEC_ID_AAC_LATM:    /* LATM/LOAS AAC syntax */
1090       caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
1091           "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "loas",
1092           NULL);
1093       break;
1094
1095     case CODEC_ID_ASV1:
1096       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
1097           "asusversion", G_TYPE_INT, 1, NULL);
1098       break;
1099     case CODEC_ID_ASV2:
1100       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
1101           "asusversion", G_TYPE_INT, 2, NULL);
1102       break;
1103
1104     case CODEC_ID_FFV1:
1105       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ffv",
1106           "ffvversion", G_TYPE_INT, 1, NULL);
1107       break;
1108
1109     case CODEC_ID_4XM:
1110       caps =
1111           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-4xm", NULL);
1112       break;
1113
1114     case CODEC_ID_XAN_WC3:
1115     case CODEC_ID_XAN_WC4:
1116       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-xan",
1117           "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
1118       break;
1119
1120     case CODEC_ID_CLJR:
1121       caps =
1122           gst_ff_vid_caps_new (context, codec_id, encode,
1123           "video/x-cirrus-logic-accupak", NULL);
1124       break;
1125
1126     case CODEC_ID_FRAPS:
1127       caps =
1128           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-fraps",
1129           NULL);
1130       break;
1131
1132     case CODEC_ID_MDEC:
1133     case CODEC_ID_ROQ:
1134     case CODEC_ID_INTERPLAY_VIDEO:
1135       buildcaps = TRUE;
1136       break;
1137
1138     case CODEC_ID_VCR1:
1139       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ati-vcr",
1140           "vcrversion", G_TYPE_INT, 1, NULL);
1141       break;
1142
1143     case CODEC_ID_RPZA:
1144       caps =
1145           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-apple-video",
1146           NULL);
1147       break;
1148
1149     case CODEC_ID_CINEPAK:
1150       caps =
1151           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-cinepak",
1152           NULL);
1153       break;
1154
1155       /* WS_VQA belogns here (order) */
1156
1157     case CODEC_ID_MSRLE:
1158       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
1159           "layout", G_TYPE_STRING, "microsoft", NULL);
1160       if (context) {
1161         gst_caps_set_simple (caps,
1162             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1163       } else {
1164         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
1165       }
1166       break;
1167
1168     case CODEC_ID_QTRLE:
1169       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
1170           "layout", G_TYPE_STRING, "quicktime", NULL);
1171       if (context) {
1172         gst_caps_set_simple (caps,
1173             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1174       } else {
1175         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL);
1176       }
1177       break;
1178
1179     case CODEC_ID_MSVIDEO1:
1180       caps =
1181           gst_ff_vid_caps_new (context, codec_id, encode,
1182           "video/x-msvideocodec", "msvideoversion", G_TYPE_INT, 1, NULL);
1183       break;
1184
1185     case CODEC_ID_WMV3:
1186       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
1187           "wmvversion", G_TYPE_INT, 3, NULL);
1188       break;
1189     case CODEC_ID_VC1:
1190       caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
1191           "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
1192       break;
1193     case CODEC_ID_QDM2:
1194       caps =
1195           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-qdm2",
1196           NULL);
1197       break;
1198
1199     case CODEC_ID_MSZH:
1200       caps =
1201           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mszh", NULL);
1202       break;
1203
1204     case CODEC_ID_ZLIB:
1205       caps =
1206           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-zlib", NULL);
1207       break;
1208
1209     case CODEC_ID_TRUEMOTION1:
1210       caps =
1211           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
1212           "trueversion", G_TYPE_INT, 1, NULL);
1213       break;
1214     case CODEC_ID_TRUEMOTION2:
1215       caps =
1216           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
1217           "trueversion", G_TYPE_INT, 2, NULL);
1218       break;
1219
1220     case CODEC_ID_ULTI:
1221       caps =
1222           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ultimotion",
1223           NULL);
1224       break;
1225
1226     case CODEC_ID_TSCC:
1227       caps =
1228           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-camtasia",
1229           NULL);
1230       if (context) {
1231         gst_caps_set_simple (caps,
1232             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1233       } else {
1234         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
1235       }
1236       break;
1237
1238     case CODEC_ID_KMVC:
1239       caps =
1240           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-kmvc", NULL);
1241       break;
1242
1243     case CODEC_ID_NUV:
1244       caps =
1245           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-nuv", NULL);
1246       break;
1247
1248     case CODEC_ID_GIF:
1249       caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/gif", NULL);
1250       break;
1251
1252     case CODEC_ID_PNG:
1253       caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/png", NULL);
1254       break;
1255
1256     case CODEC_ID_PPM:
1257       caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/ppm", NULL);
1258       break;
1259
1260     case CODEC_ID_PBM:
1261       caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/pbm", NULL);
1262       break;
1263
1264     case CODEC_ID_PAM:
1265       caps =
1266           gst_ff_vid_caps_new (context, codec_id, encode,
1267           "image/x-portable-anymap", NULL);
1268       break;
1269
1270     case CODEC_ID_PGM:
1271       caps =
1272           gst_ff_vid_caps_new (context, codec_id, encode,
1273           "image/x-portable-graymap", NULL);
1274       break;
1275
1276     case CODEC_ID_PCX:
1277       caps =
1278           gst_ff_vid_caps_new (context, codec_id, encode, "image/x-pcx", NULL);
1279       break;
1280
1281     case CODEC_ID_SGI:
1282       caps =
1283           gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sgi", NULL);
1284       break;
1285
1286     case CODEC_ID_TARGA:
1287       caps =
1288           gst_ff_vid_caps_new (context, codec_id, encode, "image/x-tga", NULL);
1289       break;
1290
1291     case CODEC_ID_TIFF:
1292       caps =
1293           gst_ff_vid_caps_new (context, codec_id, encode, "image/tiff", NULL);
1294       break;
1295
1296     case CODEC_ID_SUNRAST:
1297       caps =
1298           gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sun-raster",
1299           NULL);
1300       break;
1301
1302     case CODEC_ID_SMC:
1303       caps =
1304           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-smc", NULL);
1305       break;
1306
1307     case CODEC_ID_QDRAW:
1308       caps =
1309           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-qdrw", NULL);
1310       break;
1311
1312     case CODEC_ID_DNXHD:
1313       caps =
1314           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dnxhd",
1315           NULL);
1316       break;
1317
1318     case CODEC_ID_PRORES:
1319       caps =
1320           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-prores",
1321           NULL);
1322       break;
1323
1324     case CODEC_ID_MIMIC:
1325       caps =
1326           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mimic",
1327           NULL);
1328       break;
1329
1330     case CODEC_ID_VMNC:
1331       caps =
1332           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vmnc", NULL);
1333       break;
1334
1335     case CODEC_ID_TRUESPEECH:
1336       caps =
1337           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1338           "audio/x-truespeech", NULL);
1339       break;
1340
1341     case CODEC_ID_QCELP:
1342       caps =
1343           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/qcelp",
1344           NULL);
1345       break;
1346
1347     case CODEC_ID_AMV:
1348       caps =
1349           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-amv", NULL);
1350       break;
1351
1352     case CODEC_ID_AASC:
1353       caps =
1354           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-aasc", NULL);
1355       break;
1356
1357     case CODEC_ID_LOCO:
1358       caps =
1359           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-loco", NULL);
1360       break;
1361
1362     case CODEC_ID_ZMBV:
1363       caps =
1364           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-zmbv", NULL);
1365       break;
1366
1367     case CODEC_ID_LAGARITH:
1368       caps =
1369           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-lagarith",
1370           NULL);
1371       break;
1372
1373     case CODEC_ID_CSCD:
1374       caps =
1375           gst_ff_vid_caps_new (context, codec_id, encode, "video/x-camstudio",
1376           NULL);
1377       if (context) {
1378         gst_caps_set_simple (caps,
1379             "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
1380       } else {
1381         gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 8, 32, NULL);
1382       }
1383       break;
1384
1385     case CODEC_ID_WS_VQA:
1386     case CODEC_ID_IDCIN:
1387     case CODEC_ID_8BPS:
1388     case CODEC_ID_FLIC:
1389     case CODEC_ID_VMDVIDEO:
1390     case CODEC_ID_VMDAUDIO:
1391     case CODEC_ID_SNOW:
1392     case CODEC_ID_VIXL:
1393     case CODEC_ID_QPEG:
1394     case CODEC_ID_PGMYUV:
1395     case CODEC_ID_FFVHUFF:
1396     case CODEC_ID_WNV1:
1397     case CODEC_ID_MP3ADU:
1398     case CODEC_ID_MP3ON4:
1399     case CODEC_ID_WESTWOOD_SND1:
1400     case CODEC_ID_MMVIDEO:
1401     case CODEC_ID_AVS:
1402     case CODEC_ID_CAVS:
1403       buildcaps = TRUE;
1404       break;
1405
1406       /* weird quasi-codecs for the demuxers only */
1407     case CODEC_ID_PCM_S16LE:
1408     case CODEC_ID_PCM_S16BE:
1409     case CODEC_ID_PCM_U16LE:
1410     case CODEC_ID_PCM_U16BE:
1411     case CODEC_ID_PCM_S8:
1412     case CODEC_ID_PCM_U8:
1413     {
1414       GstAudioFormat format;
1415
1416       switch (codec_id) {
1417         case CODEC_ID_PCM_S16LE:
1418           format = GST_AUDIO_FORMAT_S16LE;
1419           break;
1420         case CODEC_ID_PCM_S16BE:
1421           format = GST_AUDIO_FORMAT_S16BE;
1422           break;
1423         case CODEC_ID_PCM_U16LE:
1424           format = GST_AUDIO_FORMAT_U16LE;
1425           break;
1426         case CODEC_ID_PCM_U16BE:
1427           format = GST_AUDIO_FORMAT_U16BE;
1428           break;
1429         case CODEC_ID_PCM_S8:
1430           format = GST_AUDIO_FORMAT_S8;
1431           break;
1432         case CODEC_ID_PCM_U8:
1433           format = GST_AUDIO_FORMAT_U8;
1434           break;
1435         default:
1436           g_assert (0);         /* don't worry, we never get here */
1437           break;
1438       }
1439
1440       caps =
1441           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-raw",
1442           "format", G_TYPE_STRING, gst_audio_format_to_string (format),
1443           "layout", G_TYPE_STRING, "interleaved", NULL);
1444     }
1445       break;
1446
1447     case CODEC_ID_PCM_MULAW:
1448       caps =
1449           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mulaw",
1450           NULL);
1451       break;
1452
1453     case CODEC_ID_PCM_ALAW:
1454       caps =
1455           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alaw",
1456           NULL);
1457       break;
1458
1459     case CODEC_ID_ADPCM_G722:
1460       caps =
1461           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/G722",
1462           NULL);
1463       if (context)
1464         gst_caps_set_simple (caps,
1465             "block_align", G_TYPE_INT, context->block_align,
1466             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1467       break;
1468
1469     case CODEC_ID_ADPCM_G726:
1470     {
1471       /* the G726 decoder can also handle G721 */
1472       caps =
1473           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
1474           "layout", G_TYPE_STRING, "g726", NULL);
1475       if (context)
1476         gst_caps_set_simple (caps,
1477             "block_align", G_TYPE_INT, context->block_align,
1478             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1479
1480       if (!encode) {
1481         gst_caps_append (caps, gst_caps_new_simple ("audio/x-adpcm",
1482                 "layout", G_TYPE_STRING, "g721",
1483                 "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL));
1484       }
1485       break;
1486     }
1487     case CODEC_ID_ADPCM_IMA_QT:
1488     case CODEC_ID_ADPCM_IMA_WAV:
1489     case CODEC_ID_ADPCM_IMA_DK3:
1490     case CODEC_ID_ADPCM_IMA_DK4:
1491     case CODEC_ID_ADPCM_IMA_WS:
1492     case CODEC_ID_ADPCM_IMA_SMJPEG:
1493     case CODEC_ID_ADPCM_IMA_AMV:
1494     case CODEC_ID_ADPCM_IMA_ISS:
1495     case CODEC_ID_ADPCM_IMA_EA_EACS:
1496     case CODEC_ID_ADPCM_IMA_EA_SEAD:
1497     case CODEC_ID_ADPCM_MS:
1498     case CODEC_ID_ADPCM_4XM:
1499     case CODEC_ID_ADPCM_XA:
1500     case CODEC_ID_ADPCM_ADX:
1501     case CODEC_ID_ADPCM_EA:
1502     case CODEC_ID_ADPCM_CT:
1503     case CODEC_ID_ADPCM_SWF:
1504     case CODEC_ID_ADPCM_YAMAHA:
1505     case CODEC_ID_ADPCM_SBPRO_2:
1506     case CODEC_ID_ADPCM_SBPRO_3:
1507     case CODEC_ID_ADPCM_SBPRO_4:
1508     case CODEC_ID_ADPCM_EA_R1:
1509     case CODEC_ID_ADPCM_EA_R2:
1510     case CODEC_ID_ADPCM_EA_R3:
1511     case CODEC_ID_ADPCM_EA_MAXIS_XA:
1512     case CODEC_ID_ADPCM_EA_XAS:
1513     case CODEC_ID_ADPCM_THP:
1514     {
1515       const gchar *layout = NULL;
1516
1517       switch (codec_id) {
1518         case CODEC_ID_ADPCM_IMA_QT:
1519           layout = "quicktime";
1520           break;
1521         case CODEC_ID_ADPCM_IMA_WAV:
1522           layout = "dvi";
1523           break;
1524         case CODEC_ID_ADPCM_IMA_DK3:
1525           layout = "dk3";
1526           break;
1527         case CODEC_ID_ADPCM_IMA_DK4:
1528           layout = "dk4";
1529           break;
1530         case CODEC_ID_ADPCM_IMA_WS:
1531           layout = "westwood";
1532           break;
1533         case CODEC_ID_ADPCM_IMA_SMJPEG:
1534           layout = "smjpeg";
1535           break;
1536         case CODEC_ID_ADPCM_IMA_AMV:
1537           layout = "amv";
1538           break;
1539         case CODEC_ID_ADPCM_IMA_ISS:
1540           layout = "iss";
1541           break;
1542         case CODEC_ID_ADPCM_IMA_EA_EACS:
1543           layout = "ea-eacs";
1544           break;
1545         case CODEC_ID_ADPCM_IMA_EA_SEAD:
1546           layout = "ea-sead";
1547           break;
1548         case CODEC_ID_ADPCM_MS:
1549           layout = "microsoft";
1550           break;
1551         case CODEC_ID_ADPCM_4XM:
1552           layout = "4xm";
1553           break;
1554         case CODEC_ID_ADPCM_XA:
1555           layout = "xa";
1556           break;
1557         case CODEC_ID_ADPCM_ADX:
1558           layout = "adx";
1559           break;
1560         case CODEC_ID_ADPCM_EA:
1561           layout = "ea";
1562           break;
1563         case CODEC_ID_ADPCM_CT:
1564           layout = "ct";
1565           break;
1566         case CODEC_ID_ADPCM_SWF:
1567           layout = "swf";
1568           break;
1569         case CODEC_ID_ADPCM_YAMAHA:
1570           layout = "yamaha";
1571           break;
1572         case CODEC_ID_ADPCM_SBPRO_2:
1573           layout = "sbpro2";
1574           break;
1575         case CODEC_ID_ADPCM_SBPRO_3:
1576           layout = "sbpro3";
1577           break;
1578         case CODEC_ID_ADPCM_SBPRO_4:
1579           layout = "sbpro4";
1580           break;
1581         case CODEC_ID_ADPCM_EA_R1:
1582           layout = "ea-r1";
1583           break;
1584         case CODEC_ID_ADPCM_EA_R2:
1585           layout = "ea-r3";
1586           break;
1587         case CODEC_ID_ADPCM_EA_R3:
1588           layout = "ea-r3";
1589           break;
1590         case CODEC_ID_ADPCM_EA_MAXIS_XA:
1591           layout = "ea-maxis-xa";
1592           break;
1593         case CODEC_ID_ADPCM_EA_XAS:
1594           layout = "ea-xas";
1595           break;
1596         case CODEC_ID_ADPCM_THP:
1597           layout = "thp";
1598           break;
1599         default:
1600           g_assert (0);         /* don't worry, we never get here */
1601           break;
1602       }
1603
1604       /* FIXME: someone please check whether we need additional properties
1605        * in this caps definition. */
1606       caps =
1607           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
1608           "layout", G_TYPE_STRING, layout, NULL);
1609       if (context)
1610         gst_caps_set_simple (caps,
1611             "block_align", G_TYPE_INT, context->block_align,
1612             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1613     }
1614       break;
1615
1616     case CODEC_ID_AMR_NB:
1617       caps =
1618           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR",
1619           NULL);
1620       break;
1621
1622     case CODEC_ID_AMR_WB:
1623       caps =
1624           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR-WB",
1625           NULL);
1626       break;
1627
1628     case CODEC_ID_GSM:
1629       caps =
1630           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-gsm",
1631           NULL);
1632       break;
1633
1634     case CODEC_ID_GSM_MS:
1635       caps =
1636           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/ms-gsm",
1637           NULL);
1638       break;
1639
1640     case CODEC_ID_NELLYMOSER:
1641       caps =
1642           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1643           "audio/x-nellymoser", NULL);
1644       break;
1645
1646     case CODEC_ID_SIPR:
1647     {
1648       caps =
1649           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-sipro",
1650           NULL);
1651       if (context) {
1652         gst_caps_set_simple (caps,
1653             "leaf_size", G_TYPE_INT, context->block_align,
1654             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1655       }
1656     }
1657       break;
1658
1659     case CODEC_ID_RA_144:
1660     case CODEC_ID_RA_288:
1661     case CODEC_ID_COOK:
1662     {
1663       gint version = 0;
1664
1665       switch (codec_id) {
1666         case CODEC_ID_RA_144:
1667           version = 1;
1668           break;
1669         case CODEC_ID_RA_288:
1670           version = 2;
1671           break;
1672         case CODEC_ID_COOK:
1673           version = 8;
1674           break;
1675         default:
1676           break;
1677       }
1678
1679       /* FIXME: properties? */
1680       caps =
1681           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1682           "audio/x-pn-realaudio", "raversion", G_TYPE_INT, version, NULL);
1683       if (context) {
1684         gst_caps_set_simple (caps,
1685             "leaf_size", G_TYPE_INT, context->block_align,
1686             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1687       }
1688     }
1689       break;
1690
1691     case CODEC_ID_ROQ_DPCM:
1692     case CODEC_ID_INTERPLAY_DPCM:
1693     case CODEC_ID_XAN_DPCM:
1694     case CODEC_ID_SOL_DPCM:
1695     {
1696       const gchar *layout = NULL;
1697
1698       switch (codec_id) {
1699         case CODEC_ID_ROQ_DPCM:
1700           layout = "roq";
1701           break;
1702         case CODEC_ID_INTERPLAY_DPCM:
1703           layout = "interplay";
1704           break;
1705         case CODEC_ID_XAN_DPCM:
1706           layout = "xan";
1707           break;
1708         case CODEC_ID_SOL_DPCM:
1709           layout = "sol";
1710           break;
1711         default:
1712           g_assert (0);         /* don't worry, we never get here */
1713           break;
1714       }
1715
1716       /* FIXME: someone please check whether we need additional properties
1717        * in this caps definition. */
1718       caps =
1719           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dpcm",
1720           "layout", G_TYPE_STRING, layout, NULL);
1721       if (context)
1722         gst_caps_set_simple (caps,
1723             "block_align", G_TYPE_INT, context->block_align,
1724             "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1725     }
1726       break;
1727
1728     case CODEC_ID_SHORTEN:
1729       caps = gst_caps_new_empty_simple ("audio/x-shorten");
1730       break;
1731
1732     case CODEC_ID_ALAC:
1733       caps =
1734           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alac",
1735           NULL);
1736       if (context) {
1737         gst_caps_set_simple (caps,
1738             "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
1739       }
1740       break;
1741
1742     case CODEC_ID_FLAC:
1743       /* Note that ffmpeg has no encoder yet, but just for safety. In the
1744        * encoder case, we want to add things like samplerate, channels... */
1745       if (!encode) {
1746         caps = gst_caps_new_empty_simple ("audio/x-flac");
1747       }
1748       break;
1749
1750     case CODEC_ID_DVD_SUBTITLE:
1751     case CODEC_ID_DVB_SUBTITLE:
1752       caps = NULL;
1753       break;
1754     case CODEC_ID_BMP:
1755       caps = gst_caps_new_empty_simple ("image/bmp");
1756       break;
1757     case CODEC_ID_TTA:
1758       caps =
1759           gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-tta",
1760           NULL);
1761       if (context) {
1762         gst_caps_set_simple (caps,
1763             "samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
1764       }
1765       break;
1766     case CODEC_ID_TWINVQ:
1767       caps =
1768           gst_ff_aud_caps_new (context, NULL, codec_id, encode,
1769           "audio/x-twin-vq", NULL);
1770       break;
1771     default:
1772       GST_DEBUG ("Unknown codec ID %d, please add mapping here", codec_id);
1773       break;
1774   }
1775
1776   if (buildcaps) {
1777     AVCodec *codec;
1778
1779     if ((codec = avcodec_find_decoder (codec_id)) ||
1780         (codec = avcodec_find_encoder (codec_id))) {
1781       gchar *mime = NULL;
1782
1783       GST_LOG ("Could not create stream format caps for %s", codec->name);
1784
1785       switch (codec->type) {
1786         case AVMEDIA_TYPE_VIDEO:
1787           mime = g_strdup_printf ("video/x-gst-av-%s", codec->name);
1788           caps = gst_ff_vid_caps_new (context, codec_id, encode, mime, NULL);
1789           g_free (mime);
1790           break;
1791         case AVMEDIA_TYPE_AUDIO:
1792           mime = g_strdup_printf ("audio/x-gst-av-%s", codec->name);
1793           caps =
1794               gst_ff_aud_caps_new (context, NULL, codec_id, encode, mime, NULL);
1795           if (context)
1796             gst_caps_set_simple (caps,
1797                 "block_align", G_TYPE_INT, context->block_align,
1798                 "bitrate", G_TYPE_INT, context->bit_rate, NULL);
1799           g_free (mime);
1800           break;
1801         default:
1802           break;
1803       }
1804     }
1805   }
1806
1807   if (caps != NULL) {
1808
1809     /* set private data */
1810     if (context && context->extradata_size > 0) {
1811       GstBuffer *data = gst_buffer_new_and_alloc (context->extradata_size);
1812
1813       gst_buffer_fill (data, 0, context->extradata, context->extradata_size);
1814       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, data, NULL);
1815       gst_buffer_unref (data);
1816     }
1817
1818     GST_LOG ("caps for codec_id=%d: %" GST_PTR_FORMAT, codec_id, caps);
1819
1820   } else {
1821     GST_LOG ("No caps found for codec_id=%d", codec_id);
1822   }
1823
1824   return caps;
1825 }
1826
1827 /* Convert a FFMPEG Pixel Format and optional AVCodecContext
1828  * to a GstCaps. If the context is ommitted, no fixed values
1829  * for video/audio size will be included in the GstCaps
1830  *
1831  * See below for usefullness
1832  */
1833
1834 GstCaps *
1835 gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context,
1836     enum CodecID codec_id)
1837 {
1838   GstCaps *caps = NULL;
1839   GstVideoFormat format;
1840
1841   format = gst_ffmpeg_pixfmt_to_videoformat (pix_fmt);
1842
1843   if (format != GST_VIDEO_FORMAT_UNKNOWN) {
1844     caps = gst_ff_vid_caps_new (context, codec_id, TRUE, "video/x-raw",
1845         "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
1846   }
1847
1848   if (caps != NULL) {
1849     GST_DEBUG ("caps for pix_fmt=%d: %" GST_PTR_FORMAT, pix_fmt, caps);
1850   } else {
1851     GST_LOG ("No caps found for pix_fmt=%d", pix_fmt);
1852   }
1853
1854   return caps;
1855 }
1856
1857 GstAudioFormat
1858 gst_ffmpeg_smpfmt_to_audioformat (enum AVSampleFormat sample_fmt)
1859 {
1860   switch (sample_fmt) {
1861     case AV_SAMPLE_FMT_U8:
1862     case AV_SAMPLE_FMT_U8P:
1863       return GST_AUDIO_FORMAT_U8;
1864       break;
1865     case AV_SAMPLE_FMT_S16:
1866     case AV_SAMPLE_FMT_S16P:
1867       return GST_AUDIO_FORMAT_S16;
1868       break;
1869     case AV_SAMPLE_FMT_S32:
1870     case AV_SAMPLE_FMT_S32P:
1871       return GST_AUDIO_FORMAT_S32;
1872       break;
1873     case AV_SAMPLE_FMT_FLT:
1874     case AV_SAMPLE_FMT_FLTP:
1875       return GST_AUDIO_FORMAT_F32;
1876       break;
1877     case AV_SAMPLE_FMT_DBL:
1878     case AV_SAMPLE_FMT_DBLP:
1879       return GST_AUDIO_FORMAT_F64;
1880       break;
1881     default:
1882       /* .. */
1883       return GST_AUDIO_FORMAT_UNKNOWN;
1884       break;
1885   }
1886 }
1887
1888 /* Convert a FFMPEG Sample Format and optional AVCodecContext
1889  * to a GstCaps. If the context is ommitted, no fixed values
1890  * for video/audio size will be included in the GstCaps
1891  *
1892  * See below for usefullness
1893  */
1894
1895 static GstCaps *
1896 gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
1897     AVCodecContext * context, AVCodec * codec, enum CodecID codec_id)
1898 {
1899   GstCaps *caps = NULL;
1900   GstAudioFormat format;
1901
1902   format = gst_ffmpeg_smpfmt_to_audioformat (sample_fmt);
1903
1904   if (format != GST_AUDIO_FORMAT_UNKNOWN) {
1905     caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
1906         "format", G_TYPE_STRING, gst_audio_format_to_string (format),
1907         "layout", G_TYPE_STRING, "interleaved", NULL);
1908     GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
1909   } else {
1910     GST_LOG ("No caps found for sample_fmt=%d", sample_fmt);
1911   }
1912
1913   return caps;
1914 }
1915
1916 static void
1917 gst_ffmpeg_audio_set_sample_fmts (GstCaps * caps,
1918     const enum AVSampleFormat *fmts)
1919 {
1920   GValue va = { 0, };
1921   GValue v = { 0, };
1922   GstAudioFormat format;
1923
1924   if (!fmts || fmts[0] == -1) {
1925     gint i;
1926
1927     g_value_init (&va, GST_TYPE_LIST);
1928     g_value_init (&v, G_TYPE_STRING);
1929     for (i = 0; i <= AV_SAMPLE_FMT_DBL; i++) {
1930       format = gst_ffmpeg_smpfmt_to_audioformat (i);
1931       g_value_set_string (&v, gst_audio_format_to_string (format));
1932       gst_value_list_append_value (&va, &v);
1933     }
1934     gst_caps_set_value (caps, "format", &va);
1935     g_value_unset (&v);
1936     g_value_unset (&va);
1937     return;
1938   }
1939
1940   /* Only a single rate */
1941   if (fmts[1] == -1) {
1942     format = gst_ffmpeg_smpfmt_to_audioformat (fmts[0]);
1943     gst_caps_set_simple (caps, "format", G_TYPE_STRING,
1944         gst_audio_format_to_string (format), NULL);
1945     return;
1946   }
1947
1948   g_value_init (&va, GST_TYPE_LIST);
1949   g_value_init (&v, G_TYPE_STRING);
1950   while (*fmts != -1) {
1951     format = gst_ffmpeg_smpfmt_to_audioformat (*fmts);
1952     g_value_set_string (&v, gst_audio_format_to_string (format));
1953     gst_value_list_append_value (&va, &v);
1954     fmts++;
1955   }
1956   gst_caps_set_value (caps, "format", &va);
1957   g_value_unset (&v);
1958   g_value_unset (&va);
1959 }
1960
1961 GstCaps *
1962 gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
1963     enum CodecID codec_id, gboolean encode, AVCodec * codec)
1964 {
1965   GstCaps *caps = NULL;
1966
1967   GST_DEBUG ("context:%p, codec_id:%d, encode:%d, codec:%p",
1968       context, codec_id, encode, codec);
1969   if (codec)
1970     GST_DEBUG ("sample_fmts:%p, samplerates:%p",
1971         codec->sample_fmts, codec->supported_samplerates);
1972
1973   if (context) {
1974     /* Specific codec context */
1975     caps =
1976         gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec,
1977         codec_id);
1978   } else {
1979     caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
1980         "layout", G_TYPE_STRING, "interleaved", NULL);
1981     gst_ffmpeg_audio_set_sample_fmts (caps, codec ? codec->sample_fmts : NULL);
1982   }
1983
1984   return caps;
1985 }
1986
1987 GstCaps *
1988 gst_ffmpeg_codectype_to_video_caps (AVCodecContext * context,
1989     enum CodecID codec_id, gboolean encode, AVCodec * codec)
1990 {
1991   GstCaps *caps;
1992
1993   GST_LOG ("context:%p, codec_id:%d, encode:%d, codec:%p",
1994       context, codec_id, encode, codec);
1995
1996   if (context) {
1997     caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
1998   } else {
1999     GstCaps *temp;
2000     enum PixelFormat i;
2001     AVCodecContext ctx = { 0, };
2002
2003     caps = gst_caps_new_empty ();
2004     for (i = 0; i < PIX_FMT_NB; i++) {
2005       ctx.width = -1;
2006       ctx.pix_fmt = i;
2007       temp = gst_ffmpeg_pixfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
2008       if (temp != NULL) {
2009         gst_caps_append (caps, temp);
2010       }
2011     }
2012   }
2013   return caps;
2014 }
2015
2016 /* Convert a FFMPEG codec Type and optional AVCodecContext
2017  * to a GstCaps. If the context is ommitted, no fixed values
2018  * for video/audio size will be included in the GstCaps
2019  *
2020  * AVMediaType is primarily meant for uncompressed data GstCaps!
2021  */
2022
2023 GstCaps *
2024 gst_ffmpeg_codectype_to_caps (enum AVMediaType codec_type,
2025     AVCodecContext * context, enum CodecID codec_id, gboolean encode)
2026 {
2027   GstCaps *caps;
2028
2029   switch (codec_type) {
2030     case AVMEDIA_TYPE_VIDEO:
2031       caps =
2032           gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
2033       break;
2034     case AVMEDIA_TYPE_AUDIO:
2035       caps =
2036           gst_ffmpeg_codectype_to_audio_caps (context, codec_id, encode, NULL);
2037       break;
2038     default:
2039       caps = NULL;
2040       break;
2041   }
2042
2043   return caps;
2044 }
2045
2046 /* Convert a GstCaps (audio/raw) to a FFMPEG SampleFmt
2047  * and other audio properties in a AVCodecContext.
2048  *
2049  * For usefullness, see below
2050  */
2051
2052 static void
2053 gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps,
2054     AVCodecContext * context, gboolean raw)
2055 {
2056   GstStructure *structure;
2057   const gchar *fmt;
2058   GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
2059
2060   g_return_if_fail (gst_caps_get_size (caps) == 1);
2061
2062   structure = gst_caps_get_structure (caps, 0);
2063
2064   gst_structure_get_int (structure, "channels", &context->channels);
2065   gst_structure_get_int (structure, "rate", &context->sample_rate);
2066   gst_structure_get_int (structure, "block_align", &context->block_align);
2067   gst_structure_get_int (structure, "bitrate", &context->bit_rate);
2068
2069   if (!raw)
2070     return;
2071
2072   if (gst_structure_has_name (structure, "audio/x-raw")) {
2073     if ((fmt = gst_structure_get_string (structure, "format"))) {
2074       format = gst_audio_format_from_string (fmt);
2075     }
2076   }
2077
2078   switch (format) {
2079     case GST_AUDIO_FORMAT_F32:
2080       context->sample_fmt = AV_SAMPLE_FMT_FLT;
2081       break;
2082     case GST_AUDIO_FORMAT_F64:
2083       context->sample_fmt = AV_SAMPLE_FMT_DBL;
2084       break;
2085     case GST_AUDIO_FORMAT_S32:
2086       context->sample_fmt = AV_SAMPLE_FMT_S32;
2087       break;
2088     case GST_AUDIO_FORMAT_S16:
2089       context->sample_fmt = AV_SAMPLE_FMT_S16;
2090       break;
2091     default:
2092       break;
2093   }
2094 }
2095
2096 /* Convert a GstCaps (video/raw) to a FFMPEG PixFmt
2097  * and other video properties in a AVCodecContext.
2098  *
2099  * For usefullness, see below
2100  */
2101
2102 static void
2103 gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
2104     AVCodecContext * context, gboolean raw)
2105 {
2106   GstStructure *structure;
2107   const GValue *fps;
2108   const GValue *par = NULL;
2109   const gchar *fmt;
2110   GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
2111
2112   GST_DEBUG ("converting caps %" GST_PTR_FORMAT, caps);
2113   g_return_if_fail (gst_caps_get_size (caps) == 1);
2114   structure = gst_caps_get_structure (caps, 0);
2115
2116   gst_structure_get_int (structure, "width", &context->width);
2117   gst_structure_get_int (structure, "height", &context->height);
2118   gst_structure_get_int (structure, "bpp", &context->bits_per_coded_sample);
2119
2120   fps = gst_structure_get_value (structure, "framerate");
2121   if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
2122
2123     /* somehow these seem mixed up.. */
2124     context->time_base.den = gst_value_get_fraction_numerator (fps);
2125     context->time_base.num = gst_value_get_fraction_denominator (fps);
2126     context->ticks_per_frame = 1;
2127
2128     GST_DEBUG ("setting framerate %d/%d = %lf",
2129         context->time_base.den, context->time_base.num,
2130         1. * context->time_base.den / context->time_base.num);
2131   }
2132
2133   par = gst_structure_get_value (structure, "pixel-aspect-ratio");
2134   if (par && GST_VALUE_HOLDS_FRACTION (par)) {
2135
2136     context->sample_aspect_ratio.num = gst_value_get_fraction_numerator (par);
2137     context->sample_aspect_ratio.den = gst_value_get_fraction_denominator (par);
2138
2139     GST_DEBUG ("setting pixel-aspect-ratio %d/%d = %lf",
2140         context->sample_aspect_ratio.den, context->sample_aspect_ratio.num,
2141         1. * context->sample_aspect_ratio.den /
2142         context->sample_aspect_ratio.num);
2143   }
2144
2145   if (!raw)
2146     return;
2147
2148   g_return_if_fail (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps));
2149
2150   if (gst_structure_has_name (structure, "video/x-raw")) {
2151     if ((fmt = gst_structure_get_string (structure, "format"))) {
2152       format = gst_video_format_from_string (fmt);
2153     }
2154   }
2155
2156   switch (format) {
2157     case GST_VIDEO_FORMAT_YUY2:
2158       context->pix_fmt = PIX_FMT_YUYV422;
2159       break;
2160     case GST_VIDEO_FORMAT_I420:
2161       context->pix_fmt = PIX_FMT_YUV420P;
2162       break;
2163     case GST_VIDEO_FORMAT_A420:
2164       context->pix_fmt = PIX_FMT_YUVA420P;
2165       break;
2166     case GST_VIDEO_FORMAT_Y41B:
2167       context->pix_fmt = PIX_FMT_YUV411P;
2168       break;
2169     case GST_VIDEO_FORMAT_Y42B:
2170       context->pix_fmt = PIX_FMT_YUV422P;
2171       break;
2172     case GST_VIDEO_FORMAT_YUV9:
2173       context->pix_fmt = PIX_FMT_YUV410P;
2174       break;
2175     case GST_VIDEO_FORMAT_Y444:
2176       context->pix_fmt = PIX_FMT_YUV444P;
2177       break;
2178     case GST_VIDEO_FORMAT_GRAY8:
2179       context->pix_fmt = PIX_FMT_GRAY8;
2180       break;
2181     case GST_VIDEO_FORMAT_xRGB:
2182 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
2183       context->pix_fmt = PIX_FMT_RGB32;
2184 #endif
2185       break;
2186     case GST_VIDEO_FORMAT_BGRx:
2187 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
2188       context->pix_fmt = PIX_FMT_RGB32;
2189 #endif
2190       break;
2191     case GST_VIDEO_FORMAT_RGB:
2192       context->pix_fmt = PIX_FMT_RGB24;
2193       break;
2194     case GST_VIDEO_FORMAT_BGR:
2195       context->pix_fmt = PIX_FMT_BGR24;
2196       break;
2197     case GST_VIDEO_FORMAT_RGB16:
2198       context->pix_fmt = PIX_FMT_RGB565;
2199       break;
2200     case GST_VIDEO_FORMAT_RGB15:
2201       context->pix_fmt = PIX_FMT_RGB555;
2202       break;
2203     case GST_VIDEO_FORMAT_RGB8P:
2204       context->pix_fmt = PIX_FMT_PAL8;
2205       break;
2206     default:
2207       break;
2208   }
2209 }
2210
2211 typedef struct
2212 {
2213   GstVideoFormat format;
2214   enum PixelFormat pixfmt;
2215 } PixToFmt;
2216
2217 /* FIXME : FILLME */
2218 static const PixToFmt pixtofmttable[] = {
2219   /* GST_VIDEO_FORMAT_I420, */
2220   {GST_VIDEO_FORMAT_I420, PIX_FMT_YUV420P},
2221   /* Note : this should use a different chroma placement */
2222   {GST_VIDEO_FORMAT_I420, PIX_FMT_YUVJ420P},
2223
2224   /* GST_VIDEO_FORMAT_YV12, */
2225   /* GST_VIDEO_FORMAT_YUY2, */
2226   {GST_VIDEO_FORMAT_YUY2, PIX_FMT_YUYV422},
2227   /* GST_VIDEO_FORMAT_UYVY, */
2228   {GST_VIDEO_FORMAT_UYVY, PIX_FMT_UYVY422},
2229   /* GST_VIDEO_FORMAT_AYUV, */
2230   /* GST_VIDEO_FORMAT_RGBx, */
2231   /* GST_VIDEO_FORMAT_BGRx, */
2232   /* GST_VIDEO_FORMAT_xRGB, */
2233   /* GST_VIDEO_FORMAT_xBGR, */
2234   /* GST_VIDEO_FORMAT_RGBA, */
2235   {GST_VIDEO_FORMAT_RGBA, PIX_FMT_RGBA},
2236   /* GST_VIDEO_FORMAT_BGRA, */
2237   {GST_VIDEO_FORMAT_BGRA, PIX_FMT_BGRA},
2238   /* GST_VIDEO_FORMAT_ARGB, */
2239   {GST_VIDEO_FORMAT_ARGB, PIX_FMT_ARGB},
2240   /* GST_VIDEO_FORMAT_ABGR, */
2241   {GST_VIDEO_FORMAT_ABGR, PIX_FMT_ABGR},
2242   /* GST_VIDEO_FORMAT_RGB, */
2243   {GST_VIDEO_FORMAT_RGB, PIX_FMT_RGB24},
2244   /* GST_VIDEO_FORMAT_BGR, */
2245   {GST_VIDEO_FORMAT_BGR, PIX_FMT_BGR24},
2246   /* GST_VIDEO_FORMAT_Y41B, */
2247   {GST_VIDEO_FORMAT_Y41B, PIX_FMT_YUV411P},
2248   /* GST_VIDEO_FORMAT_Y42B, */
2249   {GST_VIDEO_FORMAT_Y42B, PIX_FMT_YUV422P},
2250   {GST_VIDEO_FORMAT_Y42B, PIX_FMT_YUVJ422P},
2251   /* GST_VIDEO_FORMAT_YVYU, */
2252   /* GST_VIDEO_FORMAT_Y444, */
2253   {GST_VIDEO_FORMAT_Y444, PIX_FMT_YUV444P},
2254   {GST_VIDEO_FORMAT_Y444, PIX_FMT_YUVJ444P},
2255   /* GST_VIDEO_FORMAT_v210, */
2256   /* GST_VIDEO_FORMAT_v216, */
2257   /* GST_VIDEO_FORMAT_NV12, */
2258   {GST_VIDEO_FORMAT_NV12, PIX_FMT_NV12},
2259   /* GST_VIDEO_FORMAT_NV21, */
2260   {GST_VIDEO_FORMAT_NV21, PIX_FMT_NV21},
2261   /* GST_VIDEO_FORMAT_GRAY8, */
2262   {GST_VIDEO_FORMAT_GRAY8, PIX_FMT_GRAY8},
2263   /* GST_VIDEO_FORMAT_GRAY16_BE, */
2264   {GST_VIDEO_FORMAT_GRAY16_BE, PIX_FMT_GRAY16BE},
2265   /* GST_VIDEO_FORMAT_GRAY16_LE, */
2266   {GST_VIDEO_FORMAT_GRAY16_LE, PIX_FMT_GRAY16LE},
2267   /* GST_VIDEO_FORMAT_v308, */
2268   /* GST_VIDEO_FORMAT_Y800, */
2269   /* GST_VIDEO_FORMAT_Y16, */
2270   /* GST_VIDEO_FORMAT_RGB16, */
2271   {GST_VIDEO_FORMAT_RGB16, PIX_FMT_RGB565},
2272   /* GST_VIDEO_FORMAT_BGR16, */
2273   /* GST_VIDEO_FORMAT_RGB15, */
2274   {GST_VIDEO_FORMAT_RGB15, PIX_FMT_RGB555},
2275   /* GST_VIDEO_FORMAT_BGR15, */
2276   /* GST_VIDEO_FORMAT_UYVP, */
2277   /* GST_VIDEO_FORMAT_A420, */
2278   {GST_VIDEO_FORMAT_A420, PIX_FMT_YUVA420P},
2279   /* GST_VIDEO_FORMAT_RGB8_PALETTED, */
2280   {GST_VIDEO_FORMAT_RGB8P, PIX_FMT_PAL8},
2281   /* GST_VIDEO_FORMAT_YUV9, */
2282   {GST_VIDEO_FORMAT_YUV9, PIX_FMT_YUV410P},
2283   /* GST_VIDEO_FORMAT_YVU9, */
2284   /* GST_VIDEO_FORMAT_IYU1, */
2285   /* GST_VIDEO_FORMAT_ARGB64, */
2286   /* GST_VIDEO_FORMAT_AYUV64, */
2287   /* GST_VIDEO_FORMAT_r210, */
2288   {GST_VIDEO_FORMAT_I420_10LE, PIX_FMT_YUV420P10LE},
2289   {GST_VIDEO_FORMAT_I420_10BE, PIX_FMT_YUV420P10BE},
2290   {GST_VIDEO_FORMAT_I422_10LE, PIX_FMT_YUV422P10LE},
2291   {GST_VIDEO_FORMAT_I422_10BE, PIX_FMT_YUV422P10BE},
2292   {GST_VIDEO_FORMAT_Y444_10LE, PIX_FMT_YUV444P10LE},
2293   {GST_VIDEO_FORMAT_Y444_10BE, PIX_FMT_YUV444P10BE},
2294   {GST_VIDEO_FORMAT_GBR, PIX_FMT_GBRP},
2295   {GST_VIDEO_FORMAT_GBR_10LE, PIX_FMT_GBRP10LE},
2296   {GST_VIDEO_FORMAT_GBR_10BE, PIX_FMT_GBRP10BE},
2297 };
2298
2299 GstVideoFormat
2300 gst_ffmpeg_pixfmt_to_videoformat (enum PixelFormat pixfmt)
2301 {
2302   guint i;
2303
2304   for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++)
2305     if (pixtofmttable[i].pixfmt == pixfmt)
2306       return pixtofmttable[i].format;
2307
2308   GST_WARNING ("Unknown pixel format %d", pixfmt);
2309   return GST_VIDEO_FORMAT_UNKNOWN;
2310 }
2311
2312 enum PixelFormat
2313 gst_ffmpeg_videoformat_to_pixfmt (GstVideoFormat format)
2314 {
2315   guint i;
2316
2317   for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++)
2318     if (pixtofmttable[i].format == format)
2319       return pixtofmttable[i].pixfmt;
2320   return PIX_FMT_NONE;
2321 }
2322
2323 void
2324 gst_ffmpeg_videoinfo_to_context (GstVideoInfo * info, AVCodecContext * context)
2325 {
2326   gint i, bpp = 0;
2327
2328   context->width = GST_VIDEO_INFO_WIDTH (info);
2329   context->height = GST_VIDEO_INFO_HEIGHT (info);
2330   for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
2331     bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
2332   context->bits_per_coded_sample = bpp;
2333
2334   context->ticks_per_frame = 1;
2335   context->time_base.den = GST_VIDEO_INFO_FPS_N (info);
2336   context->time_base.num = GST_VIDEO_INFO_FPS_D (info);
2337
2338   context->sample_aspect_ratio.num = GST_VIDEO_INFO_PAR_N (info);
2339   context->sample_aspect_ratio.den = GST_VIDEO_INFO_PAR_D (info);
2340
2341   context->pix_fmt =
2342       gst_ffmpeg_videoformat_to_pixfmt (GST_VIDEO_INFO_FORMAT (info));
2343 }
2344
2345 void
2346 gst_ffmpeg_audioinfo_to_context (GstAudioInfo * info, AVCodecContext * context)
2347 {
2348   const AVCodec *codec;
2349   const enum AVSampleFormat *smpl_fmts;
2350   enum AVSampleFormat smpl_fmt = -1;
2351
2352   context->channels = info->channels;
2353   context->sample_rate = info->rate;
2354   context->channel_layout =
2355       gst_ffmpeg_channel_positions_to_layout (info->position, info->channels);
2356
2357   codec = context->codec;
2358
2359   smpl_fmts = codec->sample_fmts;
2360
2361   switch (info->finfo->format) {
2362     case GST_AUDIO_FORMAT_F32:
2363       if (smpl_fmts) {
2364         while (*smpl_fmts != -1) {
2365           if (*smpl_fmts == AV_SAMPLE_FMT_FLT) {
2366             smpl_fmt = *smpl_fmts;
2367             break;
2368           } else if (*smpl_fmts == AV_SAMPLE_FMT_FLTP) {
2369             smpl_fmt = *smpl_fmts;
2370           }
2371
2372           smpl_fmts++;
2373         }
2374       } else {
2375         smpl_fmt = AV_SAMPLE_FMT_FLT;
2376       }
2377       break;
2378     case GST_AUDIO_FORMAT_F64:
2379       if (smpl_fmts) {
2380         while (*smpl_fmts != -1) {
2381           if (*smpl_fmts == AV_SAMPLE_FMT_DBL) {
2382             smpl_fmt = *smpl_fmts;
2383             break;
2384           } else if (*smpl_fmts == AV_SAMPLE_FMT_DBLP) {
2385             smpl_fmt = *smpl_fmts;
2386           }
2387
2388           smpl_fmts++;
2389         }
2390       } else {
2391         smpl_fmt = AV_SAMPLE_FMT_DBL;
2392       }
2393       break;
2394     case GST_AUDIO_FORMAT_S32:
2395       if (smpl_fmts) {
2396         while (*smpl_fmts != -1) {
2397           if (*smpl_fmts == AV_SAMPLE_FMT_S32) {
2398             smpl_fmt = *smpl_fmts;
2399             break;
2400           } else if (*smpl_fmts == AV_SAMPLE_FMT_S32P) {
2401             smpl_fmt = *smpl_fmts;
2402           }
2403
2404           smpl_fmts++;
2405         }
2406       } else {
2407         smpl_fmt = AV_SAMPLE_FMT_S32;
2408       }
2409       break;
2410     case GST_AUDIO_FORMAT_S16:
2411       if (smpl_fmts) {
2412         while (*smpl_fmts != -1) {
2413           if (*smpl_fmts == AV_SAMPLE_FMT_S16) {
2414             smpl_fmt = *smpl_fmts;
2415             break;
2416           } else if (*smpl_fmts == AV_SAMPLE_FMT_S16P) {
2417             smpl_fmt = *smpl_fmts;
2418           }
2419
2420           smpl_fmts++;
2421         }
2422       } else {
2423         smpl_fmt = AV_SAMPLE_FMT_S16;
2424       }
2425       break;
2426     case GST_AUDIO_FORMAT_U8:
2427       if (smpl_fmts) {
2428         while (*smpl_fmts != -1) {
2429           if (*smpl_fmts == AV_SAMPLE_FMT_U8) {
2430             smpl_fmt = *smpl_fmts;
2431             break;
2432           } else if (*smpl_fmts == AV_SAMPLE_FMT_U8P) {
2433             smpl_fmt = *smpl_fmts;
2434           }
2435
2436           smpl_fmts++;
2437         }
2438       } else {
2439         smpl_fmt = AV_SAMPLE_FMT_U8;
2440       }
2441       break;
2442     default:
2443       break;
2444   }
2445
2446   g_assert (smpl_fmt != -1);
2447
2448   context->sample_fmt = smpl_fmt;
2449 }
2450
2451 /* Convert a GstCaps and a FFMPEG codec Type to a
2452  * AVCodecContext. If the context is ommitted, no fixed values
2453  * for video/audio size will be included in the context
2454  *
2455  * AVMediaType is primarily meant for uncompressed data GstCaps!
2456  */
2457
2458 void
2459 gst_ffmpeg_caps_with_codectype (enum AVMediaType type,
2460     const GstCaps * caps, AVCodecContext * context)
2461 {
2462   if (context == NULL)
2463     return;
2464
2465   switch (type) {
2466     case AVMEDIA_TYPE_VIDEO:
2467       gst_ffmpeg_caps_to_pixfmt (caps, context, TRUE);
2468       break;
2469
2470     case AVMEDIA_TYPE_AUDIO:
2471       gst_ffmpeg_caps_to_smpfmt (caps, context, TRUE);
2472       break;
2473
2474     default:
2475       /* unknown */
2476       break;
2477   }
2478 }
2479
2480 #if 0
2481 static void
2482 nal_escape (guint8 * dst, guint8 * src, guint size, guint * destsize)
2483 {
2484   guint8 *dstp = dst;
2485   guint8 *srcp = src;
2486   guint8 *end = src + size;
2487   gint count = 0;
2488
2489   while (srcp < end) {
2490     if (count == 2 && *srcp <= 0x03) {
2491       GST_DEBUG ("added escape code");
2492       *dstp++ = 0x03;
2493       count = 0;
2494     }
2495     if (*srcp == 0)
2496       count++;
2497     else
2498       count = 0;
2499
2500     GST_DEBUG ("copy %02x, count %d", *srcp, count);
2501     *dstp++ = *srcp++;
2502   }
2503   *destsize = dstp - dst;
2504 }
2505
2506 /* copy the config, escaping NAL units as we iterate them, if something fails we
2507  * copy everything and hope for the best. */
2508 static void
2509 copy_config (guint8 * dst, guint8 * src, guint size, guint * destsize)
2510 {
2511   guint8 *dstp = dst;
2512   guint8 *srcp = src;
2513   gint cnt, i;
2514   guint nalsize, esize;
2515
2516   /* check size */
2517   if (size < 7)
2518     goto full_copy;
2519
2520   /* check version */
2521   if (*srcp != 1)
2522     goto full_copy;
2523
2524   cnt = *(srcp + 5) & 0x1f;     /* Number of sps */
2525
2526   GST_DEBUG ("num SPS %d", cnt);
2527
2528   memcpy (dstp, srcp, 6);
2529   srcp += 6;
2530   dstp += 6;
2531
2532   for (i = 0; i < cnt; i++) {
2533     GST_DEBUG ("copy SPS %d", i);
2534     nalsize = (srcp[0] << 8) | srcp[1];
2535     nal_escape (dstp + 2, srcp + 2, nalsize, &esize);
2536     dstp[0] = esize >> 8;
2537     dstp[1] = esize & 0xff;
2538     dstp += esize + 2;
2539     srcp += nalsize + 2;
2540   }
2541
2542   cnt = *(dstp++) = *(srcp++);  /* Number of pps */
2543
2544   GST_DEBUG ("num PPS %d", cnt);
2545
2546   for (i = 0; i < cnt; i++) {
2547     GST_DEBUG ("copy PPS %d", i);
2548     nalsize = (srcp[0] << 8) | srcp[1];
2549     nal_escape (dstp + 2, srcp + 2, nalsize, &esize);
2550     dstp[0] = esize >> 8;
2551     dstp[1] = esize & 0xff;
2552     dstp += esize + 2;
2553     srcp += nalsize + 2;
2554   }
2555   *destsize = dstp - dst;
2556
2557   return;
2558
2559 full_copy:
2560   {
2561     GST_DEBUG ("something unexpected, doing full copy");
2562     memcpy (dst, src, size);
2563     *destsize = size;
2564     return;
2565   }
2566 }
2567 #endif
2568
2569 /*
2570  * caps_with_codecid () transforms a GstCaps for a known codec
2571  * ID into a filled-in context.
2572  * codec_data from caps will override possible extradata already in the context
2573  */
2574
2575 void
2576 gst_ffmpeg_caps_with_codecid (enum CodecID codec_id,
2577     enum AVMediaType codec_type, const GstCaps * caps, AVCodecContext * context)
2578 {
2579   GstStructure *str;
2580   const GValue *value;
2581   GstBuffer *buf;
2582
2583   GST_LOG ("codec_id:%d, codec_type:%d, caps:%" GST_PTR_FORMAT " context:%p",
2584       codec_id, codec_type, caps, context);
2585
2586   if (!context || !gst_caps_get_size (caps))
2587     return;
2588
2589   str = gst_caps_get_structure (caps, 0);
2590
2591   /* extradata parsing (esds [mpeg4], wma/wmv, msmpeg4v1/2/3, etc.) */
2592   if ((value = gst_structure_get_value (str, "codec_data"))) {
2593     GstMapInfo map;
2594
2595     buf = gst_value_get_buffer (value);
2596     gst_buffer_map (buf, &map, GST_MAP_READ);
2597
2598     /* free the old one if it is there */
2599     if (context->extradata)
2600       av_free (context->extradata);
2601
2602 #if 0
2603     if (codec_id == CODEC_ID_H264) {
2604       guint extrasize;
2605
2606       GST_DEBUG ("copy, escaping codec_data %d", size);
2607       /* ffmpeg h264 expects the codec_data to be escaped, there is no real
2608        * reason for this but let's just escape it for now. Start by allocating
2609        * enough space, x2 is more than enough.
2610        *
2611        * FIXME, we disabled escaping because some file already contain escaped
2612        * codec_data and then we escape twice and fail. It's better to leave it
2613        * as is, as that is what most players do. */
2614       context->extradata =
2615           av_mallocz (GST_ROUND_UP_16 (size * 2 +
2616               FF_INPUT_BUFFER_PADDING_SIZE));
2617       copy_config (context->extradata, data, size, &extrasize);
2618       GST_DEBUG ("escaped size: %d", extrasize);
2619       context->extradata_size = extrasize;
2620     } else
2621 #endif
2622     {
2623       /* allocate with enough padding */
2624       GST_DEBUG ("copy codec_data");
2625       context->extradata =
2626           av_mallocz (GST_ROUND_UP_16 (map.size +
2627               FF_INPUT_BUFFER_PADDING_SIZE));
2628       memcpy (context->extradata, map.data, map.size);
2629       context->extradata_size = map.size;
2630     }
2631
2632     /* Hack for VC1. Sometimes the first (length) byte is 0 for some files */
2633     if (codec_id == CODEC_ID_VC1 && map.size > 0 && map.data[0] == 0) {
2634       context->extradata[0] = (guint8) map.size;
2635     }
2636
2637     GST_DEBUG ("have codec data of size %" G_GSIZE_FORMAT, map.size);
2638
2639     gst_buffer_unmap (buf, &map);
2640   } else if (context->extradata == NULL && codec_id != CODEC_ID_AAC_LATM &&
2641       codec_id != CODEC_ID_FLAC) {
2642     /* no extradata, alloc dummy with 0 sized, some codecs insist on reading
2643      * extradata anyway which makes then segfault. */
2644     context->extradata =
2645         av_mallocz (GST_ROUND_UP_16 (FF_INPUT_BUFFER_PADDING_SIZE));
2646     context->extradata_size = 0;
2647     GST_DEBUG ("no codec data");
2648   }
2649
2650   switch (codec_id) {
2651     case CODEC_ID_MPEG4:
2652     {
2653       const gchar *mime = gst_structure_get_name (str);
2654
2655       if (!strcmp (mime, "video/x-divx"))
2656         context->codec_tag = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
2657       else if (!strcmp (mime, "video/x-xvid"))
2658         context->codec_tag = GST_MAKE_FOURCC ('X', 'V', 'I', 'D');
2659       else if (!strcmp (mime, "video/x-3ivx"))
2660         context->codec_tag = GST_MAKE_FOURCC ('3', 'I', 'V', '1');
2661       else if (!strcmp (mime, "video/mpeg"))
2662         context->codec_tag = GST_MAKE_FOURCC ('m', 'p', '4', 'v');
2663     }
2664       break;
2665
2666     case CODEC_ID_SVQ3:
2667       /* FIXME: this is a workaround for older gst-plugins releases
2668        * (<= 0.8.9). This should be removed at some point, because
2669        * it causes wrong decoded frame order. */
2670       if (!context->extradata) {
2671         gint halfpel_flag, thirdpel_flag, low_delay, unknown_svq3_flag;
2672         guint16 flags;
2673
2674         if (gst_structure_get_int (str, "halfpel_flag", &halfpel_flag) ||
2675             gst_structure_get_int (str, "thirdpel_flag", &thirdpel_flag) ||
2676             gst_structure_get_int (str, "low_delay", &low_delay) ||
2677             gst_structure_get_int (str, "unknown_svq3_flag",
2678                 &unknown_svq3_flag)) {
2679           context->extradata = (guint8 *) av_mallocz (0x64);
2680           g_stpcpy ((gchar *) context->extradata, "SVQ3");
2681           flags = 1 << 3;
2682           flags |= low_delay;
2683           flags = flags << 2;
2684           flags |= unknown_svq3_flag;
2685           flags = flags << 6;
2686           flags |= halfpel_flag;
2687           flags = flags << 1;
2688           flags |= thirdpel_flag;
2689           flags = flags << 3;
2690
2691           flags = GUINT16_FROM_LE (flags);
2692
2693           memcpy ((gchar *) context->extradata + 0x62, &flags, 2);
2694           context->extradata_size = 0x64;
2695         }
2696       }
2697       break;
2698
2699     case CODEC_ID_MSRLE:
2700     case CODEC_ID_QTRLE:
2701     case CODEC_ID_TSCC:
2702     case CODEC_ID_CSCD:
2703     case CODEC_ID_APE:
2704     {
2705       gint depth;
2706
2707       if (gst_structure_get_int (str, "depth", &depth)) {
2708         context->bits_per_coded_sample = depth;
2709       } else {
2710         GST_WARNING ("No depth field in caps %" GST_PTR_FORMAT, caps);
2711       }
2712
2713     }
2714       break;
2715
2716     case CODEC_ID_RV10:
2717     case CODEC_ID_RV20:
2718     case CODEC_ID_RV30:
2719     case CODEC_ID_RV40:
2720     {
2721       gint format;
2722
2723       if (gst_structure_get_int (str, "format", &format))
2724         context->sub_id = format;
2725
2726       break;
2727     }
2728     case CODEC_ID_COOK:
2729     case CODEC_ID_RA_288:
2730     case CODEC_ID_RA_144:
2731     case CODEC_ID_SIPR:
2732     {
2733       gint leaf_size;
2734       gint bitrate;
2735
2736       if (gst_structure_get_int (str, "leaf_size", &leaf_size))
2737         context->block_align = leaf_size;
2738       if (gst_structure_get_int (str, "bitrate", &bitrate))
2739         context->bit_rate = bitrate;
2740     }
2741     case CODEC_ID_ALAC:
2742       gst_structure_get_int (str, "samplesize",
2743           &context->bits_per_coded_sample);
2744       break;
2745
2746     case CODEC_ID_DVVIDEO:
2747     {
2748       const gchar *format;
2749
2750       if ((format = gst_structure_get_string (str, "format"))) {
2751
2752         if (g_str_equal (format, "YUY2"))
2753           context->pix_fmt = PIX_FMT_YUYV422;
2754         else if (g_str_equal (format, "I420"))
2755           context->pix_fmt = PIX_FMT_YUV420P;
2756         else if (g_str_equal (format, "A420"))
2757           context->pix_fmt = PIX_FMT_YUVA420P;
2758         else if (g_str_equal (format, "Y41B"))
2759           context->pix_fmt = PIX_FMT_YUV411P;
2760         else if (g_str_equal (format, "Y42B"))
2761           context->pix_fmt = PIX_FMT_YUV422P;
2762         else if (g_str_equal (format, "YUV9"))
2763           context->pix_fmt = PIX_FMT_YUV410P;
2764         else {
2765           GST_WARNING ("couldn't convert format %s" " to a pixel format",
2766               format);
2767         }
2768       } else
2769         GST_WARNING ("No specified format");
2770       break;
2771     }
2772     case CODEC_ID_H263P:
2773     {
2774       gboolean val;
2775
2776       if (!gst_structure_get_boolean (str, "annex-f", &val) || val)
2777         context->flags |= CODEC_FLAG_4MV;
2778       else
2779         context->flags &= ~CODEC_FLAG_4MV;
2780       if ((!gst_structure_get_boolean (str, "annex-i", &val) || val) &&
2781           (!gst_structure_get_boolean (str, "annex-t", &val) || val))
2782         context->flags |= CODEC_FLAG_AC_PRED;
2783       else
2784         context->flags &= ~CODEC_FLAG_AC_PRED;
2785       if (!gst_structure_get_boolean (str, "annex-j", &val) || val)
2786         context->flags |= CODEC_FLAG_LOOP_FILTER;
2787       else
2788         context->flags &= ~CODEC_FLAG_LOOP_FILTER;
2789       break;
2790     }
2791     case CODEC_ID_ADPCM_G726:
2792     {
2793       const gchar *layout;
2794
2795       if ((layout = gst_structure_get_string (str, "layout"))) {
2796         if (!strcmp (layout, "g721")) {
2797           context->sample_rate = 8000;
2798           context->channels = 1;
2799           context->bit_rate = 32000;
2800         }
2801       }
2802       break;
2803     }
2804     default:
2805       break;
2806   }
2807
2808   if (!gst_caps_is_fixed (caps))
2809     return;
2810
2811   /* common properties (width, height, fps) */
2812   switch (codec_type) {
2813     case AVMEDIA_TYPE_VIDEO:
2814       gst_ffmpeg_caps_to_pixfmt (caps, context, codec_id == CODEC_ID_RAWVIDEO);
2815       break;
2816     case AVMEDIA_TYPE_AUDIO:
2817       gst_ffmpeg_caps_to_smpfmt (caps, context, FALSE);
2818       break;
2819     default:
2820       break;
2821   }
2822
2823   /* fixup of default settings */
2824   switch (codec_id) {
2825     case CODEC_ID_QCELP:
2826       /* QCELP is always mono, no matter what the caps say */
2827       context->channels = 1;
2828       break;
2829     default:
2830       break;
2831   }
2832 }
2833
2834 /* _formatid_to_caps () is meant for muxers/demuxers, it
2835  * transforms a name (ffmpeg way of ID'ing these, why don't
2836  * they have unique numerical IDs?) to the corresponding
2837  * caps belonging to that mux-format
2838  *
2839  * Note: we don't need any additional info because the caps
2840  * isn't supposed to contain any useful info besides the
2841  * media type anyway
2842  */
2843
2844 GstCaps *
2845 gst_ffmpeg_formatid_to_caps (const gchar * format_name)
2846 {
2847   GstCaps *caps = NULL;
2848
2849   if (!strcmp (format_name, "mpeg")) {
2850     caps = gst_caps_new_simple ("video/mpeg",
2851         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
2852   } else if (!strcmp (format_name, "mpegts")) {
2853     caps = gst_caps_new_simple ("video/mpegts",
2854         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
2855   } else if (!strcmp (format_name, "rm")) {
2856     caps = gst_caps_new_simple ("application/x-pn-realmedia",
2857         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
2858   } else if (!strcmp (format_name, "asf")) {
2859     caps = gst_caps_new_empty_simple ("video/x-ms-asf");
2860   } else if (!strcmp (format_name, "avi")) {
2861     caps = gst_caps_new_empty_simple ("video/x-msvideo");
2862   } else if (!strcmp (format_name, "wav")) {
2863     caps = gst_caps_new_empty_simple ("audio/x-wav");
2864   } else if (!strcmp (format_name, "ape")) {
2865     caps = gst_caps_new_empty_simple ("application/x-ape");
2866   } else if (!strcmp (format_name, "swf")) {
2867     caps = gst_caps_new_empty_simple ("application/x-shockwave-flash");
2868   } else if (!strcmp (format_name, "au")) {
2869     caps = gst_caps_new_empty_simple ("audio/x-au");
2870   } else if (!strcmp (format_name, "dv")) {
2871     caps = gst_caps_new_simple ("video/x-dv",
2872         "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
2873   } else if (!strcmp (format_name, "4xm")) {
2874     caps = gst_caps_new_empty_simple ("video/x-4xm");
2875   } else if (!strcmp (format_name, "matroska")) {
2876     caps = gst_caps_new_empty_simple ("video/x-matroska");
2877   } else if (!strcmp (format_name, "mp3")) {
2878     caps = gst_caps_new_empty_simple ("application/x-id3");
2879   } else if (!strcmp (format_name, "flic")) {
2880     caps = gst_caps_new_empty_simple ("video/x-fli");
2881   } else if (!strcmp (format_name, "flv")) {
2882     caps = gst_caps_new_empty_simple ("video/x-flv");
2883   } else if (!strcmp (format_name, "tta")) {
2884     caps = gst_caps_new_empty_simple ("audio/x-ttafile");
2885   } else if (!strcmp (format_name, "aiff")) {
2886     caps = gst_caps_new_empty_simple ("audio/x-aiff");
2887   } else if (!strcmp (format_name, "mov_mp4_m4a_3gp_3g2")) {
2888     caps =
2889         gst_caps_from_string
2890         ("application/x-3gp; video/quicktime; audio/x-m4a");
2891   } else if (!strcmp (format_name, "mov")) {
2892     caps = gst_caps_from_string ("video/quicktime,variant=(string)apple");
2893   } else if (!strcmp (format_name, "mp4")) {
2894     caps = gst_caps_from_string ("video/quicktime,variant=(string)iso");
2895   } else if (!strcmp (format_name, "3gp")) {
2896     caps = gst_caps_from_string ("video/quicktime,variant=(string)3gpp");
2897   } else if (!strcmp (format_name, "3g2")) {
2898     caps = gst_caps_from_string ("video/quicktime,variant=(string)3g2");
2899   } else if (!strcmp (format_name, "psp")) {
2900     caps = gst_caps_from_string ("video/quicktime,variant=(string)psp");
2901   } else if (!strcmp (format_name, "ipod")) {
2902     caps = gst_caps_from_string ("video/quicktime,variant=(string)ipod");
2903   } else if (!strcmp (format_name, "aac")) {
2904     caps = gst_caps_new_simple ("audio/mpeg",
2905         "mpegversion", G_TYPE_INT, 4, NULL);
2906   } else if (!strcmp (format_name, "gif")) {
2907     caps = gst_caps_from_string ("image/gif");
2908   } else if (!strcmp (format_name, "ogg")) {
2909     caps = gst_caps_from_string ("application/ogg");
2910   } else if (!strcmp (format_name, "mxf") || !strcmp (format_name, "mxf_d10")) {
2911     caps = gst_caps_from_string ("application/mxf");
2912   } else if (!strcmp (format_name, "gxf")) {
2913     caps = gst_caps_from_string ("application/gxf");
2914   } else if (!strcmp (format_name, "yuv4mpegpipe")) {
2915     caps = gst_caps_new_simple ("application/x-yuv4mpeg",
2916         "y4mversion", G_TYPE_INT, 2, NULL);
2917   } else if (!strcmp (format_name, "mpc")) {
2918     caps = gst_caps_from_string ("audio/x-musepack, streamversion = (int) 7");
2919   } else if (!strcmp (format_name, "vqf")) {
2920     caps = gst_caps_from_string ("audio/x-vqf");
2921   } else if (!strcmp (format_name, "nsv")) {
2922     caps = gst_caps_from_string ("video/x-nsv");
2923   } else if (!strcmp (format_name, "amr")) {
2924     caps = gst_caps_from_string ("audio/x-amr-nb-sh");
2925   } else if (!strcmp (format_name, "webm")) {
2926     caps = gst_caps_from_string ("video/webm");
2927   } else if (!strcmp (format_name, "voc")) {
2928     caps = gst_caps_from_string ("audio/x-voc");
2929   } else {
2930     gchar *name;
2931
2932     GST_LOG ("Could not create stream format caps for %s", format_name);
2933     name = g_strdup_printf ("application/x-gst-av-%s", format_name);
2934     caps = gst_caps_new_empty_simple (name);
2935     g_free (name);
2936   }
2937
2938   return caps;
2939 }
2940
2941 gboolean
2942 gst_ffmpeg_formatid_get_codecids (const gchar * format_name,
2943     enum CodecID ** video_codec_list, enum CodecID ** audio_codec_list,
2944     AVOutputFormat * plugin)
2945 {
2946   static enum CodecID tmp_vlist[] = {
2947     CODEC_ID_NONE,
2948     CODEC_ID_NONE
2949   };
2950   static enum CodecID tmp_alist[] = {
2951     CODEC_ID_NONE,
2952     CODEC_ID_NONE
2953   };
2954
2955   GST_LOG ("format_name : %s", format_name);
2956
2957   if (!strcmp (format_name, "mp4")) {
2958     static enum CodecID mp4_video_list[] = {
2959       CODEC_ID_MPEG4, CODEC_ID_H264,
2960       CODEC_ID_MJPEG,
2961       CODEC_ID_NONE
2962     };
2963     static enum CodecID mp4_audio_list[] = {
2964       CODEC_ID_AAC, CODEC_ID_MP3,
2965       CODEC_ID_NONE
2966     };
2967
2968     *video_codec_list = mp4_video_list;
2969     *audio_codec_list = mp4_audio_list;
2970   } else if (!strcmp (format_name, "mpeg")) {
2971     static enum CodecID mpeg_video_list[] = { CODEC_ID_MPEG1VIDEO,
2972       CODEC_ID_MPEG2VIDEO,
2973       CODEC_ID_H264,
2974       CODEC_ID_NONE
2975     };
2976     static enum CodecID mpeg_audio_list[] = { CODEC_ID_MP1,
2977       CODEC_ID_MP2,
2978       CODEC_ID_MP3,
2979       CODEC_ID_NONE
2980     };
2981
2982     *video_codec_list = mpeg_video_list;
2983     *audio_codec_list = mpeg_audio_list;
2984   } else if (!strcmp (format_name, "dvd")) {
2985     static enum CodecID mpeg_video_list[] = { CODEC_ID_MPEG2VIDEO,
2986       CODEC_ID_NONE
2987     };
2988     static enum CodecID mpeg_audio_list[] = { CODEC_ID_MP2,
2989       CODEC_ID_AC3,
2990       CODEC_ID_DTS,
2991       CODEC_ID_PCM_S16BE,
2992       CODEC_ID_NONE
2993     };
2994
2995     *video_codec_list = mpeg_video_list;
2996     *audio_codec_list = mpeg_audio_list;
2997   } else if (!strcmp (format_name, "mpegts")) {
2998     static enum CodecID mpegts_video_list[] = { CODEC_ID_MPEG1VIDEO,
2999       CODEC_ID_MPEG2VIDEO,
3000       CODEC_ID_H264,
3001       CODEC_ID_NONE
3002     };
3003     static enum CodecID mpegts_audio_list[] = { CODEC_ID_MP2,
3004       CODEC_ID_MP3,
3005       CODEC_ID_AC3,
3006       CODEC_ID_DTS,
3007       CODEC_ID_AAC,
3008       CODEC_ID_NONE
3009     };
3010
3011     *video_codec_list = mpegts_video_list;
3012     *audio_codec_list = mpegts_audio_list;
3013   } else if (!strcmp (format_name, "vob")) {
3014     static enum CodecID vob_video_list[] =
3015         { CODEC_ID_MPEG2VIDEO, CODEC_ID_NONE };
3016     static enum CodecID vob_audio_list[] = { CODEC_ID_MP2, CODEC_ID_AC3,
3017       CODEC_ID_DTS, CODEC_ID_NONE
3018     };
3019
3020     *video_codec_list = vob_video_list;
3021     *audio_codec_list = vob_audio_list;
3022   } else if (!strcmp (format_name, "flv")) {
3023     static enum CodecID flv_video_list[] = { CODEC_ID_FLV1, CODEC_ID_NONE };
3024     static enum CodecID flv_audio_list[] = { CODEC_ID_MP3, CODEC_ID_NONE };
3025
3026     *video_codec_list = flv_video_list;
3027     *audio_codec_list = flv_audio_list;
3028   } else if (!strcmp (format_name, "asf")) {
3029     static enum CodecID asf_video_list[] =
3030         { CODEC_ID_WMV1, CODEC_ID_WMV2, CODEC_ID_MSMPEG4V3, CODEC_ID_NONE };
3031     static enum CodecID asf_audio_list[] =
3032         { CODEC_ID_WMAV1, CODEC_ID_WMAV2, CODEC_ID_MP3, CODEC_ID_NONE };
3033
3034     *video_codec_list = asf_video_list;
3035     *audio_codec_list = asf_audio_list;
3036   } else if (!strcmp (format_name, "dv")) {
3037     static enum CodecID dv_video_list[] = { CODEC_ID_DVVIDEO, CODEC_ID_NONE };
3038     static enum CodecID dv_audio_list[] = { CODEC_ID_PCM_S16LE, CODEC_ID_NONE };
3039
3040     *video_codec_list = dv_video_list;
3041     *audio_codec_list = dv_audio_list;
3042   } else if (!strcmp (format_name, "mov")) {
3043     static enum CodecID mov_video_list[] = {
3044       CODEC_ID_SVQ1, CODEC_ID_SVQ3, CODEC_ID_MPEG4,
3045       CODEC_ID_H263, CODEC_ID_H263P,
3046       CODEC_ID_H264, CODEC_ID_DVVIDEO,
3047       CODEC_ID_MJPEG,
3048       CODEC_ID_NONE
3049     };
3050     static enum CodecID mov_audio_list[] = {
3051       CODEC_ID_PCM_MULAW, CODEC_ID_PCM_ALAW, CODEC_ID_ADPCM_IMA_QT,
3052       CODEC_ID_MACE3, CODEC_ID_MACE6, CODEC_ID_AAC,
3053       CODEC_ID_AMR_NB, CODEC_ID_AMR_WB,
3054       CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE,
3055       CODEC_ID_MP3, CODEC_ID_NONE
3056     };
3057
3058     *video_codec_list = mov_video_list;
3059     *audio_codec_list = mov_audio_list;
3060   } else if ((!strcmp (format_name, "3gp") || !strcmp (format_name, "3g2"))) {
3061     static enum CodecID tgp_video_list[] = {
3062       CODEC_ID_MPEG4, CODEC_ID_H263, CODEC_ID_H263P, CODEC_ID_H264,
3063       CODEC_ID_NONE
3064     };
3065     static enum CodecID tgp_audio_list[] = {
3066       CODEC_ID_AMR_NB, CODEC_ID_AMR_WB,
3067       CODEC_ID_AAC,
3068       CODEC_ID_NONE
3069     };
3070
3071     *video_codec_list = tgp_video_list;
3072     *audio_codec_list = tgp_audio_list;
3073   } else if (!strcmp (format_name, "mmf")) {
3074     static enum CodecID mmf_audio_list[] = {
3075       CODEC_ID_ADPCM_YAMAHA, CODEC_ID_NONE
3076     };
3077     *video_codec_list = NULL;
3078     *audio_codec_list = mmf_audio_list;
3079   } else if (!strcmp (format_name, "amr")) {
3080     static enum CodecID amr_audio_list[] = {
3081       CODEC_ID_AMR_NB, CODEC_ID_AMR_WB,
3082       CODEC_ID_NONE
3083     };
3084     *video_codec_list = NULL;
3085     *audio_codec_list = amr_audio_list;
3086   } else if (!strcmp (format_name, "gif")) {
3087     static enum CodecID gif_image_list[] = {
3088       CODEC_ID_RAWVIDEO, CODEC_ID_NONE
3089     };
3090     *video_codec_list = gif_image_list;
3091     *audio_codec_list = NULL;
3092   } else if ((plugin->audio_codec != CODEC_ID_NONE) ||
3093       (plugin->video_codec != CODEC_ID_NONE)) {
3094     tmp_vlist[0] = plugin->video_codec;
3095     tmp_alist[0] = plugin->audio_codec;
3096
3097     *video_codec_list = tmp_vlist;
3098     *audio_codec_list = tmp_alist;
3099   } else {
3100     GST_LOG ("Format %s not found", format_name);
3101     return FALSE;
3102   }
3103
3104   return TRUE;
3105 }
3106
3107 /* Convert a GstCaps to a FFMPEG codec ID. Size et all
3108  * are omitted, that can be queried by the user itself,
3109  * we're not eating the GstCaps or anything
3110  * A pointer to an allocated context is also needed for
3111  * optional extra info
3112  */
3113
3114 enum CodecID
3115 gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
3116 {
3117   enum CodecID id = CODEC_ID_NONE;
3118   const gchar *mimetype;
3119   const GstStructure *structure;
3120   gboolean video = FALSE, audio = FALSE;        /* we want to be sure! */
3121
3122   g_return_val_if_fail (caps != NULL, CODEC_ID_NONE);
3123   g_return_val_if_fail (gst_caps_get_size (caps) == 1, CODEC_ID_NONE);
3124   structure = gst_caps_get_structure (caps, 0);
3125
3126   mimetype = gst_structure_get_name (structure);
3127
3128   if (!strcmp (mimetype, "video/x-raw")) {
3129     id = CODEC_ID_RAWVIDEO;
3130     video = TRUE;
3131   } else if (!strcmp (mimetype, "audio/x-raw")) {
3132     GstAudioInfo info;
3133
3134     if (gst_audio_info_from_caps (&info, caps)) {
3135       switch (GST_AUDIO_INFO_FORMAT (&info)) {
3136         case GST_AUDIO_FORMAT_S8:
3137           id = CODEC_ID_PCM_S8;
3138           break;
3139         case GST_AUDIO_FORMAT_U8:
3140           id = CODEC_ID_PCM_U8;
3141           break;
3142         case GST_AUDIO_FORMAT_S16LE:
3143           id = CODEC_ID_PCM_S16LE;
3144           break;
3145         case GST_AUDIO_FORMAT_S16BE:
3146           id = CODEC_ID_PCM_S16BE;
3147           break;
3148         case GST_AUDIO_FORMAT_U16LE:
3149           id = CODEC_ID_PCM_U16LE;
3150           break;
3151         case GST_AUDIO_FORMAT_U16BE:
3152           id = CODEC_ID_PCM_U16BE;
3153           break;
3154         default:
3155           break;
3156       }
3157       if (id != CODEC_ID_NONE)
3158         audio = TRUE;
3159     }
3160   } else if (!strcmp (mimetype, "audio/x-mulaw")) {
3161     id = CODEC_ID_PCM_MULAW;
3162     audio = TRUE;
3163   } else if (!strcmp (mimetype, "audio/x-alaw")) {
3164     id = CODEC_ID_PCM_ALAW;
3165     audio = TRUE;
3166   } else if (!strcmp (mimetype, "video/x-dv")) {
3167     gboolean sys_strm;
3168
3169     if (gst_structure_get_boolean (structure, "systemstream", &sys_strm) &&
3170         !sys_strm) {
3171       id = CODEC_ID_DVVIDEO;
3172       video = TRUE;
3173     }
3174   } else if (!strcmp (mimetype, "audio/x-dv")) {        /* ??? */
3175     id = CODEC_ID_DVAUDIO;
3176     audio = TRUE;
3177   } else if (!strcmp (mimetype, "video/x-h263")) {
3178     const gchar *h263version =
3179         gst_structure_get_string (structure, "h263version");
3180     if (h263version && !strcmp (h263version, "h263p"))
3181       id = CODEC_ID_H263P;
3182     else
3183       id = CODEC_ID_H263;
3184     video = TRUE;
3185   } else if (!strcmp (mimetype, "video/x-intel-h263")) {
3186     id = CODEC_ID_H263I;
3187     video = TRUE;
3188   } else if (!strcmp (mimetype, "video/x-h261")) {
3189     id = CODEC_ID_H261;
3190     video = TRUE;
3191   } else if (!strcmp (mimetype, "video/mpeg")) {
3192     gboolean sys_strm;
3193     gint mpegversion;
3194
3195     if (gst_structure_get_boolean (structure, "systemstream", &sys_strm) &&
3196         gst_structure_get_int (structure, "mpegversion", &mpegversion) &&
3197         !sys_strm) {
3198       switch (mpegversion) {
3199         case 1:
3200           id = CODEC_ID_MPEG1VIDEO;
3201           break;
3202         case 2:
3203           id = CODEC_ID_MPEG2VIDEO;
3204           break;
3205         case 4:
3206           id = CODEC_ID_MPEG4;
3207           break;
3208       }
3209     }
3210     if (id != CODEC_ID_NONE)
3211       video = TRUE;
3212   } else if (!strcmp (mimetype, "image/jpeg")) {
3213     id = CODEC_ID_MJPEG;        /* A... B... */
3214     video = TRUE;
3215   } else if (!strcmp (mimetype, "video/x-jpeg-b")) {
3216     id = CODEC_ID_MJPEGB;
3217     video = TRUE;
3218   } else if (!strcmp (mimetype, "video/x-wmv")) {
3219     gint wmvversion = 0;
3220
3221     if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
3222       switch (wmvversion) {
3223         case 1:
3224           id = CODEC_ID_WMV1;
3225           break;
3226         case 2:
3227           id = CODEC_ID_WMV2;
3228           break;
3229         case 3:
3230         {
3231           const gchar *format;
3232
3233           /* WMV3 unless the fourcc exists and says otherwise */
3234           id = CODEC_ID_WMV3;
3235
3236           if ((format = gst_structure_get_string (structure, "format")) &&
3237               (g_str_equal (format, "WVC1") || g_str_equal (format, "WMVA")))
3238             id = CODEC_ID_VC1;
3239
3240           break;
3241         }
3242       }
3243     }
3244     if (id != CODEC_ID_NONE)
3245       video = TRUE;
3246   } else if (!strcmp (mimetype, "audio/x-vorbis")) {
3247     id = CODEC_ID_VORBIS;
3248     audio = TRUE;
3249   } else if (!strcmp (mimetype, "audio/x-qdm2")) {
3250     id = CODEC_ID_QDM2;
3251     audio = TRUE;
3252   } else if (!strcmp (mimetype, "audio/mpeg")) {
3253     gint layer = 0;
3254     gint mpegversion = 0;
3255
3256     if (gst_structure_get_int (structure, "mpegversion", &mpegversion)) {
3257       switch (mpegversion) {
3258         case 2:                /* ffmpeg uses faad for both... */
3259         case 4:
3260           id = CODEC_ID_AAC;
3261           break;
3262         case 1:
3263           if (gst_structure_get_int (structure, "layer", &layer)) {
3264             switch (layer) {
3265               case 1:
3266                 id = CODEC_ID_MP1;
3267                 break;
3268               case 2:
3269                 id = CODEC_ID_MP2;
3270                 break;
3271               case 3:
3272                 id = CODEC_ID_MP3;
3273                 break;
3274             }
3275           }
3276       }
3277     }
3278     if (id != CODEC_ID_NONE)
3279       audio = TRUE;
3280   } else if (!strcmp (mimetype, "audio/x-musepack")) {
3281     gint streamversion = -1;
3282
3283     if (gst_structure_get_int (structure, "streamversion", &streamversion)) {
3284       if (streamversion == 7)
3285         id = CODEC_ID_MUSEPACK7;
3286     } else {
3287       id = CODEC_ID_MUSEPACK7;
3288     }
3289   } else if (!strcmp (mimetype, "audio/x-wma")) {
3290     gint wmaversion = 0;
3291
3292     if (gst_structure_get_int (structure, "wmaversion", &wmaversion)) {
3293       switch (wmaversion) {
3294         case 1:
3295           id = CODEC_ID_WMAV1;
3296           break;
3297         case 2:
3298           id = CODEC_ID_WMAV2;
3299           break;
3300         case 3:
3301           id = CODEC_ID_WMAPRO;
3302           break;
3303       }
3304     }
3305     if (id != CODEC_ID_NONE)
3306       audio = TRUE;
3307   } else if (!strcmp (mimetype, "audio/x-wms")) {
3308     id = CODEC_ID_WMAVOICE;
3309     audio = TRUE;
3310   } else if (!strcmp (mimetype, "audio/x-ac3")) {
3311     id = CODEC_ID_AC3;
3312     audio = TRUE;
3313   } else if (!strcmp (mimetype, "audio/x-eac3")) {
3314     id = CODEC_ID_EAC3;
3315     audio = TRUE;
3316   } else if (!strcmp (mimetype, "audio/x-vnd.sony.atrac3") ||
3317       !strcmp (mimetype, "audio/atrac3")) {
3318     id = CODEC_ID_ATRAC3;
3319     audio = TRUE;
3320   } else if (!strcmp (mimetype, "audio/x-dts")) {
3321     id = CODEC_ID_DTS;
3322     audio = TRUE;
3323   } else if (!strcmp (mimetype, "application/x-ape")) {
3324     id = CODEC_ID_APE;
3325     audio = TRUE;
3326   } else if (!strcmp (mimetype, "video/x-msmpeg")) {
3327     gint msmpegversion = 0;
3328
3329     if (gst_structure_get_int (structure, "msmpegversion", &msmpegversion)) {
3330       switch (msmpegversion) {
3331         case 41:
3332           id = CODEC_ID_MSMPEG4V1;
3333           break;
3334         case 42:
3335           id = CODEC_ID_MSMPEG4V2;
3336           break;
3337         case 43:
3338           id = CODEC_ID_MSMPEG4V3;
3339           break;
3340       }
3341     }
3342     if (id != CODEC_ID_NONE)
3343       video = TRUE;
3344   } else if (!strcmp (mimetype, "video/x-svq")) {
3345     gint svqversion = 0;
3346
3347     if (gst_structure_get_int (structure, "svqversion", &svqversion)) {
3348       switch (svqversion) {
3349         case 1:
3350           id = CODEC_ID_SVQ1;
3351           break;
3352         case 3:
3353           id = CODEC_ID_SVQ3;
3354           break;
3355       }
3356     }
3357     if (id != CODEC_ID_NONE)
3358       video = TRUE;
3359   } else if (!strcmp (mimetype, "video/x-huffyuv")) {
3360     id = CODEC_ID_HUFFYUV;
3361     video = TRUE;
3362   } else if (!strcmp (mimetype, "audio/x-mace")) {
3363     gint maceversion = 0;
3364
3365     if (gst_structure_get_int (structure, "maceversion", &maceversion)) {
3366       switch (maceversion) {
3367         case 3:
3368           id = CODEC_ID_MACE3;
3369           break;
3370         case 6:
3371           id = CODEC_ID_MACE6;
3372           break;
3373       }
3374     }
3375     if (id != CODEC_ID_NONE)
3376       audio = TRUE;
3377   } else if (!strcmp (mimetype, "video/x-theora")) {
3378     id = CODEC_ID_THEORA;
3379     video = TRUE;
3380   } else if (!strcmp (mimetype, "video/x-vp3")) {
3381     id = CODEC_ID_VP3;
3382     video = TRUE;
3383   } else if (!strcmp (mimetype, "video/x-vp5")) {
3384     id = CODEC_ID_VP5;
3385     video = TRUE;
3386   } else if (!strcmp (mimetype, "video/x-vp6")) {
3387     id = CODEC_ID_VP6;
3388     video = TRUE;
3389   } else if (!strcmp (mimetype, "video/x-vp6-flash")) {
3390     id = CODEC_ID_VP6F;
3391     video = TRUE;
3392   } else if (!strcmp (mimetype, "video/x-vp6-alpha")) {
3393     id = CODEC_ID_VP6A;
3394     video = TRUE;
3395   } else if (!strcmp (mimetype, "video/x-vp8")) {
3396     id = CODEC_ID_VP8;
3397     video = TRUE;
3398   } else if (!strcmp (mimetype, "video/x-flash-screen")) {
3399     id = CODEC_ID_FLASHSV;
3400     video = TRUE;
3401   } else if (!strcmp (mimetype, "video/x-indeo")) {
3402     gint indeoversion = 0;
3403
3404     if (gst_structure_get_int (structure, "indeoversion", &indeoversion)) {
3405       switch (indeoversion) {
3406         case 5:
3407           id = CODEC_ID_INDEO5;
3408           break;
3409         case 4:
3410           id = CODEC_ID_INDEO4;
3411           break;
3412         case 3:
3413           id = CODEC_ID_INDEO3;
3414           break;
3415         case 2:
3416           id = CODEC_ID_INDEO2;
3417           break;
3418       }
3419       if (id != CODEC_ID_NONE)
3420         video = TRUE;
3421     }
3422   } else if (!strcmp (mimetype, "video/x-divx")) {
3423     gint divxversion = 0;
3424
3425     if (gst_structure_get_int (structure, "divxversion", &divxversion)) {
3426       switch (divxversion) {
3427         case 3:
3428           id = CODEC_ID_MSMPEG4V3;
3429           break;
3430         case 4:
3431         case 5:
3432           id = CODEC_ID_MPEG4;
3433           break;
3434       }
3435     }
3436     if (id != CODEC_ID_NONE)
3437       video = TRUE;
3438   } else if (!strcmp (mimetype, "video/x-3ivx")) {
3439     id = CODEC_ID_MPEG4;
3440     video = TRUE;
3441   } else if (!strcmp (mimetype, "video/x-xvid")) {
3442     id = CODEC_ID_MPEG4;
3443     video = TRUE;
3444   } else if (!strcmp (mimetype, "video/x-ffv")) {
3445     gint ffvversion = 0;
3446
3447     if (gst_structure_get_int (structure, "ffvversion", &ffvversion) &&
3448         ffvversion == 1) {
3449       id = CODEC_ID_FFV1;
3450       video = TRUE;
3451     }
3452   } else if (!strcmp (mimetype, "audio/x-adpcm")) {
3453     const gchar *layout;
3454
3455     layout = gst_structure_get_string (structure, "layout");
3456     if (layout == NULL) {
3457       /* break */
3458     } else if (!strcmp (layout, "quicktime")) {
3459       id = CODEC_ID_ADPCM_IMA_QT;
3460     } else if (!strcmp (layout, "microsoft")) {
3461       id = CODEC_ID_ADPCM_MS;
3462     } else if (!strcmp (layout, "dvi")) {
3463       id = CODEC_ID_ADPCM_IMA_WAV;
3464     } else if (!strcmp (layout, "4xm")) {
3465       id = CODEC_ID_ADPCM_4XM;
3466     } else if (!strcmp (layout, "smjpeg")) {
3467       id = CODEC_ID_ADPCM_IMA_SMJPEG;
3468     } else if (!strcmp (layout, "dk3")) {
3469       id = CODEC_ID_ADPCM_IMA_DK3;
3470     } else if (!strcmp (layout, "dk4")) {
3471       id = CODEC_ID_ADPCM_IMA_DK4;
3472     } else if (!strcmp (layout, "westwood")) {
3473       id = CODEC_ID_ADPCM_IMA_WS;
3474     } else if (!strcmp (layout, "iss")) {
3475       id = CODEC_ID_ADPCM_IMA_ISS;
3476     } else if (!strcmp (layout, "xa")) {
3477       id = CODEC_ID_ADPCM_XA;
3478     } else if (!strcmp (layout, "adx")) {
3479       id = CODEC_ID_ADPCM_ADX;
3480     } else if (!strcmp (layout, "ea")) {
3481       id = CODEC_ID_ADPCM_EA;
3482     } else if (!strcmp (layout, "g726")) {
3483       id = CODEC_ID_ADPCM_G726;
3484     } else if (!strcmp (layout, "g721")) {
3485       id = CODEC_ID_ADPCM_G726;
3486     } else if (!strcmp (layout, "ct")) {
3487       id = CODEC_ID_ADPCM_CT;
3488     } else if (!strcmp (layout, "swf")) {
3489       id = CODEC_ID_ADPCM_SWF;
3490     } else if (!strcmp (layout, "yamaha")) {
3491       id = CODEC_ID_ADPCM_YAMAHA;
3492     } else if (!strcmp (layout, "sbpro2")) {
3493       id = CODEC_ID_ADPCM_SBPRO_2;
3494     } else if (!strcmp (layout, "sbpro3")) {
3495       id = CODEC_ID_ADPCM_SBPRO_3;
3496     } else if (!strcmp (layout, "sbpro4")) {
3497       id = CODEC_ID_ADPCM_SBPRO_4;
3498     }
3499     if (id != CODEC_ID_NONE)
3500       audio = TRUE;
3501   } else if (!strcmp (mimetype, "video/x-4xm")) {
3502     id = CODEC_ID_4XM;
3503     video = TRUE;
3504   } else if (!strcmp (mimetype, "audio/x-dpcm")) {
3505     const gchar *layout;
3506
3507     layout = gst_structure_get_string (structure, "layout");
3508     if (!layout) {
3509       /* .. */
3510     } else if (!strcmp (layout, "roq")) {
3511       id = CODEC_ID_ROQ_DPCM;
3512     } else if (!strcmp (layout, "interplay")) {
3513       id = CODEC_ID_INTERPLAY_DPCM;
3514     } else if (!strcmp (layout, "xan")) {
3515       id = CODEC_ID_XAN_DPCM;
3516     } else if (!strcmp (layout, "sol")) {
3517       id = CODEC_ID_SOL_DPCM;
3518     }
3519     if (id != CODEC_ID_NONE)
3520       audio = TRUE;
3521   } else if (!strcmp (mimetype, "audio/x-flac")) {
3522     id = CODEC_ID_FLAC;
3523     audio = TRUE;
3524   } else if (!strcmp (mimetype, "audio/x-shorten")) {
3525     id = CODEC_ID_SHORTEN;
3526     audio = TRUE;
3527   } else if (!strcmp (mimetype, "audio/x-alac")) {
3528     id = CODEC_ID_ALAC;
3529     audio = TRUE;
3530   } else if (!strcmp (mimetype, "video/x-cinepak")) {
3531     id = CODEC_ID_CINEPAK;
3532     video = TRUE;
3533   } else if (!strcmp (mimetype, "video/x-pn-realvideo")) {
3534     gint rmversion;
3535
3536     if (gst_structure_get_int (structure, "rmversion", &rmversion)) {
3537       switch (rmversion) {
3538         case 1:
3539           id = CODEC_ID_RV10;
3540           break;
3541         case 2:
3542           id = CODEC_ID_RV20;
3543           break;
3544         case 3:
3545           id = CODEC_ID_RV30;
3546           break;
3547         case 4:
3548           id = CODEC_ID_RV40;
3549           break;
3550       }
3551     }
3552     if (id != CODEC_ID_NONE)
3553       video = TRUE;
3554   } else if (!strcmp (mimetype, "audio/x-sipro")) {
3555     id = CODEC_ID_SIPR;
3556     audio = TRUE;
3557   } else if (!strcmp (mimetype, "audio/x-pn-realaudio")) {
3558     gint raversion;
3559
3560     if (gst_structure_get_int (structure, "raversion", &raversion)) {
3561       switch (raversion) {
3562         case 1:
3563           id = CODEC_ID_RA_144;
3564           break;
3565         case 2:
3566           id = CODEC_ID_RA_288;
3567           break;
3568         case 8:
3569           id = CODEC_ID_COOK;
3570           break;
3571       }
3572     }
3573     if (id != CODEC_ID_NONE)
3574       audio = TRUE;
3575   } else if (!strcmp (mimetype, "video/x-rle")) {
3576     const gchar *layout;
3577
3578     if ((layout = gst_structure_get_string (structure, "layout"))) {
3579       if (!strcmp (layout, "microsoft")) {
3580         id = CODEC_ID_MSRLE;
3581         video = TRUE;
3582       }
3583     }
3584   } else if (!strcmp (mimetype, "video/x-xan")) {
3585     gint wcversion = 0;
3586
3587     if ((gst_structure_get_int (structure, "wcversion", &wcversion))) {
3588       switch (wcversion) {
3589         case 3:
3590           id = CODEC_ID_XAN_WC3;
3591           video = TRUE;
3592           break;
3593         case 4:
3594           id = CODEC_ID_XAN_WC4;
3595           video = TRUE;
3596           break;
3597         default:
3598           break;
3599       }
3600     }
3601   } else if (!strcmp (mimetype, "audio/AMR")) {
3602     audio = TRUE;
3603     id = CODEC_ID_AMR_NB;
3604   } else if (!strcmp (mimetype, "audio/AMR-WB")) {
3605     id = CODEC_ID_AMR_WB;
3606     audio = TRUE;
3607   } else if (!strcmp (mimetype, "audio/qcelp")) {
3608     id = CODEC_ID_QCELP;
3609     audio = TRUE;
3610   } else if (!strcmp (mimetype, "video/x-h264")) {
3611     id = CODEC_ID_H264;
3612     video = TRUE;
3613   } else if (!strcmp (mimetype, "video/x-flash-video")) {
3614     gint flvversion = 0;
3615
3616     if ((gst_structure_get_int (structure, "flvversion", &flvversion))) {
3617       switch (flvversion) {
3618         case 1:
3619           id = CODEC_ID_FLV1;
3620           video = TRUE;
3621           break;
3622         default:
3623           break;
3624       }
3625     }
3626
3627   } else if (!strcmp (mimetype, "audio/x-nellymoser")) {
3628     id = CODEC_ID_NELLYMOSER;
3629     audio = TRUE;
3630   } else if (!strncmp (mimetype, "audio/x-gst-av-", 15)) {
3631     gchar ext[16];
3632     AVCodec *codec;
3633
3634     if (strlen (mimetype) <= 30 &&
3635         sscanf (mimetype, "audio/x-gst-av-%s", ext) == 1) {
3636       if ((codec = avcodec_find_decoder_by_name (ext)) ||
3637           (codec = avcodec_find_encoder_by_name (ext))) {
3638         id = codec->id;
3639         audio = TRUE;
3640       }
3641     }
3642   } else if (!strncmp (mimetype, "video/x-gst-av-", 15)) {
3643     gchar ext[16];
3644     AVCodec *codec;
3645
3646     if (strlen (mimetype) <= 30 &&
3647         sscanf (mimetype, "video/x-gst-av-%s", ext) == 1) {
3648       if ((codec = avcodec_find_decoder_by_name (ext)) ||
3649           (codec = avcodec_find_encoder_by_name (ext))) {
3650         id = codec->id;
3651         video = TRUE;
3652       }
3653     }
3654   }
3655
3656   if (context != NULL) {
3657     if (video == TRUE) {
3658       context->codec_type = AVMEDIA_TYPE_VIDEO;
3659     } else if (audio == TRUE) {
3660       context->codec_type = AVMEDIA_TYPE_AUDIO;
3661     } else {
3662       context->codec_type = AVMEDIA_TYPE_UNKNOWN;
3663     }
3664     context->codec_id = id;
3665     gst_ffmpeg_caps_with_codecid (id, context->codec_type, caps, context);
3666   }
3667
3668   if (id != CODEC_ID_NONE) {
3669     GST_DEBUG ("The id=%d belongs to the caps %" GST_PTR_FORMAT, id, caps);
3670   } else {
3671     GST_WARNING ("Couldn't figure out the id for caps %" GST_PTR_FORMAT, caps);
3672   }
3673
3674   return id;
3675 }