New upstream development release
[pkg-gstreamer/gst-libav1.0.git] / debian / patches / 03_git-2012-12-18.patch
1 Index: gst-libav1.0/ext/libav/Makefile.am
2 ===================================================================
3 --- gst-libav1.0.orig/ext/libav/Makefile.am     2012-09-14 12:09:56.000000000 +0200
4 +++ gst-libav1.0/ext/libav/Makefile.am  2012-12-18 11:40:28.506169306 +0100
5 @@ -10,9 +10,9 @@
6                           gstavprotocol.c       \
7                           gstavcodecmap.c       \
8                           gstavutils.c  \
9 -                         gstavenc.c    \
10 +                         gstavaudenc.c \
11                           gstavvidenc.c \
12 -                         gstavdec.c    \
13 +                         gstavauddec.c \
14                           gstavviddec.c \
15                           gstavcfg.c    \
16                           gstavdemux.c  \
17 @@ -40,7 +40,9 @@
18         gstav.h \
19         gstavcodecmap.h \
20         gstavutils.h \
21 -       gstavenc.h \
22 +       gstavauddec.h \
23 +       gstavviddec.h \
24 +       gstavaudenc.h \
25         gstavvidenc.h \
26         gstavcfg.h \
27         gstavpipe.h
28 Index: gst-libav1.0/ext/libav/gstav.c
29 ===================================================================
30 --- gst-libav1.0.orig/ext/libav/gstav.c 2012-12-18 11:37:41.518172475 +0100
31 +++ gst-libav1.0/ext/libav/gstav.c      2012-12-18 11:40:28.506169306 +0100
32 @@ -13,8 +13,8 @@
33   *
34   * You should have received a copy of the GNU Library General Public
35   * License along with this library; if not, write to the
36 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
37 - * Boston, MA 02111-1307, USA.
38 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
39 + * Boston, MA 02110-1301, USA.
40   */
41  
42  /* First, include the header file for the plugin, to bring in the
43 @@ -45,7 +45,7 @@
44    int ret;
45  
46    g_static_mutex_lock (&gst_avcodec_mutex);
47 -  ret = avcodec_open (avctx, codec);
48 +  ret = avcodec_open2 (avctx, codec, NULL);
49    g_static_mutex_unlock (&gst_avcodec_mutex);
50  
51    return ret;
52 @@ -69,7 +69,7 @@
53    int ret;
54  
55    g_static_mutex_lock (&gst_avcodec_mutex);
56 -  ret = av_find_stream_info (ic);
57 +  ret = avformat_find_stream_info (ic, NULL);
58    g_static_mutex_unlock (&gst_avcodec_mutex);
59  
60    return ret;
61 @@ -156,9 +156,6 @@
62    gst_ffmpegaudioresample_register (plugin);
63  #endif
64  
65 -  av_register_protocol2 (&gstreamer_protocol, sizeof (URLProtocol));
66 -  av_register_protocol2 (&gstpipe_protocol, sizeof (URLProtocol));
67 -
68    /* Now we can return the pointer to the newly created Plugin object. */
69    return TRUE;
70  }
71 Index: gst-libav1.0/ext/libav/gstav.h
72 ===================================================================
73 --- gst-libav1.0.orig/ext/libav/gstav.h 2012-09-14 12:09:56.000000000 +0200
74 +++ gst-libav1.0/ext/libav/gstav.h      2012-12-18 11:40:28.506169306 +0100
75 @@ -13,8 +13,8 @@
76   *
77   * You should have received a copy of the GNU Library General Public
78   * License along with this library; if not, write to the
79 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
80 - * Boston, MA 02111-1307, USA.
81 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
82 + * Boston, MA 02110-1301, USA.
83   */
84  
85  /* First, include the header file for the plugin, to bring in the
86 @@ -28,6 +28,8 @@
87  #include <libavformat/avformat.h>
88  
89  #include <gst/gst.h>
90 +#include <gst/audio/audio.h>
91 +#include <gst/video/video.h>
92  
93  GST_DEBUG_CATEGORY_EXTERN (ffmpeg_debug);
94  #define GST_CAT_DEFAULT ffmpeg_debug
95 @@ -55,10 +57,13 @@
96  int gst_ffmpeg_avcodec_close (AVCodecContext *avctx);
97  int gst_ffmpeg_av_find_stream_info(AVFormatContext *ic);
98  
99 -G_END_DECLS
100 +int gst_ffmpegdata_open (GstPad * pad, int flags, AVIOContext ** context);
101 +int gst_ffmpegdata_close (AVIOContext * h);
102 +typedef struct _GstFFMpegPipe GstFFMpegPipe;
103 +int gst_ffmpeg_pipe_open (GstFFMpegPipe *ffpipe, int flags, AVIOContext ** context);
104 +int gst_ffmpeg_pipe_close (AVIOContext * h);
105  
106 -extern URLProtocol gstreamer_protocol;
107 -extern URLProtocol gstpipe_protocol;
108 +G_END_DECLS
109  
110  /* use GST_FFMPEG URL_STREAMHEADER with URL_WRONLY if the first
111   * buffer should be used as streamheader property on the pad's caps. */
112 Index: gst-libav1.0/ext/libav/gstavauddec.c
113 ===================================================================
114 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
115 +++ gst-libav1.0/ext/libav/gstavauddec.c        2012-12-18 11:40:28.506169306 +0100
116 @@ -0,0 +1,887 @@
117 +/* GStreamer
118 + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
119 + * Copyright (C) <2012> Collabora Ltd.
120 + *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
121 + *
122 + * This library is free software; you can redistribute it and/or
123 + * modify it under the terms of the GNU Library General Public
124 + * License as published by the Free Software Foundation; either
125 + * version 2 of the License, or (at your option) any later version.
126 + *
127 + * This library is distributed in the hope that it will be useful,
128 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
129 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
130 + * Library General Public License for more details.
131 + *
132 + * You should have received a copy of the GNU Library General Public
133 + * License along with this library; if not, write to the
134 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
135 + * Boston, MA 02110-1301, USA.
136 + */
137 +
138 +#ifdef HAVE_CONFIG_H
139 +#include "config.h"
140 +#endif
141 +
142 +#include <assert.h>
143 +#include <string.h>
144 +
145 +#include <libavcodec/avcodec.h>
146 +
147 +#include <gst/gst.h>
148 +
149 +#include "gstav.h"
150 +#include "gstavcodecmap.h"
151 +#include "gstavutils.h"
152 +#include "gstavauddec.h"
153 +
154 +GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
155 +
156 +/* A number of function prototypes are given so we can refer to them later. */
157 +static void gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass);
158 +static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
159 +static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
160 +static void gst_ffmpegauddec_finalize (GObject * object);
161 +
162 +static gboolean gst_ffmpegauddec_stop (GstAudioDecoder * decoder);
163 +static void gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard);
164 +static gboolean gst_ffmpegauddec_set_format (GstAudioDecoder * decoder,
165 +    GstCaps * caps);
166 +static GstFlowReturn gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder,
167 +    GstBuffer * inbuf);
168 +
169 +static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
170 +    gboolean force);
171 +
172 +static void gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
173 +
174 +#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
175 +
176 +static GstElementClass *parent_class = NULL;
177 +
178 +static void
179 +gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass)
180 +{
181 +  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
182 +  GstPadTemplate *sinktempl, *srctempl;
183 +  GstCaps *sinkcaps, *srccaps;
184 +  AVCodec *in_plugin;
185 +  gchar *longname, *description;
186 +
187 +  in_plugin =
188 +      (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
189 +      GST_FFDEC_PARAMS_QDATA);
190 +  g_assert (in_plugin != NULL);
191 +
192 +  /* construct the element details struct */
193 +  longname = g_strdup_printf ("libav %s decoder", in_plugin->long_name);
194 +  description = g_strdup_printf ("libav %s decoder", in_plugin->name);
195 +  gst_element_class_set_metadata (element_class, longname,
196 +      "Codec/Decoder/Audio", description,
197 +      "Wim Taymans <wim.taymans@gmail.com>, "
198 +      "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
199 +      "Edward Hervey <bilboed@bilboed.com>");
200 +  g_free (longname);
201 +  g_free (description);
202 +
203 +  /* get the caps */
204 +  sinkcaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, FALSE);
205 +  if (!sinkcaps) {
206 +    GST_DEBUG ("Couldn't get sink caps for decoder '%s'", in_plugin->name);
207 +    sinkcaps = gst_caps_from_string ("unknown/unknown");
208 +  }
209 +  srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
210 +      in_plugin->id, FALSE, in_plugin);
211 +  if (!srccaps) {
212 +    GST_DEBUG ("Couldn't get source caps for decoder '%s'", in_plugin->name);
213 +    srccaps = gst_caps_from_string ("audio/x-raw");
214 +  }
215 +
216 +  /* pad templates */
217 +  sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
218 +      GST_PAD_ALWAYS, sinkcaps);
219 +  srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
220 +
221 +  gst_element_class_add_pad_template (element_class, srctempl);
222 +  gst_element_class_add_pad_template (element_class, sinktempl);
223 +
224 +  klass->in_plugin = in_plugin;
225 +  klass->srctempl = srctempl;
226 +  klass->sinktempl = sinktempl;
227 +}
228 +
229 +static void
230 +gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
231 +{
232 +  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
233 +  GstAudioDecoderClass *gstaudiodecoder_class = GST_AUDIO_DECODER_CLASS (klass);
234 +
235 +  parent_class = g_type_class_peek_parent (klass);
236 +
237 +  gobject_class->finalize = gst_ffmpegauddec_finalize;
238 +
239 +  gstaudiodecoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_stop);
240 +  gstaudiodecoder_class->set_format =
241 +      GST_DEBUG_FUNCPTR (gst_ffmpegauddec_set_format);
242 +  gstaudiodecoder_class->handle_frame =
243 +      GST_DEBUG_FUNCPTR (gst_ffmpegauddec_handle_frame);
244 +  gstaudiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_flush);
245 +}
246 +
247 +static void
248 +gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
249 +{
250 +  GstFFMpegAudDecClass *klass =
251 +      (GstFFMpegAudDecClass *) G_OBJECT_GET_CLASS (ffmpegdec);
252 +
253 +  /* some ffmpeg data */
254 +  ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
255 +  ffmpegdec->opened = FALSE;
256 +
257 +  gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (ffmpegdec), TRUE);
258 +  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (ffmpegdec), TRUE);
259 +}
260 +
261 +static void
262 +gst_ffmpegauddec_finalize (GObject * object)
263 +{
264 +  GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) object;
265 +
266 +  if (ffmpegdec->context != NULL)
267 +    av_free (ffmpegdec->context);
268 +  ffmpegdec->context = NULL;
269 +
270 +  G_OBJECT_CLASS (parent_class)->finalize (object);
271 +}
272 +
273 +/* With LOCK */
274 +static void
275 +gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec)
276 +{
277 +  GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
278 +
279 +  gst_caps_replace (&ffmpegdec->last_caps, NULL);
280 +  gst_buffer_replace (&ffmpegdec->outbuf, NULL);
281 +
282 +  gst_ffmpeg_avcodec_close (ffmpegdec->context);
283 +  ffmpegdec->opened = FALSE;
284 +
285 +  if (ffmpegdec->context->extradata) {
286 +    av_free (ffmpegdec->context->extradata);
287 +    ffmpegdec->context->extradata = NULL;
288 +  }
289 +}
290 +
291 +static gboolean
292 +gst_ffmpegauddec_stop (GstAudioDecoder * decoder)
293 +{
294 +  GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
295 +
296 +  GST_OBJECT_LOCK (ffmpegdec);
297 +  gst_ffmpegauddec_close (ffmpegdec);
298 +  GST_OBJECT_UNLOCK (ffmpegdec);
299 +  gst_audio_info_init (&ffmpegdec->info);
300 +  gst_caps_replace (&ffmpegdec->last_caps, NULL);
301 +
302 +  return TRUE;
303 +}
304 +
305 +/* with LOCK */
306 +static gboolean
307 +gst_ffmpegauddec_open (GstFFMpegAudDec * ffmpegdec)
308 +{
309 +  GstFFMpegAudDecClass *oclass;
310 +
311 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
312 +
313 +  if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
314 +    goto could_not_open;
315 +
316 +  ffmpegdec->opened = TRUE;
317 +
318 +  GST_LOG_OBJECT (ffmpegdec, "Opened libav codec %s, id %d",
319 +      oclass->in_plugin->name, oclass->in_plugin->id);
320 +
321 +  gst_audio_info_init (&ffmpegdec->info);
322 +
323 +  return TRUE;
324 +
325 +  /* ERRORS */
326 +could_not_open:
327 +  {
328 +    gst_ffmpegauddec_close (ffmpegdec);
329 +    GST_DEBUG_OBJECT (ffmpegdec, "avdec_%s: Failed to open libav codec",
330 +        oclass->in_plugin->name);
331 +    return FALSE;
332 +  }
333 +}
334 +
335 +typedef struct
336 +{
337 +  GstBuffer *buffer;
338 +  GstMapInfo map;
339 +} BufferInfo;
340 +
341 +/* called when ffmpeg wants us to allocate a buffer to write the decoded frame
342 + * into. We try to give it memory from our pool */
343 +static int
344 +gst_ffmpegauddec_get_buffer (AVCodecContext * context, AVFrame * frame)
345 +{
346 +  GstFFMpegAudDec *ffmpegdec;
347 +  GstAudioInfo *info;
348 +  BufferInfo *buffer_info;
349 +
350 +  ffmpegdec = (GstFFMpegAudDec *) context->opaque;
351 +  if (G_UNLIKELY (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)))
352 +    goto negotiate_failed;
353 +
354 +  /* Always use the default allocator for planar audio formats because
355 +   * we will have to copy and deinterleave later anyway */
356 +  if (av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt))
357 +    goto fallback;
358 +
359 +  info = gst_audio_decoder_get_audio_info (GST_AUDIO_DECODER (ffmpegdec));
360 +
361 +  buffer_info = g_slice_new (BufferInfo);
362 +  buffer_info->buffer =
363 +      gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (ffmpegdec),
364 +      frame->nb_samples * info->bpf);
365 +  gst_buffer_map (buffer_info->buffer, &buffer_info->map, GST_MAP_WRITE);
366 +  frame->opaque = buffer_info;
367 +  frame->data[0] = buffer_info->map.data;
368 +  frame->extended_data = frame->data;
369 +  frame->linesize[0] = buffer_info->map.size;
370 +  frame->type = FF_BUFFER_TYPE_USER;
371 +
372 +  return 0;
373 +  /* fallbacks */
374 +negotiate_failed:
375 +  {
376 +    GST_DEBUG_OBJECT (ffmpegdec, "negotiate failed");
377 +    goto fallback;
378 +  }
379 +fallback:
380 +  {
381 +    return avcodec_default_get_buffer (context, frame);
382 +  }
383 +}
384 +
385 +static gboolean
386 +gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
387 +{
388 +  GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
389 +  GstFFMpegAudDecClass *oclass;
390 +  gboolean ret = TRUE;
391 +
392 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
393 +
394 +  GST_DEBUG_OBJECT (ffmpegdec, "setcaps called");
395 +
396 +  GST_OBJECT_LOCK (ffmpegdec);
397 +
398 +  if (ffmpegdec->last_caps && gst_caps_is_equal (ffmpegdec->last_caps, caps)) {
399 +    GST_DEBUG_OBJECT (ffmpegdec, "same caps");
400 +    GST_OBJECT_UNLOCK (ffmpegdec);
401 +    return TRUE;
402 +  }
403 +
404 +  gst_caps_replace (&ffmpegdec->last_caps, caps);
405 +
406 +  /* close old session */
407 +  if (ffmpegdec->opened) {
408 +    GST_OBJECT_UNLOCK (ffmpegdec);
409 +    gst_ffmpegauddec_drain (ffmpegdec);
410 +    GST_OBJECT_LOCK (ffmpegdec);
411 +    gst_ffmpegauddec_close (ffmpegdec);
412 +  }
413 +
414 +  /* get size and so */
415 +  gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
416 +      oclass->in_plugin->type, caps, ffmpegdec->context);
417 +
418 +  /* workaround encoder bugs */
419 +  ffmpegdec->context->workaround_bugs |= FF_BUG_AUTODETECT;
420 +  ffmpegdec->context->err_recognition = 1;
421 +
422 +  ffmpegdec->context->opaque = ffmpegdec;
423 +  ffmpegdec->context->get_buffer = gst_ffmpegauddec_get_buffer;
424 +  ffmpegdec->context->reget_buffer = NULL;
425 +  ffmpegdec->context->release_buffer = NULL;
426 +
427 +  /* open codec - we don't select an output pix_fmt yet,
428 +   * simply because we don't know! We only get it
429 +   * during playback... */
430 +  if (!gst_ffmpegauddec_open (ffmpegdec))
431 +    goto open_failed;
432 +
433 +done:
434 +  GST_OBJECT_UNLOCK (ffmpegdec);
435 +
436 +  return ret;
437 +
438 +  /* ERRORS */
439 +open_failed:
440 +  {
441 +    GST_DEBUG_OBJECT (ffmpegdec, "Failed to open");
442 +    ret = FALSE;
443 +    goto done;
444 +  }
445 +}
446 +
447 +static gboolean
448 +gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec, gboolean force)
449 +{
450 +  GstFFMpegAudDecClass *oclass;
451 +  gint depth;
452 +  GstAudioFormat format;
453 +  GstAudioChannelPosition pos[64] = { 0, };
454 +
455 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
456 +
457 +  depth = av_smp_format_depth (ffmpegdec->context->sample_fmt) * 8;
458 +  format = gst_ffmpeg_smpfmt_to_audioformat (ffmpegdec->context->sample_fmt);
459 +  if (format == GST_AUDIO_FORMAT_UNKNOWN)
460 +    goto no_caps;
461 +
462 +  if (!force && ffmpegdec->info.rate ==
463 +      ffmpegdec->context->sample_rate &&
464 +      ffmpegdec->info.channels == ffmpegdec->context->channels &&
465 +      ffmpegdec->info.finfo->depth == depth)
466 +    return TRUE;
467 +
468 +  GST_DEBUG_OBJECT (ffmpegdec,
469 +      "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)",
470 +      ffmpegdec->info.rate, ffmpegdec->info.channels,
471 +      ffmpegdec->info.finfo->depth,
472 +      ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
473 +
474 +  gst_ffmpeg_channel_layout_to_gst (ffmpegdec->context->channel_layout,
475 +      ffmpegdec->context->channels, pos);
476 +  memcpy (ffmpegdec->ffmpeg_layout, pos,
477 +      sizeof (GstAudioChannelPosition) * ffmpegdec->context->channels);
478 +
479 +  /* Get GStreamer channel layout */
480 +  gst_audio_channel_positions_to_valid_order (pos,
481 +      ffmpegdec->context->channels);
482 +  ffmpegdec->needs_reorder =
483 +      memcmp (pos, ffmpegdec->ffmpeg_layout,
484 +      sizeof (pos[0]) * ffmpegdec->context->channels) != 0;
485 +  gst_audio_info_set_format (&ffmpegdec->info, format,
486 +      ffmpegdec->context->sample_rate, ffmpegdec->context->channels, pos);
487 +
488 +  if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (ffmpegdec),
489 +          &ffmpegdec->info))
490 +    goto caps_failed;
491 +
492 +  return TRUE;
493 +
494 +  /* ERRORS */
495 +no_caps:
496 +  {
497 +#ifdef HAVE_LIBAV_UNINSTALLED
498 +    /* using internal ffmpeg snapshot */
499 +    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
500 +        ("Could not find GStreamer caps mapping for libav codec '%s'.",
501 +            oclass->in_plugin->name), (NULL));
502 +#else
503 +    /* using external ffmpeg */
504 +    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION,
505 +        ("Could not find GStreamer caps mapping for libav codec '%s', and "
506 +            "you are using an external libavcodec. This is most likely due to "
507 +            "a packaging problem and/or libavcodec having been upgraded to a "
508 +            "version that is not compatible with this version of "
509 +            "gstreamer-libav. Make sure your gstreamer-libav and libavcodec "
510 +            "packages come from the same source/repository.",
511 +            oclass->in_plugin->name), (NULL));
512 +#endif
513 +    return FALSE;
514 +  }
515 +caps_failed:
516 +  {
517 +    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
518 +        ("Could not set caps for libav decoder (%s), not fixed?",
519 +            oclass->in_plugin->name));
520 +
521 +    return FALSE;
522 +  }
523 +}
524 +
525 +static void
526 +gst_avpacket_init (AVPacket * packet, guint8 * data, guint size)
527 +{
528 +  memset (packet, 0, sizeof (AVPacket));
529 +  packet->data = data;
530 +  packet->size = size;
531 +}
532 +
533 +static gint
534 +gst_ffmpegauddec_audio_frame (GstFFMpegAudDec * ffmpegdec,
535 +    AVCodec * in_plugin, guint8 * data, guint size,
536 +    GstBuffer ** outbuf, GstFlowReturn * ret)
537 +{
538 +  gint len = -1;
539 +  gint have_data = AVCODEC_MAX_AUDIO_FRAME_SIZE;
540 +  AVPacket packet;
541 +  AVFrame frame;
542 +
543 +  GST_DEBUG_OBJECT (ffmpegdec, "size: %d", size);
544 +
545 +  gst_avpacket_init (&packet, data, size);
546 +  memset (&frame, 0, sizeof (frame));
547 +  avcodec_get_frame_defaults (&frame);
548 +  len = avcodec_decode_audio4 (ffmpegdec->context, &frame, &have_data, &packet);
549 +
550 +  GST_DEBUG_OBJECT (ffmpegdec,
551 +      "Decode audio: len=%d, have_data=%d", len, have_data);
552 +
553 +  if (len >= 0 && have_data > 0) {
554 +    BufferInfo *buffer_info = frame.opaque;
555 +
556 +    if (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)) {
557 +      *outbuf = NULL;
558 +      *ret = GST_FLOW_NOT_NEGOTIATED;
559 +      len = -1;
560 +      goto beach;
561 +    }
562 +
563 +    GST_DEBUG_OBJECT (ffmpegdec, "Creating output buffer");
564 +    if (buffer_info) {
565 +      *outbuf = buffer_info->buffer;
566 +      gst_buffer_unmap (buffer_info->buffer, &buffer_info->map);
567 +      g_slice_free (BufferInfo, buffer_info);
568 +      frame.opaque = NULL;
569 +    } else if (av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt)
570 +        && ffmpegdec->info.channels > 1) {
571 +      gint i, j;
572 +      gint nsamples, channels;
573 +      GstMapInfo minfo;
574 +
575 +      channels = ffmpegdec->info.channels;
576 +
577 +      *outbuf =
578 +          gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER
579 +          (ffmpegdec), frame.linesize[0] * channels);
580 +
581 +      gst_buffer_map (*outbuf, &minfo, GST_MAP_WRITE);
582 +
583 +      nsamples = frame.nb_samples;
584 +      switch (ffmpegdec->info.finfo->width) {
585 +        case 8:{
586 +          guint8 *odata = minfo.data;
587 +
588 +          for (i = 0; i < nsamples; i++) {
589 +            for (j = 0; j < channels; j++) {
590 +              odata[j] = ((const guint8 *) frame.extended_data[j])[i];
591 +            }
592 +            odata += channels;
593 +          }
594 +          break;
595 +        }
596 +        case 16:{
597 +          guint16 *odata = (guint16 *) minfo.data;
598 +
599 +          for (i = 0; i < nsamples; i++) {
600 +            for (j = 0; j < channels; j++) {
601 +              odata[j] = ((const guint16 *) frame.extended_data[j])[i];
602 +            }
603 +            odata += channels;
604 +          }
605 +          break;
606 +        }
607 +        case 32:{
608 +          guint32 *odata = (guint32 *) minfo.data;
609 +
610 +          for (i = 0; i < nsamples; i++) {
611 +            for (j = 0; j < channels; j++) {
612 +              odata[j] = ((const guint32 *) frame.extended_data[j])[i];
613 +            }
614 +            odata += channels;
615 +          }
616 +          break;
617 +        }
618 +        case 64:{
619 +          guint64 *odata = (guint64 *) minfo.data;
620 +
621 +          for (i = 0; i < nsamples; i++) {
622 +            for (j = 0; j < channels; j++) {
623 +              odata[j] = ((const guint64 *) frame.extended_data[j])[i];
624 +            }
625 +            odata += channels;
626 +          }
627 +          break;
628 +        }
629 +        default:
630 +          g_assert_not_reached ();
631 +          break;
632 +      }
633 +      gst_buffer_unmap (*outbuf, &minfo);
634 +    } else {
635 +      *outbuf =
636 +          gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER
637 +          (ffmpegdec), frame.linesize[0]);
638 +      gst_buffer_fill (*outbuf, 0, frame.data[0], frame.linesize[0]);
639 +    }
640 +
641 +    GST_DEBUG_OBJECT (ffmpegdec, "Buffer created. Size: %d", have_data);
642 +
643 +    /* Reorder channels to the GStreamer channel order */
644 +    if (ffmpegdec->needs_reorder) {
645 +      *outbuf = gst_buffer_make_writable (*outbuf);
646 +      gst_audio_buffer_reorder_channels (*outbuf, ffmpegdec->info.finfo->format,
647 +          ffmpegdec->info.channels, ffmpegdec->ffmpeg_layout,
648 +          ffmpegdec->info.position);
649 +    }
650 +  } else {
651 +    *outbuf = NULL;
652 +  }
653 +
654 +beach:
655 +  GST_DEBUG_OBJECT (ffmpegdec, "return flow %d, out %p, len %d",
656 +      *ret, *outbuf, len);
657 +  return len;
658 +}
659 +
660 +/* gst_ffmpegauddec_frame:
661 + * ffmpegdec:
662 + * data: pointer to the data to decode
663 + * size: size of data in bytes
664 + * got_data: 0 if no data was decoded, != 0 otherwise.
665 + * in_time: timestamp of data
666 + * in_duration: duration of data
667 + * ret: GstFlowReturn to return in the chain function
668 + *
669 + * Decode the given frame and pushes it downstream.
670 + *
671 + * Returns: Number of bytes used in decoding, -1 on error/failure.
672 + */
673 +
674 +static gint
675 +gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec,
676 +    guint8 * data, guint size, gint * got_data, GstFlowReturn * ret)
677 +{
678 +  GstFFMpegAudDecClass *oclass;
679 +  GstBuffer *outbuf = NULL;
680 +  gint have_data = 0, len = 0;
681 +
682 +  if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
683 +    goto no_codec;
684 +
685 +  GST_LOG_OBJECT (ffmpegdec, "data:%p, size:%d", data, size);
686 +
687 +  *ret = GST_FLOW_OK;
688 +  ffmpegdec->context->frame_number++;
689 +
690 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
691 +
692 +  len =
693 +      gst_ffmpegauddec_audio_frame (ffmpegdec, oclass->in_plugin, data, size,
694 +      &outbuf, ret);
695 +
696 +  if (outbuf)
697 +    have_data = 1;
698 +
699 +  if (len < 0 || have_data < 0) {
700 +    GST_WARNING_OBJECT (ffmpegdec,
701 +        "avdec_%s: decoding error (len: %d, have_data: %d)",
702 +        oclass->in_plugin->name, len, have_data);
703 +    *got_data = 0;
704 +    goto beach;
705 +  } else if (len == 0 && have_data == 0) {
706 +    *got_data = 0;
707 +    goto beach;
708 +  } else {
709 +    /* this is where I lost my last clue on ffmpeg... */
710 +    *got_data = 1;
711 +  }
712 +
713 +  if (outbuf) {
714 +    GST_LOG_OBJECT (ffmpegdec, "Decoded data, now storing buffer %p", outbuf);
715 +
716 +    if (ffmpegdec->outbuf)
717 +      ffmpegdec->outbuf = gst_buffer_append (ffmpegdec->outbuf, outbuf);
718 +    else
719 +      ffmpegdec->outbuf = outbuf;
720 +  } else {
721 +    GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
722 +  }
723 +
724 +beach:
725 +  return len;
726 +
727 +  /* ERRORS */
728 +no_codec:
729 +  {
730 +    GST_ERROR_OBJECT (ffmpegdec, "no codec context");
731 +    return -1;
732 +  }
733 +}
734 +
735 +static void
736 +gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
737 +{
738 +  GstFFMpegAudDecClass *oclass;
739 +
740 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
741 +
742 +  if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
743 +    gint have_data, len, try = 0;
744 +
745 +    GST_LOG_OBJECT (ffmpegdec,
746 +        "codec has delay capabilities, calling until libav has drained everything");
747 +
748 +    do {
749 +      GstFlowReturn ret;
750 +
751 +      len = gst_ffmpegauddec_frame (ffmpegdec, NULL, 0, &have_data, &ret);
752 +      if (len < 0 || have_data == 0)
753 +        break;
754 +    } while (try++ < 10);
755 +  }
756 +
757 +  if (ffmpegdec->outbuf)
758 +    gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec),
759 +        ffmpegdec->outbuf, 1);
760 +  ffmpegdec->outbuf = NULL;
761 +}
762 +
763 +static void
764 +gst_ffmpegauddec_flush (GstAudioDecoder * decoder, gboolean hard)
765 +{
766 +  GstFFMpegAudDec *ffmpegdec = (GstFFMpegAudDec *) decoder;
767 +
768 +  if (ffmpegdec->opened) {
769 +    avcodec_flush_buffers (ffmpegdec->context);
770 +  }
771 +}
772 +
773 +static GstFlowReturn
774 +gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
775 +{
776 +  GstFFMpegAudDec *ffmpegdec;
777 +  GstFFMpegAudDecClass *oclass;
778 +  guint8 *data, *bdata;
779 +  GstMapInfo map;
780 +  gint size, bsize, len, have_data;
781 +  GstFlowReturn ret = GST_FLOW_OK;
782 +
783 +  ffmpegdec = (GstFFMpegAudDec *) decoder;
784 +
785 +  if (G_UNLIKELY (!ffmpegdec->opened))
786 +    goto not_negotiated;
787 +
788 +  if (inbuf == NULL) {
789 +    gst_ffmpegauddec_drain (ffmpegdec);
790 +    return GST_FLOW_OK;
791 +  }
792 +
793 +  inbuf = gst_buffer_ref (inbuf);
794 +
795 +  oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
796 +
797 +  GST_LOG_OBJECT (ffmpegdec,
798 +      "Received new data of size %u, offset:%" G_GUINT64_FORMAT ", ts:%"
799 +      GST_TIME_FORMAT ", dur:%" GST_TIME_FORMAT,
800 +      gst_buffer_get_size (inbuf), GST_BUFFER_OFFSET (inbuf),
801 +      GST_TIME_ARGS (GST_BUFFER_PTS (inbuf)),
802 +      GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)));
803 +
804 +  /* workarounds, functions write to buffers:
805 +   *  libavcodec/svq1.c:svq1_decode_frame writes to the given buffer.
806 +   *  libavcodec/svq3.c:svq3_decode_slice_header too.
807 +   * ffmpeg devs know about it and will fix it (they said). */
808 +  if (oclass->in_plugin->id == CODEC_ID_SVQ1 ||
809 +      oclass->in_plugin->id == CODEC_ID_SVQ3) {
810 +    inbuf = gst_buffer_make_writable (inbuf);
811 +  }
812 +
813 +  gst_buffer_map (inbuf, &map, GST_MAP_READ);
814 +
815 +  bdata = map.data;
816 +  bsize = map.size;
817 +
818 +  do {
819 +    data = bdata;
820 +    size = bsize;
821 +
822 +    /* decode a frame of audio now */
823 +    len = gst_ffmpegauddec_frame (ffmpegdec, data, size, &have_data, &ret);
824 +
825 +    if (ret != GST_FLOW_OK) {
826 +      GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
827 +          gst_flow_get_name (ret));
828 +      /* bad flow return, make sure we discard all data and exit */
829 +      bsize = 0;
830 +      break;
831 +    }
832 +
833 +    if (len == 0 && !have_data) {
834 +      /* nothing was decoded, this could be because no data was available or
835 +       * because we were skipping frames.
836 +       * If we have no context we must exit and wait for more data, we keep the
837 +       * data we tried. */
838 +      GST_LOG_OBJECT (ffmpegdec, "Decoding didn't return any data, breaking");
839 +      break;
840 +    } else if (len < 0) {
841 +      /* a decoding error happened, we must break and try again with next data. */
842 +      GST_LOG_OBJECT (ffmpegdec, "Decoding error, breaking");
843 +      bsize = 0;
844 +      break;
845 +    }
846 +    /* prepare for the next round, for codecs with a context we did this
847 +     * already when using the parser. */
848 +    bsize -= len;
849 +    bdata += len;
850 +
851 +    GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0).  bsize:%d , bdata:%p",
852 +        bsize, bdata);
853 +  } while (bsize > 0);
854 +
855 +  gst_buffer_unmap (inbuf, &map);
856 +  gst_buffer_unref (inbuf);
857 +
858 +  if (ffmpegdec->outbuf)
859 +    ret =
860 +        gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec),
861 +        ffmpegdec->outbuf, 1);
862 +  ffmpegdec->outbuf = NULL;
863 +
864 +  if (bsize > 0) {
865 +    GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
866 +  }
867 +
868 +  return ret;
869 +
870 +  /* ERRORS */
871 +not_negotiated:
872 +  {
873 +    oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
874 +    GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL),
875 +        ("avdec_%s: input format was not set before data start",
876 +            oclass->in_plugin->name));
877 +    return GST_FLOW_NOT_NEGOTIATED;
878 +  }
879 +}
880 +
881 +gboolean
882 +gst_ffmpegauddec_register (GstPlugin * plugin)
883 +{
884 +  GTypeInfo typeinfo = {
885 +    sizeof (GstFFMpegAudDecClass),
886 +    (GBaseInitFunc) gst_ffmpegauddec_base_init,
887 +    NULL,
888 +    (GClassInitFunc) gst_ffmpegauddec_class_init,
889 +    NULL,
890 +    NULL,
891 +    sizeof (GstFFMpegAudDec),
892 +    0,
893 +    (GInstanceInitFunc) gst_ffmpegauddec_init,
894 +  };
895 +  GType type;
896 +  AVCodec *in_plugin;
897 +  gint rank;
898 +
899 +  in_plugin = av_codec_next (NULL);
900 +
901 +  GST_LOG ("Registering decoders");
902 +
903 +  while (in_plugin) {
904 +    gchar *type_name;
905 +    gchar *plugin_name;
906 +
907 +    /* only decoders */
908 +    if (!av_codec_is_decoder (in_plugin)
909 +        || in_plugin->type != AVMEDIA_TYPE_AUDIO) {
910 +      goto next;
911 +    }
912 +
913 +    /* no quasi-codecs, please */
914 +    if (in_plugin->id >= CODEC_ID_PCM_S16LE &&
915 +        in_plugin->id <= CODEC_ID_PCM_BLURAY) {
916 +      goto next;
917 +    }
918 +
919 +    /* No decoders depending on external libraries (we don't build them, but
920 +     * people who build against an external ffmpeg might have them.
921 +     * We have native gstreamer plugins for all of those libraries anyway. */
922 +    if (!strncmp (in_plugin->name, "lib", 3)) {
923 +      GST_DEBUG
924 +          ("Not using external library decoder %s. Use the gstreamer-native ones instead.",
925 +          in_plugin->name);
926 +      goto next;
927 +    }
928 +
929 +    GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
930 +
931 +    /* no codecs for which we're GUARANTEED to have better alternatives */
932 +    /* MP1 : Use MP3 for decoding */
933 +    /* MP2 : Use MP3 for decoding */
934 +    /* Theora: Use libtheora based theoradec */
935 +    if (!strcmp (in_plugin->name, "vorbis") ||
936 +        !strcmp (in_plugin->name, "wavpack") ||
937 +        !strcmp (in_plugin->name, "mp1") ||
938 +        !strcmp (in_plugin->name, "mp2") ||
939 +        !strcmp (in_plugin->name, "libfaad") ||
940 +        !strcmp (in_plugin->name, "mpeg4aac") ||
941 +        !strcmp (in_plugin->name, "ass") ||
942 +        !strcmp (in_plugin->name, "srt") ||
943 +        !strcmp (in_plugin->name, "pgssub") ||
944 +        !strcmp (in_plugin->name, "dvdsub") ||
945 +        !strcmp (in_plugin->name, "dvbsub")) {
946 +      GST_LOG ("Ignoring decoder %s", in_plugin->name);
947 +      goto next;
948 +    }
949 +
950 +    /* construct the type */
951 +    plugin_name = g_strdup ((gchar *) in_plugin->name);
952 +    g_strdelimit (plugin_name, NULL, '_');
953 +    type_name = g_strdup_printf ("avdec_%s", plugin_name);
954 +    g_free (plugin_name);
955 +
956 +    type = g_type_from_name (type_name);
957 +
958 +    if (!type) {
959 +      /* create the gtype now */
960 +      type =
961 +          g_type_register_static (GST_TYPE_AUDIO_DECODER, type_name, &typeinfo,
962 +          0);
963 +      g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) in_plugin);
964 +    }
965 +
966 +    /* (Ronald) MPEG-4 gets a higher priority because it has been well-
967 +     * tested and by far outperforms divxdec/xviddec - so we prefer it.
968 +     * msmpeg4v3 same, as it outperforms divxdec for divx3 playback.
969 +     * VC1/WMV3 are not working and thus unpreferred for now. */
970 +    switch (in_plugin->id) {
971 +      case CODEC_ID_RA_144:
972 +      case CODEC_ID_RA_288:
973 +      case CODEC_ID_COOK:
974 +        rank = GST_RANK_PRIMARY;
975 +        break;
976 +        /* SIPR: decoder should have a higher rank than realaudiodec.
977 +         */
978 +      case CODEC_ID_SIPR:
979 +        rank = GST_RANK_SECONDARY;
980 +        break;
981 +      case CODEC_ID_MP3:
982 +        rank = GST_RANK_NONE;
983 +        break;
984 +      default:
985 +        rank = GST_RANK_MARGINAL;
986 +        break;
987 +    }
988 +    if (!gst_element_register (plugin, type_name, rank, type)) {
989 +      g_warning ("Failed to register %s", type_name);
990 +      g_free (type_name);
991 +      return FALSE;
992 +    }
993 +
994 +    g_free (type_name);
995 +
996 +  next:
997 +    in_plugin = av_codec_next (in_plugin);
998 +  }
999 +
1000 +  GST_LOG ("Finished Registering decoders");
1001 +
1002 +  return TRUE;
1003 +}
1004 Index: gst-libav1.0/ext/libav/gstavauddec.h
1005 ===================================================================
1006 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1007 +++ gst-libav1.0/ext/libav/gstavauddec.h        2012-12-18 11:40:28.506169306 +0100
1008 @@ -0,0 +1,73 @@
1009 +/* GStreamer
1010 + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
1011 + *
1012 + * This library is free software; you can redistribute it and/or
1013 + * modify it under the terms of the GNU Library General Public
1014 + * License as published by the Free Software Foundation; either
1015 + * version 2 of the License, or (at your option) any later version.
1016 + *
1017 + * This library is distributed in the hope that it will be useful,
1018 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1019 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1020 + * Library General Public License for more details.
1021 + *
1022 + * You should have received a copy of the GNU Library General Public
1023 + * License along with this library; if not, write to the
1024 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
1025 + * Boston, MA 02110-1301, USA.
1026 + */
1027 +#ifndef __GST_FFMPEGAUDDEC_H__
1028 +#define __GST_FFMPEGAUDDEC_H__
1029 +
1030 +G_BEGIN_DECLS
1031 +
1032 +#include <gst/gst.h>
1033 +#include <gst/audio/audio.h>
1034 +#include <gst/audio/gstaudiodecoder.h>
1035 +#include <libavcodec/avcodec.h>
1036 +
1037 +typedef struct _GstFFMpegAudDec GstFFMpegAudDec;
1038 +struct _GstFFMpegAudDec
1039 +{
1040 +  GstAudioDecoder parent;
1041 +
1042 +  /* decoding */
1043 +  AVCodecContext *context;
1044 +  gboolean opened;
1045 +
1046 +  /* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
1047 +  GstCaps *last_caps;
1048 +
1049 +  /* Stores current buffers to push as GstAudioDecoder wants 1:1 mapping for input/output buffers */
1050 +  GstBuffer *outbuf;
1051 +
1052 +  /* current output format */
1053 +  GstAudioInfo info;
1054 +  GstAudioChannelPosition ffmpeg_layout[64];
1055 +  gboolean needs_reorder;
1056 +};
1057 +
1058 +typedef struct _GstFFMpegAudDecClass GstFFMpegAudDecClass;
1059 +
1060 +struct _GstFFMpegAudDecClass
1061 +{
1062 +  GstAudioDecoderClass parent_class;
1063 +
1064 +  AVCodec *in_plugin;
1065 +  GstPadTemplate *srctempl, *sinktempl;
1066 +};
1067 +
1068 +#define GST_TYPE_FFMPEGDEC \
1069 +  (gst_ffmpegauddec_get_type())
1070 +#define GST_FFMPEGDEC(obj) \
1071 +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGDEC,GstFFMpegAudDec))
1072 +#define GST_FFMPEGAUDDEC_CLASS(klass) \
1073 +  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGDEC,GstFFMpegAudDecClass))
1074 +#define GST_IS_FFMPEGDEC(obj) \
1075 +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGDEC))
1076 +#define GST_IS_FFMPEGAUDDEC_CLASS(klass) \
1077 +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGDEC))
1078 +
1079 +G_END_DECLS
1080 +
1081 +#endif
1082 Index: gst-libav1.0/ext/libav/gstavaudenc.c
1083 ===================================================================
1084 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1085 +++ gst-libav1.0/ext/libav/gstavaudenc.c        2012-12-18 11:40:28.506169306 +0100
1086 @@ -0,0 +1,741 @@
1087 +/* GStreamer
1088 + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
1089 + * Copyright (C) <2012> Collabora Ltd.
1090 + *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
1091 + *
1092 + * This library is free software; you can redistribute it and/or
1093 + * modify it under the terms of the GNU Library General Public
1094 + * License as published by the Free Software Foundation; either
1095 + * version 2 of the License, or (at your option) any later version.
1096 + *
1097 + * This library is distributed in the hope that it will be useful,
1098 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1099 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1100 + * Library General Public License for more details.
1101 + *
1102 + * You should have received a copy of the GNU Library General Public
1103 + * License along with this library; if not, write to the
1104 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
1105 + * Boston, MA 02110-1301, USA.
1106 + */
1107 +
1108 +#ifdef HAVE_CONFIG_H
1109 +#include "config.h"
1110 +#endif
1111 +
1112 +#include <assert.h>
1113 +#include <string.h>
1114 +/* for stats file handling */
1115 +#include <stdio.h>
1116 +#include <glib/gstdio.h>
1117 +#include <errno.h>
1118 +
1119 +#include <libavcodec/avcodec.h>
1120 +
1121 +#include <gst/gst.h>
1122 +
1123 +#include "gstav.h"
1124 +#include "gstavcodecmap.h"
1125 +#include "gstavutils.h"
1126 +#include "gstavaudenc.h"
1127 +
1128 +#define DEFAULT_AUDIO_BITRATE 128000
1129 +
1130 +enum
1131 +{
1132 +  /* FILL ME */
1133 +  LAST_SIGNAL
1134 +};
1135 +
1136 +enum
1137 +{
1138 +  PROP_0,
1139 +  PROP_BIT_RATE,
1140 +  PROP_RTP_PAYLOAD_SIZE,
1141 +};
1142 +
1143 +/* A number of function prototypes are given so we can refer to them later. */
1144 +static void gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass);
1145 +static void gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass);
1146 +static void gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc);
1147 +static void gst_ffmpegaudenc_finalize (GObject * object);
1148 +
1149 +static GstCaps *gst_ffmpegaudenc_getcaps (GstAudioEncoder * encoder,
1150 +    GstCaps * filter);
1151 +static gboolean gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder,
1152 +    GstAudioInfo * info);
1153 +static GstFlowReturn gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder,
1154 +    GstBuffer * inbuf);
1155 +static gboolean gst_ffmpegaudenc_stop (GstAudioEncoder * encoder);
1156 +static void gst_ffmpegaudenc_flush (GstAudioEncoder * encoder);
1157 +
1158 +static void gst_ffmpegaudenc_set_property (GObject * object,
1159 +    guint prop_id, const GValue * value, GParamSpec * pspec);
1160 +static void gst_ffmpegaudenc_get_property (GObject * object,
1161 +    guint prop_id, GValue * value, GParamSpec * pspec);
1162 +
1163 +#define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("avenc-params")
1164 +
1165 +static GstElementClass *parent_class = NULL;
1166 +
1167 +/*static guint gst_ffmpegaudenc_signals[LAST_SIGNAL] = { 0 }; */
1168 +
1169 +static void
1170 +gst_ffmpegaudenc_base_init (GstFFMpegAudEncClass * klass)
1171 +{
1172 +  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
1173 +  AVCodec *in_plugin;
1174 +  GstPadTemplate *srctempl = NULL, *sinktempl = NULL;
1175 +  GstCaps *srccaps = NULL, *sinkcaps = NULL;
1176 +  gchar *longname, *description;
1177 +
1178 +  in_plugin =
1179 +      (AVCodec *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
1180 +      GST_FFENC_PARAMS_QDATA);
1181 +  g_assert (in_plugin != NULL);
1182 +
1183 +  /* construct the element details struct */
1184 +  longname = g_strdup_printf ("libav %s encoder", in_plugin->long_name);
1185 +  description = g_strdup_printf ("libav %s encoder", in_plugin->name);
1186 +  gst_element_class_set_metadata (element_class, longname,
1187 +      "Codec/Encoder/Audio", description,
1188 +      "Wim Taymans <wim.taymans@gmail.com>, "
1189 +      "Ronald Bultje <rbultje@ronald.bitfreak.net>");
1190 +  g_free (longname);
1191 +  g_free (description);
1192 +
1193 +  if (!(srccaps = gst_ffmpeg_codecid_to_caps (in_plugin->id, NULL, TRUE))) {
1194 +    GST_DEBUG ("Couldn't get source caps for encoder '%s'", in_plugin->name);
1195 +    srccaps = gst_caps_new_empty_simple ("unknown/unknown");
1196 +  }
1197 +
1198 +  sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
1199 +      in_plugin->id, TRUE, in_plugin);
1200 +  if (!sinkcaps) {
1201 +    GST_DEBUG ("Couldn't get sink caps for encoder '%s'", in_plugin->name);
1202 +    sinkcaps = gst_caps_new_empty_simple ("unknown/unknown");
1203 +  }
1204 +
1205 +  /* pad templates */
1206 +  sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK,
1207 +      GST_PAD_ALWAYS, sinkcaps);
1208 +  srctempl = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, srccaps);
1209 +
1210 +  gst_element_class_add_pad_template (element_class, srctempl);
1211 +  gst_element_class_add_pad_template (element_class, sinktempl);
1212 +
1213 +  klass->in_plugin = in_plugin;
1214 +  klass->srctempl = srctempl;
1215 +  klass->sinktempl = sinktempl;
1216 +
1217 +  return;
1218 +}
1219 +
1220 +static void
1221 +gst_ffmpegaudenc_class_init (GstFFMpegAudEncClass * klass)
1222 +{
1223 +  GObjectClass *gobject_class;
1224 +  GstAudioEncoderClass *gstaudioencoder_class;
1225 +
1226 +  gobject_class = (GObjectClass *) klass;
1227 +  gstaudioencoder_class = (GstAudioEncoderClass *) klass;
1228 +
1229 +  parent_class = g_type_class_peek_parent (klass);
1230 +
1231 +  gobject_class->set_property = gst_ffmpegaudenc_set_property;
1232 +  gobject_class->get_property = gst_ffmpegaudenc_get_property;
1233 +
1234 +  /* FIXME: could use -1 for a sensible per-codec defaults */
1235 +  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BIT_RATE,
1236 +      g_param_spec_int ("bitrate", "Bit Rate",
1237 +          "Target Audio Bitrate", 0, G_MAXINT, DEFAULT_AUDIO_BITRATE,
1238 +          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1239 +
1240 +  gobject_class->finalize = gst_ffmpegaudenc_finalize;
1241 +
1242 +  gstaudioencoder_class->stop = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_stop);
1243 +  gstaudioencoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_getcaps);
1244 +  gstaudioencoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_flush);
1245 +  gstaudioencoder_class->set_format =
1246 +      GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_set_format);
1247 +  gstaudioencoder_class->handle_frame =
1248 +      GST_DEBUG_FUNCPTR (gst_ffmpegaudenc_handle_frame);
1249 +}
1250 +
1251 +static void
1252 +gst_ffmpegaudenc_init (GstFFMpegAudEnc * ffmpegaudenc)
1253 +{
1254 +  GstFFMpegAudEncClass *klass =
1255 +      (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
1256 +
1257 +  /* ffmpeg objects */
1258 +  ffmpegaudenc->context = avcodec_alloc_context3 (klass->in_plugin);
1259 +  ffmpegaudenc->opened = FALSE;
1260 +
1261 +  gst_audio_encoder_set_drainable (GST_AUDIO_ENCODER (ffmpegaudenc), TRUE);
1262 +}
1263 +
1264 +static void
1265 +gst_ffmpegaudenc_finalize (GObject * object)
1266 +{
1267 +  GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) object;
1268 +
1269 +  /* clean up remaining allocated data */
1270 +  av_free (ffmpegaudenc->context);
1271 +
1272 +  G_OBJECT_CLASS (parent_class)->finalize (object);
1273 +}
1274 +
1275 +static gboolean
1276 +gst_ffmpegaudenc_stop (GstAudioEncoder * encoder)
1277 +{
1278 +  GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
1279 +
1280 +  /* close old session */
1281 +  gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
1282 +  ffmpegaudenc->opened = FALSE;
1283 +
1284 +  return TRUE;
1285 +}
1286 +
1287 +static void
1288 +gst_ffmpegaudenc_flush (GstAudioEncoder * encoder)
1289 +{
1290 +  GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
1291 +
1292 +  if (ffmpegaudenc->opened) {
1293 +    avcodec_flush_buffers (ffmpegaudenc->context);
1294 +  }
1295 +}
1296 +
1297 +static GstCaps *
1298 +gst_ffmpegaudenc_getcaps (GstAudioEncoder * encoder, GstCaps * filter)
1299 +{
1300 +  GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
1301 +  GstCaps *caps = NULL;
1302 +
1303 +  GST_DEBUG_OBJECT (ffmpegaudenc, "getting caps");
1304 +
1305 +  /* audio needs no special care */
1306 +  caps = gst_audio_encoder_proxy_getcaps (encoder, NULL, filter);
1307 +
1308 +  GST_DEBUG_OBJECT (ffmpegaudenc, "audio caps, return %" GST_PTR_FORMAT, caps);
1309 +
1310 +  return caps;
1311 +}
1312 +
1313 +static gboolean
1314 +gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info)
1315 +{
1316 +  GstFFMpegAudEnc *ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
1317 +  GstCaps *other_caps;
1318 +  GstCaps *allowed_caps;
1319 +  GstCaps *icaps;
1320 +  gsize frame_size;
1321 +  GstFFMpegAudEncClass *oclass =
1322 +      (GstFFMpegAudEncClass *) G_OBJECT_GET_CLASS (ffmpegaudenc);
1323 +
1324 +  /* close old session */
1325 +  if (ffmpegaudenc->opened) {
1326 +    gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
1327 +    ffmpegaudenc->opened = FALSE;
1328 +  }
1329 +
1330 +  /* if we set it in _getcaps we should set it also in _link */
1331 +  ffmpegaudenc->context->strict_std_compliance = -1;
1332 +
1333 +  /* user defined properties */
1334 +  if (ffmpegaudenc->bitrate > 0) {
1335 +    GST_INFO_OBJECT (ffmpegaudenc, "Setting avcontext to bitrate %d",
1336 +        ffmpegaudenc->bitrate);
1337 +    ffmpegaudenc->context->bit_rate = ffmpegaudenc->bitrate;
1338 +    ffmpegaudenc->context->bit_rate_tolerance = ffmpegaudenc->bitrate;
1339 +  } else {
1340 +    GST_INFO_OBJECT (ffmpegaudenc, "Using avcontext default bitrate %d",
1341 +        ffmpegaudenc->context->bit_rate);
1342 +  }
1343 +
1344 +  /* RTP payload used for GOB production (for Asterisk) */
1345 +  if (ffmpegaudenc->rtp_payload_size) {
1346 +    ffmpegaudenc->context->rtp_payload_size = ffmpegaudenc->rtp_payload_size;
1347 +  }
1348 +
1349 +  /* some other defaults */
1350 +  ffmpegaudenc->context->rc_strategy = 2;
1351 +  ffmpegaudenc->context->b_frame_strategy = 0;
1352 +  ffmpegaudenc->context->coder_type = 0;
1353 +  ffmpegaudenc->context->context_model = 0;
1354 +  ffmpegaudenc->context->scenechange_threshold = 0;
1355 +  ffmpegaudenc->context->inter_threshold = 0;
1356 +
1357 +  /* fetch pix_fmt and so on */
1358 +  gst_ffmpeg_audioinfo_to_context (info, ffmpegaudenc->context);
1359 +  if (!ffmpegaudenc->context->time_base.den) {
1360 +    ffmpegaudenc->context->time_base.den = GST_AUDIO_INFO_RATE (info);
1361 +    ffmpegaudenc->context->time_base.num = 1;
1362 +    ffmpegaudenc->context->ticks_per_frame = 1;
1363 +  }
1364 +
1365 +  if (ffmpegaudenc->context->channel_layout) {
1366 +    gst_ffmpeg_channel_layout_to_gst (ffmpegaudenc->context->channel_layout,
1367 +        ffmpegaudenc->context->channels, ffmpegaudenc->ffmpeg_layout);
1368 +    ffmpegaudenc->needs_reorder =
1369 +        (memcmp (ffmpegaudenc->ffmpeg_layout, info->position,
1370 +            sizeof (GstAudioChannelPosition) *
1371 +            ffmpegaudenc->context->channels) != 0);
1372 +  }
1373 +
1374 +  /* open codec */
1375 +  if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
1376 +    if (ffmpegaudenc->context->priv_data)
1377 +      gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
1378 +    GST_DEBUG_OBJECT (ffmpegaudenc, "avenc_%s: Failed to open FFMPEG codec",
1379 +        oclass->in_plugin->name);
1380 +    return FALSE;
1381 +  }
1382 +
1383 +  /* some codecs support more than one format, first auto-choose one */
1384 +  GST_DEBUG_OBJECT (ffmpegaudenc, "picking an output format ...");
1385 +  allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
1386 +  if (!allowed_caps) {
1387 +    GST_DEBUG_OBJECT (ffmpegaudenc, "... but no peer, using template caps");
1388 +    /* we need to copy because get_allowed_caps returns a ref, and
1389 +     * get_pad_template_caps doesn't */
1390 +    allowed_caps =
1391 +        gst_pad_get_pad_template_caps (GST_AUDIO_ENCODER_SRC_PAD (encoder));
1392 +  }
1393 +  GST_DEBUG_OBJECT (ffmpegaudenc, "chose caps %" GST_PTR_FORMAT, allowed_caps);
1394 +  gst_ffmpeg_caps_with_codecid (oclass->in_plugin->id,
1395 +      oclass->in_plugin->type, allowed_caps, ffmpegaudenc->context);
1396 +
1397 +  /* try to set this caps on the other side */
1398 +  other_caps = gst_ffmpeg_codecid_to_caps (oclass->in_plugin->id,
1399 +      ffmpegaudenc->context, TRUE);
1400 +
1401 +  if (!other_caps) {
1402 +    gst_caps_unref (allowed_caps);
1403 +    gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
1404 +    GST_DEBUG ("Unsupported codec - no caps found");
1405 +    return FALSE;
1406 +  }
1407 +
1408 +  icaps = gst_caps_intersect (allowed_caps, other_caps);
1409 +  gst_caps_unref (allowed_caps);
1410 +  gst_caps_unref (other_caps);
1411 +  if (gst_caps_is_empty (icaps)) {
1412 +    gst_caps_unref (icaps);
1413 +    return FALSE;
1414 +  }
1415 +  icaps = gst_caps_truncate (icaps);
1416 +
1417 +  if (!gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (ffmpegaudenc),
1418 +          icaps)) {
1419 +    gst_ffmpeg_avcodec_close (ffmpegaudenc->context);
1420 +    gst_caps_unref (icaps);
1421 +    return FALSE;
1422 +  }
1423 +  gst_caps_unref (icaps);
1424 +
1425 +  frame_size = ffmpegaudenc->context->frame_size;
1426 +  if (frame_size > 1) {
1427 +    gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
1428 +        frame_size);
1429 +    gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
1430 +        frame_size);
1431 +    gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 1);
1432 +  } else {
1433 +    gst_audio_encoder_set_frame_samples_min (GST_AUDIO_ENCODER (ffmpegaudenc),
1434 +        0);
1435 +    gst_audio_encoder_set_frame_samples_max (GST_AUDIO_ENCODER (ffmpegaudenc),
1436 +        0);
1437 +    gst_audio_encoder_set_frame_max (GST_AUDIO_ENCODER (ffmpegaudenc), 0);
1438 +  }
1439 +
1440 +  /* success! */
1441 +  ffmpegaudenc->opened = TRUE;
1442 +
1443 +  return TRUE;
1444 +}
1445 +
1446 +
1447 +static GstFlowReturn
1448 +gst_ffmpegaudenc_encode_audio (GstFFMpegAudEnc * ffmpegaudenc,
1449 +    guint8 * audio_in, guint in_size, gint * have_data)
1450 +{
1451 +  GstAudioEncoder *enc;
1452 +  AVCodecContext *ctx;
1453 +  gint res;
1454 +  GstFlowReturn ret;
1455 +  GstAudioInfo *info;
1456 +  AVPacket pkt;
1457 +  AVFrame frame;
1458 +  gboolean planar;
1459 +
1460 +  enc = GST_AUDIO_ENCODER (ffmpegaudenc);
1461 +
1462 +  ctx = ffmpegaudenc->context;
1463 +
1464 +  GST_LOG_OBJECT (ffmpegaudenc, "encoding buffer ");
1465 +
1466 +  memset (&pkt, 0, sizeof (pkt));
1467 +  memset (&frame, 0, sizeof (frame));
1468 +  avcodec_get_frame_defaults (&frame);
1469 +
1470 +  info = gst_audio_encoder_get_audio_info (enc);
1471 +  planar = av_sample_fmt_is_planar (ffmpegaudenc->context->sample_fmt);
1472 +
1473 +  if (planar && info->channels > 1) {
1474 +    gint channels, nsamples;
1475 +    gint i, j;
1476 +
1477 +    nsamples = frame.nb_samples = in_size / info->bpf;
1478 +    channels = info->channels;
1479 +
1480 +    if (info->channels > AV_NUM_DATA_POINTERS) {
1481 +      frame.extended_data = g_new (uint8_t *, info->channels);
1482 +    } else {
1483 +      frame.extended_data = frame.data;
1484 +    }
1485 +
1486 +    frame.extended_data[0] = g_malloc (in_size);
1487 +    frame.linesize[0] = in_size / channels;
1488 +    for (i = 1; i < channels; i++)
1489 +      frame.extended_data[i] = frame.extended_data[i - 1] + frame.linesize[0];
1490 +
1491 +    switch (info->finfo->width) {
1492 +      case 8:{
1493 +        const guint8 *idata = (const guint8 *) audio_in;
1494 +
1495 +        for (i = 0; i < nsamples; i++) {
1496 +          for (j = 0; j < channels; j++) {
1497 +            ((guint8 *) frame.extended_data[j])[i] = idata[j];
1498 +          }
1499 +          idata += channels;
1500 +        }
1501 +        break;
1502 +      }
1503 +      case 16:{
1504 +        const guint16 *idata = (const guint16 *) audio_in;
1505 +
1506 +        for (i = 0; i < nsamples; i++) {
1507 +          for (j = 0; j < channels; j++) {
1508 +            ((guint16 *) frame.extended_data[j])[i] = idata[j];
1509 +          }
1510 +          idata += channels;
1511 +        }
1512 +        break;
1513 +      }
1514 +      case 32:{
1515 +        const guint32 *idata = (const guint32 *) audio_in;
1516 +
1517 +        for (i = 0; i < nsamples; i++) {
1518 +          for (j = 0; j < channels; j++) {
1519 +            ((guint32 *) frame.extended_data[j])[i] = idata[j];
1520 +          }
1521 +          idata += channels;
1522 +        }
1523 +
1524 +        break;
1525 +      }
1526 +      case 64:{
1527 +        const guint64 *idata = (const guint64 *) audio_in;
1528 +
1529 +        for (i = 0; i < nsamples; i++) {
1530 +          for (j = 0; j < channels; j++) {
1531 +            ((guint64 *) frame.extended_data[j])[i] = idata[j];
1532 +          }
1533 +          idata += channels;
1534 +        }
1535 +
1536 +        break;
1537 +      }
1538 +      default:
1539 +        g_assert_not_reached ();
1540 +        break;
1541 +    }
1542 +
1543 +  } else {
1544 +    frame.data[0] = audio_in;
1545 +    frame.extended_data = frame.data;
1546 +    frame.linesize[0] = in_size;
1547 +    frame.nb_samples = in_size / info->bpf;
1548 +  }
1549 +
1550 +  res = avcodec_encode_audio2 (ctx, &pkt, &frame, have_data);
1551 +  if (planar && info->channels > 1)
1552 +    g_free (frame.data[0]);
1553 +  if (frame.extended_data != frame.data)
1554 +    g_free (frame.extended_data);
1555 +
1556 +  if (res < 0) {
1557 +    char error_str[128] = { 0, };
1558 +
1559 +    av_strerror (res, error_str, sizeof (error_str));
1560 +    GST_ERROR_OBJECT (enc, "Failed to encode buffer: %d - %s", res, error_str);
1561 +    return GST_FLOW_OK;
1562 +  }
1563 +  GST_LOG_OBJECT (ffmpegaudenc, "got output size %d", res);
1564 +
1565 +  if (*have_data) {
1566 +    GstBuffer *outbuf;
1567 +    const AVCodec *codec;
1568 +
1569 +    GST_LOG_OBJECT (ffmpegaudenc, "pushing size %d", pkt.size);
1570 +
1571 +    outbuf =
1572 +        gst_buffer_new_wrapped_full (0, pkt.data, pkt.size, 0, pkt.size,
1573 +        pkt.data, av_free);
1574 +
1575 +    codec = ffmpegaudenc->context->codec;
1576 +    if ((codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
1577 +      ret = gst_audio_encoder_finish_frame (enc, outbuf, -1);
1578 +    } else {
1579 +      ret = gst_audio_encoder_finish_frame (enc, outbuf, frame.nb_samples);
1580 +    }
1581 +  } else {
1582 +    GST_LOG_OBJECT (ffmpegaudenc, "no output produced");
1583 +    ret = GST_FLOW_OK;
1584 +  }
1585 +
1586 +  return ret;
1587 +}
1588 +
1589 +static void
1590 +gst_ffmpegaudenc_drain (GstFFMpegAudEnc * ffmpegaudenc)
1591 +{
1592 +  GstFFMpegAudEncClass *oclass;
1593 +
1594 +  oclass = (GstFFMpegAudEncClass *) (G_OBJECT_GET_CLASS (ffmpegaudenc));
1595 +
1596 +  if (oclass->in_plugin->capabilities & CODEC_CAP_DELAY) {
1597 +    gint have_data, try = 0;
1598 +
1599 +    GST_LOG_OBJECT (ffmpegaudenc,
1600 +        "codec has delay capabilities, calling until libav has drained everything");
1601 +
1602 +    do {
1603 +      GstFlowReturn ret;
1604 +
1605 +      ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, NULL, 0, &have_data);
1606 +      if (ret != GST_FLOW_OK || have_data == 0)
1607 +        break;
1608 +    } while (try++ < 10);
1609 +  }
1610 +}
1611 +
1612 +static GstFlowReturn
1613 +gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf)
1614 +{
1615 +  GstFFMpegAudEnc *ffmpegaudenc;
1616 +  gsize size;
1617 +  GstFlowReturn ret;
1618 +  guint8 *in_data;
1619 +  GstMapInfo map;
1620 +  gint have_data;
1621 +
1622 +  ffmpegaudenc = (GstFFMpegAudEnc *) encoder;
1623 +
1624 +  if (G_UNLIKELY (!ffmpegaudenc->opened))
1625 +    goto not_negotiated;
1626 +
1627 +  if (!inbuf) {
1628 +    gst_ffmpegaudenc_drain (ffmpegaudenc);
1629 +    return GST_FLOW_OK;
1630 +  }
1631 +
1632 +  inbuf = gst_buffer_ref (inbuf);
1633 +
1634 +  GST_DEBUG_OBJECT (ffmpegaudenc,
1635 +      "Received time %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
1636 +      ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
1637 +      GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (inbuf));
1638 +
1639 +  /* Reorder channels to the GStreamer channel order */
1640 +  if (ffmpegaudenc->needs_reorder) {
1641 +    GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder);
1642 +
1643 +    inbuf = gst_buffer_make_writable (inbuf);
1644 +    gst_audio_buffer_reorder_channels (inbuf, info->finfo->format,
1645 +        info->channels, info->position, ffmpegaudenc->ffmpeg_layout);
1646 +  }
1647 +
1648 +  gst_buffer_map (inbuf, &map, GST_MAP_READ);
1649 +  in_data = map.data;
1650 +  size = map.size;
1651 +  ret = gst_ffmpegaudenc_encode_audio (ffmpegaudenc, in_data, size, &have_data);
1652 +  gst_buffer_unmap (inbuf, &map);
1653 +  gst_buffer_unref (inbuf);
1654 +
1655 +  if (ret != GST_FLOW_OK)
1656 +    goto push_failed;
1657 +
1658 +  return GST_FLOW_OK;
1659 +
1660 +  /* ERRORS */
1661 +not_negotiated:
1662 +  {
1663 +    GST_ELEMENT_ERROR (ffmpegaudenc, CORE, NEGOTIATION, (NULL),
1664 +        ("not configured to input format before data start"));
1665 +    gst_buffer_unref (inbuf);
1666 +    return GST_FLOW_NOT_NEGOTIATED;
1667 +  }
1668 +push_failed:
1669 +  {
1670 +    GST_DEBUG_OBJECT (ffmpegaudenc, "Failed to push buffer %d (%s)", ret,
1671 +        gst_flow_get_name (ret));
1672 +    return ret;
1673 +  }
1674 +}
1675 +
1676 +static void
1677 +gst_ffmpegaudenc_set_property (GObject * object,
1678 +    guint prop_id, const GValue * value, GParamSpec * pspec)
1679 +{
1680 +  GstFFMpegAudEnc *ffmpegaudenc;
1681 +
1682 +  /* Get a pointer of the right type. */
1683 +  ffmpegaudenc = (GstFFMpegAudEnc *) (object);
1684 +
1685 +  if (ffmpegaudenc->opened) {
1686 +    GST_WARNING_OBJECT (ffmpegaudenc,
1687 +        "Can't change properties once decoder is setup !");
1688 +    return;
1689 +  }
1690 +
1691 +  /* Check the argument id to see which argument we're setting. */
1692 +  switch (prop_id) {
1693 +    case PROP_BIT_RATE:
1694 +      ffmpegaudenc->bitrate = g_value_get_int (value);
1695 +      break;
1696 +    case PROP_RTP_PAYLOAD_SIZE:
1697 +      ffmpegaudenc->rtp_payload_size = g_value_get_int (value);
1698 +      break;
1699 +    default:
1700 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1701 +      break;
1702 +  }
1703 +}
1704 +
1705 +/* The set function is simply the inverse of the get fuction. */
1706 +static void
1707 +gst_ffmpegaudenc_get_property (GObject * object,
1708 +    guint prop_id, GValue * value, GParamSpec * pspec)
1709 +{
1710 +  GstFFMpegAudEnc *ffmpegaudenc;
1711 +
1712 +  /* It's not null if we got it, but it might not be ours */
1713 +  ffmpegaudenc = (GstFFMpegAudEnc *) (object);
1714 +
1715 +  switch (prop_id) {
1716 +    case PROP_BIT_RATE:
1717 +      g_value_set_int (value, ffmpegaudenc->bitrate);
1718 +      break;
1719 +      break;
1720 +    case PROP_RTP_PAYLOAD_SIZE:
1721 +      g_value_set_int (value, ffmpegaudenc->rtp_payload_size);
1722 +      break;
1723 +    default:
1724 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1725 +      break;
1726 +  }
1727 +}
1728 +
1729 +gboolean
1730 +gst_ffmpegaudenc_register (GstPlugin * plugin)
1731 +{
1732 +  GTypeInfo typeinfo = {
1733 +    sizeof (GstFFMpegAudEncClass),
1734 +    (GBaseInitFunc) gst_ffmpegaudenc_base_init,
1735 +    NULL,
1736 +    (GClassInitFunc) gst_ffmpegaudenc_class_init,
1737 +    NULL,
1738 +    NULL,
1739 +    sizeof (GstFFMpegAudEnc),
1740 +    0,
1741 +    (GInstanceInitFunc) gst_ffmpegaudenc_init,
1742 +  };
1743 +  GType type;
1744 +  AVCodec *in_plugin;
1745 +
1746 +
1747 +  GST_LOG ("Registering encoders");
1748 +
1749 +  in_plugin = av_codec_next (NULL);
1750 +  while (in_plugin) {
1751 +    gchar *type_name;
1752 +
1753 +    /* Skip non-AV codecs */
1754 +    if (in_plugin->type != AVMEDIA_TYPE_AUDIO)
1755 +      goto next;
1756 +
1757 +    /* no quasi codecs, please */
1758 +    if ((in_plugin->id >= CODEC_ID_PCM_S16LE &&
1759 +            in_plugin->id <= CODEC_ID_PCM_BLURAY)) {
1760 +      goto next;
1761 +    }
1762 +
1763 +    /* No encoders depending on external libraries (we don't build them, but
1764 +     * people who build against an external ffmpeg might have them.
1765 +     * We have native gstreamer plugins for all of those libraries anyway. */
1766 +    if (!strncmp (in_plugin->name, "lib", 3)) {
1767 +      GST_DEBUG
1768 +          ("Not using external library encoder %s. Use the gstreamer-native ones instead.",
1769 +          in_plugin->name);
1770 +      goto next;
1771 +    }
1772 +
1773 +    /* only encoders */
1774 +    if (!av_codec_is_encoder (in_plugin)) {
1775 +      goto next;
1776 +    }
1777 +
1778 +    /* FIXME : We should have a method to know cheaply whether we have a mapping
1779 +     * for the given plugin or not */
1780 +
1781 +    GST_DEBUG ("Trying plugin %s [%s]", in_plugin->name, in_plugin->long_name);
1782 +
1783 +    /* no codecs for which we're GUARANTEED to have better alternatives */
1784 +    if (!strcmp (in_plugin->name, "vorbis")
1785 +        || !strcmp (in_plugin->name, "flac")) {
1786 +      GST_LOG ("Ignoring encoder %s", in_plugin->name);
1787 +      goto next;
1788 +    }
1789 +
1790 +    /* construct the type */
1791 +    type_name = g_strdup_printf ("avenc_%s", in_plugin->name);
1792 +
1793 +    type = g_type_from_name (type_name);
1794 +
1795 +    if (!type) {
1796 +
1797 +      /* create the glib type now */
1798 +      type =
1799 +          g_type_register_static (GST_TYPE_AUDIO_ENCODER, type_name, &typeinfo,
1800 +          0);
1801 +      g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) in_plugin);
1802 +
1803 +      {
1804 +        static const GInterfaceInfo preset_info = {
1805 +          NULL,
1806 +          NULL,
1807 +          NULL
1808 +        };
1809 +        g_type_add_interface_static (type, GST_TYPE_PRESET, &preset_info);
1810 +      }
1811 +    }
1812 +
1813 +    if (!gst_element_register (plugin, type_name, GST_RANK_SECONDARY, type)) {
1814 +      g_free (type_name);
1815 +      return FALSE;
1816 +    }
1817 +
1818 +    g_free (type_name);
1819 +
1820 +  next:
1821 +    in_plugin = av_codec_next (in_plugin);
1822 +  }
1823 +
1824 +  GST_LOG ("Finished registering encoders");
1825 +
1826 +  return TRUE;
1827 +}
1828 Index: gst-libav1.0/ext/libav/gstavaudenc.h
1829 ===================================================================
1830 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1831 +++ gst-libav1.0/ext/libav/gstavaudenc.h        2012-12-18 11:40:28.506169306 +0100
1832 @@ -0,0 +1,77 @@
1833 +/* GStreamer
1834 + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
1835 + *
1836 + * This library is free software; you can redistribute it and/or
1837 + * modify it under the terms of the GNU Library General Public
1838 + * License as published by the Free Software Foundation; either
1839 + * version 2 of the License, or (at your option) any later version.
1840 + *
1841 + * This library is distributed in the hope that it will be useful,
1842 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1843 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1844 + * Library General Public License for more details.
1845 + *
1846 + * You should have received a copy of the GNU Library General Public
1847 + * License along with this library; if not, write to the
1848 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
1849 + * Boston, MA 02110-1301, USA.
1850 + */
1851 +
1852 +/* First, include the header file for the plugin, to bring in the
1853 + * object definition and other useful things.
1854 + */
1855 +
1856 +#ifndef __GST_FFMPEGAUDENC_H__
1857 +#define __GST_FFMPEGAUDENC_H__
1858 +
1859 +G_BEGIN_DECLS
1860 +
1861 +#include <gst/gst.h>
1862 +#include <gst/audio/gstaudioencoder.h>
1863 +#include <libavcodec/avcodec.h>
1864 +
1865 +typedef struct _GstFFMpegAudEnc GstFFMpegAudEnc;
1866 +
1867 +struct _GstFFMpegAudEnc
1868 +{
1869 +  GstAudioEncoder parent;
1870 +
1871 +  AVCodecContext *context;
1872 +  gboolean opened;
1873 +
1874 +  /* cache */
1875 +  gint bitrate;
1876 +  gint rtp_payload_size;
1877 +
1878 +  /* other settings are copied over straight,
1879 +   * include a context here, rather than copy-and-past it from avcodec.h */
1880 +  AVCodecContext config;
1881 +
1882 +  GstAudioChannelPosition ffmpeg_layout[64];
1883 +  gboolean needs_reorder;
1884 +};
1885 +
1886 +typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass;
1887 +
1888 +struct _GstFFMpegAudEncClass
1889 +{
1890 +  GstAudioEncoderClass parent_class;
1891 +
1892 +  AVCodec *in_plugin;
1893 +  GstPadTemplate *srctempl, *sinktempl;
1894 +};
1895 +
1896 +#define GST_TYPE_FFMPEGAUDENC \
1897 +  (gst_ffmpegaudenc_get_type())
1898 +#define GST_FFMPEGAUDENC(obj) \
1899 +  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEnc))
1900 +#define GST_FFMPEGAUDENC_CLASS(klass) \
1901 +  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FFMPEGAUDENC,GstFFMpegAudEncClass))
1902 +#define GST_IS_FFMPEGAUDENC(obj) \
1903 +  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FFMPEGAUDENC))
1904 +#define GST_IS_FFMPEGAUDENC_CLASS(klass) \
1905 +  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FFMPEGAUDENC))
1906 +
1907 +G_END_DECLS
1908 +
1909 +#endif /* __GST_FFMPEGAUDENC_H__ */
1910 Index: gst-libav1.0/ext/libav/gstavcfg.c
1911 ===================================================================
1912 --- gst-libav1.0.orig/ext/libav/gstavcfg.c      2012-09-14 12:09:56.000000000 +0200
1913 +++ gst-libav1.0/ext/libav/gstavcfg.c   2012-12-18 11:40:28.506169306 +0100
1914 @@ -16,8 +16,8 @@
1915   *
1916   * You should have received a copy of the GNU Library General Public
1917   * License along with this library; if not, write to the
1918 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1919 - * Boston, MA 02111-1307, USA.
1920 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
1921 + * Boston, MA 02110-1301, USA.
1922   */
1923  
1924  
1925 @@ -147,7 +147,6 @@
1926        {FF_DCT_FASTINT, "Fast Integer", "fastint"},
1927        {FF_DCT_INT, "Accurate Integer", "int"},
1928        {FF_DCT_MMX, "MMX", "mmx"},
1929 -      {FF_DCT_MLIB, "MLIB", "mlib"},
1930        {FF_DCT_ALTIVEC, "ALTIVEC", "altivec"},
1931        {FF_DCT_FAAN, "FAAN", "faan"},
1932        {0, NULL, NULL},
1933 @@ -173,8 +172,6 @@
1934        {FF_IDCT_SIMPLE, "Simple", "simple"},
1935        {FF_IDCT_SIMPLEMMX, "Simple MMX", "simplemmx"},
1936        {FF_IDCT_LIBMPEG2MMX, "LIBMPEG2MMX", "libmpeg2mmx"},
1937 -      {FF_IDCT_PS2, "PS2", "ps2"},
1938 -      {FF_IDCT_MLIB, "MLIB", "mlib"},
1939        {FF_IDCT_ARM, "ARM", "arm"},
1940        {FF_IDCT_ALTIVEC, "ALTIVEC", "altivec"},
1941        {FF_IDCT_SH4, "SH4", "sh4"},
1942 @@ -263,16 +260,11 @@
1943  
1944    if (!ffmpeg_flags_type) {
1945      static const GFlagsValue ffmpeg_flags[] = {
1946 -      {CODEC_FLAG_OBMC, "Use overlapped block motion compensation (h263+)",
1947 -          "obmc"},
1948        {CODEC_FLAG_QSCALE, "Use fixed qscale", "qscale"},
1949        {CODEC_FLAG_4MV, "Allow 4 MV per MB", "4mv"},
1950 -      {CODEC_FLAG_H263P_AIV, "H.263 alternative inter VLC", "aiv"},
1951        {CODEC_FLAG_QPEL, "Quartel Pel Motion Compensation", "qpel"},
1952        {CODEC_FLAG_GMC, "GMC", "gmc"},
1953        {CODEC_FLAG_MV0, "Always try a MB with MV (0,0)", "mv0"},
1954 -      {CODEC_FLAG_PART,
1955 -          "Store MV, DC and AC coefficients in seperate partitions", "part"},
1956        {CODEC_FLAG_LOOP_FILTER, "Loop filter", "loop-filter"},
1957        {CODEC_FLAG_GRAY, "Only decode/encode grayscale", "gray"},
1958        {CODEC_FLAG_NORMALIZE_AQP,
1959 @@ -282,13 +274,9 @@
1960            "global-headers"},
1961        {CODEC_FLAG_AC_PRED, "H263 Advanced Intra Coding / MPEG4 AC prediction",
1962            "aic"},
1963 -      {CODEC_FLAG_H263P_UMV, "Unlimited Motion Vector", "umv"},
1964        {CODEC_FLAG_CBP_RD, "Rate Distoration Optimization for CBP", "cbp-rd"},
1965        {CODEC_FLAG_QP_RD, "Rate Distoration Optimization for QP selection",
1966            "qp-rd"},
1967 -      {CODEC_FLAG_H263P_SLICE_STRUCT, "H263 slice struct", "ss"},
1968 -      {CODEC_FLAG_SVCD_SCAN_OFFSET,
1969 -          "Reserve space for SVCD scan offset user data", "scanoffset"},
1970        {CODEC_FLAG_CLOSED_GOP, "Closed GOP", "closedgop"},
1971        {0, NULL, NULL},
1972      };
1973 @@ -750,10 +738,8 @@
1974    prop_id = base;
1975    g_return_if_fail (base > 0);
1976  
1977 -  ctx = avcodec_alloc_context ();
1978 -  if (ctx)
1979 -    avcodec_get_context_defaults (ctx);
1980 -  else
1981 +  ctx = avcodec_alloc_context3 (klass->in_plugin);
1982 +  if (!ctx)
1983      g_warning ("could not get context");
1984  
1985    for (list = property_list; list; list = list->next) {
1986 Index: gst-libav1.0/ext/libav/gstavcfg.h
1987 ===================================================================
1988 --- gst-libav1.0.orig/ext/libav/gstavcfg.h      2012-09-14 12:09:56.000000000 +0200
1989 +++ gst-libav1.0/ext/libav/gstavcfg.h   2012-12-18 11:40:28.510169305 +0100
1990 @@ -13,8 +13,8 @@
1991   *
1992   * You should have received a copy of the GNU Library General Public
1993   * License along with this library; if not, write to the
1994 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1995 - * Boston, MA 02111-1307, USA.
1996 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
1997 + * Boston, MA 02110-1301, USA.
1998   */
1999  
2000  
2001 Index: gst-libav1.0/ext/libav/gstavcodecmap.c
2002 ===================================================================
2003 --- gst-libav1.0.orig/ext/libav/gstavcodecmap.c 2012-11-21 15:10:58.230244282 +0100
2004 +++ gst-libav1.0/ext/libav/gstavcodecmap.c      2012-12-18 11:40:28.510169305 +0100
2005 @@ -15,8 +15,8 @@
2006   *
2007   * You should have received a copy of the GNU Library General Public
2008   * License along with this library; if not, write to the
2009 - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
2010 - * Boston, MA 02111-1307, USA.
2011 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
2012 + * Boston, MA 02110-1301, USA.
2013   */
2014  
2015  #ifdef HAVE_CONFIG_H
2016 @@ -27,6 +27,7 @@
2017  
2018  #include <gst/gst.h>
2019  #include <libavcodec/avcodec.h>
2020 +#include <libavutil/channel_layout.h>
2021  
2022  #include "gstav.h"
2023  #include "gstavcodecmap.h"
2024 @@ -35,44 +36,6 @@
2025  #include <gst/audio/audio.h>
2026  #include <gst/pbutils/codec-utils.h>
2027  
2028 -/*
2029 - * Read a palette from a caps.
2030 - */
2031 -
2032 -static void
2033 -gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
2034 -{
2035 -  GstStructure *str = gst_caps_get_structure (caps, 0);
2036 -  const GValue *palette_v;
2037 -  GstBuffer *palette;
2038 -
2039 -  /* do we have a palette? */
2040 -  if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
2041 -    palette = gst_value_get_buffer (palette_v);
2042 -    GST_DEBUG ("got palette data %p", palette);
2043 -    if (gst_buffer_get_size (palette) >= AVPALETTE_SIZE) {
2044 -      if (context->palctrl)
2045 -        av_free (context->palctrl);
2046 -      context->palctrl = av_malloc (sizeof (AVPaletteControl));
2047 -      context->palctrl->palette_changed = 1;
2048 -      gst_buffer_extract (palette, 0, context->palctrl->palette,
2049 -          AVPALETTE_SIZE);
2050 -      GST_DEBUG ("extracted palette data");
2051 -    }
2052 -  }
2053 -}
2054 -
2055 -static void
2056 -gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
2057 -{
2058 -  if (context->palctrl) {
2059 -    GstBuffer *palette = gst_buffer_new_and_alloc (AVPALETTE_SIZE);
2060 -
2061 -    gst_buffer_fill (palette, 0, context->palctrl->palette, AVPALETTE_SIZE);
2062 -    gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, palette, NULL);
2063 -  }
2064 -}
2065 -
2066  /* IMPORTANT: Keep this sorted by the ffmpeg channel masks */
2067  static const struct
2068  {
2069 @@ -80,34 +43,60 @@
2070    GstAudioChannelPosition gst;
2071  } _ff_to_gst_layout[] = {
2072    {
2073 -  CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
2074 -  CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
2075 -  CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
2076 -  CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
2077 -  CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
2078 -  CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
2079 -  CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
2080 -  CH_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
2081 -  CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
2082 -  CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
2083 -  CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
2084 -  CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
2085 -  CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
2086 -  CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
2087 -  CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
2088 -  CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
2089 -  CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
2090 -  CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
2091 -  CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
2092 -  CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
2093 +  AV_CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
2094 +  AV_CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
2095 +  AV_CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
2096 +  AV_CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
2097 +  AV_CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
2098 +  AV_CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
2099 +  AV_CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
2100 +  AV_CH_FRONT_RIGHT_OF_CENTER,
2101 +        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
2102 +  AV_CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
2103 +  AV_CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
2104 +  AV_CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
2105 +  AV_CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_CENTER}, {
2106 +  AV_CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT}, {
2107 +  AV_CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER}, {
2108 +  AV_CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT}, {
2109 +  AV_CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT}, {
2110 +  AV_CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER}, {
2111 +  AV_CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT}, {
2112 +  AV_CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
2113 +  AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
2114  };
2115  
2116 +static guint64
2117 +gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos,
2118 +    gint channels)
2119 +{
2120 +  gint i, j;
2121 +  guint64 ret = 0;
2122 +  gint channels_found = 0;
2123 +
2124 +  if (!pos)
2125 +    return 0;
2126 +
2127 +  for (i = 0; i < channels; i++) {
2128 +    for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) {
2129 +      if (_ff_to_gst_layout[j].gst == pos[i]) {
2130 +        ret |= _ff_to_gst_layout[j].ff;
2131 +        channels_found++;
2132 +        break;
2133 +      }
2134 +    }
2135 +  }
2136 +
2137 +  if (channels_found != channels)
2138 +    return 0;
2139 +  return ret;
2140 +}
2141 +
2142  gboolean
2143 -gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
2144 +gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
2145      GstAudioChannelPosition * pos)
2146  {
2147 -  guint nchannels = 0, channels = context->channels;
2148 -  guint64 channel_layout = context->channel_layout;
2149 +  guint nchannels = 0;
2150    gboolean none_layout = FALSE;
2151  
2152    if (channel_layout == 0) {
2153 @@ -170,6 +159,52 @@
2154    return TRUE;
2155  }
2156  
2157 +static void
2158 +gst_ffmpeg_video_set_pix_fmts (GstCaps * caps, const enum AVPixelFormat *fmts)
2159 +{
2160 +  GValue va = { 0, };
2161 +  GValue v = { 0, };
2162 +  GstVideoFormat format;
2163 +
2164 +  if (!fmts || fmts[0] == -1) {
2165 +    gint i;
2166 +
2167 +    g_value_init (&va, GST_TYPE_LIST);
2168 +    g_value_init (&v, G_TYPE_STRING);
2169 +    for (i = 0; i <= PIX_FMT_NB; i++) {
2170 +      format = gst_ffmpeg_pixfmt_to_videoformat (i);
2171 +      if (format == GST_VIDEO_FORMAT_UNKNOWN)
2172 +        continue;
2173 +      g_value_set_string (&v, gst_video_format_to_string (format));
2174 +      gst_value_list_append_value (&va, &v);
2175 +    }
2176 +    gst_caps_set_value (caps, "format", &va);
2177 +    g_value_unset (&v);
2178 +    g_value_unset (&va);
2179 +    return;
2180 +  }
2181 +
2182 +  /* Only a single format */
2183 +  g_value_init (&va, GST_TYPE_LIST);
2184 +  g_value_init (&v, G_TYPE_STRING);
2185 +  while (*fmts != -1) {
2186 +    format = gst_ffmpeg_pixfmt_to_videoformat (*fmts);
2187 +    if (format != GST_VIDEO_FORMAT_UNKNOWN) {
2188 +      g_value_set_string (&v, gst_video_format_to_string (format));
2189 +      gst_value_list_append_value (&va, &v);
2190 +    }
2191 +    fmts++;
2192 +  }
2193 +  if (gst_value_list_get_size (&va) == 1) {
2194 +    /* The single value is still in v */
2195 +    gst_caps_set_value (caps, "format", &v);
2196 +  } else if (gst_value_list_get_size (&va) > 1) {
2197 +    gst_caps_set_value (caps, "format", &va);
2198 +  }
2199 +  g_value_unset (&v);
2200 +  g_value_unset (&va);
2201 +}
2202 +
2203  /* this macro makes a caps width fixed or unfixed width/height
2204   * properties depending on whether we've got a context.
2205   *
2206 @@ -179,10 +214,10 @@
2207   * but I'm too lazy today. Maybe later.
2208   */
2209  static GstCaps *
2210 -gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
2211 -    gboolean encode, const char *mimetype, const char *fieldname, ...)
2212 +gst_ff_vid_caps_new (AVCodecContext * context, AVCodec * codec,
2213 +    enum CodecID codec_id, gboolean encode, const char *mimetype,
2214 +    const char *fieldname, ...)
2215  {
2216 -  GstStructure *structure = NULL;
2217    GstCaps *caps = NULL;
2218    va_list var_args;
2219    gint i;
2220 @@ -252,32 +287,58 @@
2221        {
2222          static struct
2223          {
2224 -          guint32 csp;
2225 +          const gchar *csp;
2226            gint width, height;
2227            gint par_n, par_d;
2228            gint framerate_n, framerate_d;
2229          } profiles[] = {
2230            {
2231 -          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 10, 11, 30000, 1001}, {
2232 -          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 480, 40, 33, 30000, 1001}, {
2233 -          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 59, 54, 25, 1}, {
2234 -          GST_MAKE_FOURCC ('I', '4', '2', '0'), 720, 576, 118, 81, 25, 1}, {
2235 -          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 59, 54, 25, 1}, {
2236 -          GST_MAKE_FOURCC ('Y', '4', '1', 'B'), 720, 576, 118, 81, 25, 1}
2237 -        };
2238 +          "Y41B", 720, 480, 8, 9, 30000, 1001}, {
2239 +          "Y41B", 720, 480, 32, 27, 30000, 1001}, {
2240 +          "Y42B", 720, 480, 8, 9, 30000, 1001}, {
2241 +          "Y42B", 720, 480, 32, 27, 30000, 1001}, {
2242 +          "I420", 720, 576, 16, 15, 25, 1}, {
2243 +          "I420", 720, 576, 64, 45, 25, 1}, {
2244 +          "Y41B", 720, 576, 16, 15, 25, 1}, {
2245 +          "Y41B", 720, 576, 64, 45, 25, 1}, {
2246 +          "Y42B", 720, 576, 16, 15, 25, 1}, {
2247 +          "Y42B", 720, 576, 64, 45, 25, 1}, {
2248 +          "Y42B", 1280, 1080, 1, 1, 30000, 1001}, {
2249 +          "Y42B", 1280, 1080, 3, 2, 30000, 1001}, {
2250 +          "Y42B", 1440, 1080, 1, 1, 25, 1}, {
2251 +          "Y42B", 1440, 1080, 4, 3, 25, 1}, {
2252 +          "Y42B", 960, 720, 1, 1, 60000, 1001}, {
2253 +          "Y42B", 960, 720, 4, 3, 60000, 1001}, {
2254 +          "Y42B", 960, 720, 1, 1, 50, 1}, {
2255 +        "Y42B", 960, 720, 4, 3, 50, 1},};
2256          GstCaps *temp;
2257          gint n_sizes = G_N_ELEMENTS (profiles);
2258  
2259 -        caps = gst_caps_new_empty ();
2260 -        for (i = 0; i < n_sizes; i++) {
2261 -          temp = gst_caps_new_simple (mimetype,
2262 -              "width", G_TYPE_INT, profiles[i].width,
2263 -              "height", G_TYPE_INT, profiles[i].height,
2264 -              "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
2265 -              profiles[i].framerate_d, "pixel-aspect-ratio", GST_TYPE_FRACTION,
2266 -              profiles[i].par_n, profiles[i].par_d, NULL);
2267 +        if (strcmp (mimetype, "video/x-raw") == 0) {
2268 +          caps = gst_caps_new_empty ();
2269 +          for (i = 0; i < n_sizes; i++) {
2270 +            temp = gst_caps_new_simple (mimetype,
2271 +                "format", G_TYPE_STRING, profiles[i].csp,
2272 +                "width", G_TYPE_INT, profiles[i].width,
2273 +                "height", G_TYPE_INT, profiles[i].height,
2274 +                "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
2275 +                profiles[i].framerate_d, "pixel-aspect-ratio",
2276 +                GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
2277  
2278 -          gst_caps_append (caps, temp);
2279 +            gst_caps_append (caps, temp);
2280 +          }
2281 +        } else {
2282 +          caps = gst_caps_new_empty ();
2283 +          for (i = 0; i < n_sizes; i++) {
2284 +            temp = gst_caps_new_simple (mimetype,
2285 +                "width", G_TYPE_INT, profiles[i].width,
2286 +                "height", G_TYPE_INT, profiles[i].height,
2287 +                "framerate", GST_TYPE_FRACTION, profiles[i].framerate_n,
2288 +                profiles[i].framerate_d, "pixel-aspect-ratio",
2289 +                GST_TYPE_FRACTION, profiles[i].par_n, profiles[i].par_d, NULL);
2290 +
2291 +            gst_caps_append (caps, temp);
2292 +          }
2293          }
2294          break;
2295        }
2296 @@ -294,7 +355,40 @@
2297          break;
2298        }
2299        default:
2300 +      {
2301 +        if (codec && codec->supported_framerates
2302 +            && codec->supported_framerates[0].num != 0
2303 +            && codec->supported_framerates[0].den != 0) {
2304 +          GValue va = { 0, };
2305 +          GValue v = { 0, };
2306 +          const AVRational *rates = codec->supported_framerates;
2307 +
2308 +          if (rates[1].num == 0 && rates[1].den == 0) {
2309 +            caps =
2310 +                gst_caps_new_simple (mimetype, "framerate", GST_TYPE_FRACTION,
2311 +                rates[0].num, rates[0].den, NULL);
2312 +          } else {
2313 +            g_value_init (&va, GST_TYPE_LIST);
2314 +            g_value_init (&v, GST_TYPE_FRACTION);
2315 +
2316 +            while (rates->num != 0 && rates->den != 0) {
2317 +              gst_value_set_fraction (&v, rates->num, rates->den);
2318 +              gst_value_list_append_value (&va, &v);
2319 +              rates++;
2320 +            }
2321 +
2322 +            caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
2323 +            gst_caps_set_value (caps, "framerate", &va);
2324 +            g_value_unset (&va);
2325 +            g_value_unset (&v);
2326 +          }
2327 +
2328 +        } else {
2329 +          caps = gst_caps_new_empty_simple (mimetype);
2330 +        }
2331 +
2332          break;
2333 +      }
2334      }
2335    }
2336  
2337 @@ -302,27 +396,84 @@
2338     * default unfixed setting */
2339    if (!caps) {
2340      GST_DEBUG ("Creating default caps");
2341 -    caps = gst_caps_new_simple (mimetype, NULL, NULL, NULL);
2342 +    caps = gst_caps_new_empty_simple (mimetype);
2343    }
2344  
2345 -  for (i = 0; i < gst_caps_get_size (caps); i++) {
2346 -    va_start (var_args, fieldname);
2347 -    structure = gst_caps_get_structure (caps, i);
2348 -    gst_structure_set_valist (structure, fieldname, var_args);
2349 -    va_end (var_args);
2350 -  }
2351 +  va_start (var_args, fieldname);
2352 +  gst_caps_set_simple_valist (caps, fieldname, var_args);
2353 +  va_end (var_args);
2354  
2355    return caps;
2356  }
2357  
2358 +static gint
2359 +get_nbits_set (guint64 n)
2360 +{
2361 +  gint i, x;
2362 +
2363 +  x = 0;
2364 +  for (i = 0; i < 64; i++) {
2365 +    if ((n & (G_GUINT64_CONSTANT (1) << i)))
2366 +      x++;
2367 +  }
2368 +
2369 +  return x;
2370 +}
2371 +
2372 +static void
2373 +gst_ffmpeg_audio_set_sample_fmts (GstCaps * caps,
2374 +    const enum AVSampleFormat *fmts)
2375 +{
2376 +  GValue va = { 0, };
2377 +  GValue v = { 0, };
2378 +  GstAudioFormat format;
2379 +
2380 +  if (!fmts || fmts[0] == -1) {
2381 +    gint i;
2382 +
2383 +    g_value_init (&va, GST_TYPE_LIST);
2384 +    g_value_init (&v, G_TYPE_STRING);
2385 +    for (i = 0; i <= AV_SAMPLE_FMT_DBL; i++) {
2386 +      format = gst_ffmpeg_smpfmt_to_audioformat (i);
2387 +      if (format == GST_AUDIO_FORMAT_UNKNOWN)
2388 +        continue;
2389 +      g_value_set_string (&v, gst_audio_format_to_string (format));
2390 +      gst_value_list_append_value (&va, &v);
2391 +    }
2392 +    gst_caps_set_value (caps, "format", &va);
2393 +    g_value_unset (&v);
2394 +    g_value_unset (&va);
2395 +    return;
2396 +  }
2397 +
2398 +  g_value_init (&va, GST_TYPE_LIST);
2399 +  g_value_init (&v, G_TYPE_STRING);
2400 +  while (*fmts != -1) {
2401 +    format = gst_ffmpeg_smpfmt_to_audioformat (*fmts);
2402 +    if (format != GST_AUDIO_FORMAT_UNKNOWN) {
2403 +      g_value_set_string (&v, gst_audio_format_to_string (format));
2404 +      gst_value_list_append_value (&va, &v);
2405 +    }
2406 +    fmts++;
2407 +  }
2408 +  if (gst_value_list_get_size (&va) == 1) {
2409 +    /* The single value is still in v */
2410 +    gst_caps_set_value (caps, "format", &v);
2411 +  } else if (gst_value_list_get_size (&va) > 1) {
2412 +    gst_caps_set_value (caps, "format", &va);
2413 +  }
2414 +  g_value_unset (&v);
2415 +  g_value_unset (&va);
2416 +}
2417 +
2418  /* same for audio - now with channels/sample rate
2419   */
2420  static GstCaps *
2421 -gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
2422 -    gboolean encode, const char *mimetype, const char *fieldname, ...)
2423 +gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
2424 +    enum CodecID codec_id, gboolean encode, const char *mimetype,
2425 +    const char *fieldname, ...)
2426  {
2427    GstCaps *caps = NULL;
2428 -  GstStructure *structure = NULL;
2429    gint i;
2430    va_list var_args;
2431  
2432 @@ -334,7 +485,8 @@
2433          "rate", G_TYPE_INT, context->sample_rate,
2434          "channels", G_TYPE_INT, context->channels, NULL);
2435  
2436 -    if (gst_ffmpeg_channel_layout_to_gst (context, pos)) {
2437 +    if (gst_ffmpeg_channel_layout_to_gst (context->channel_layout,
2438 +            context->channels, pos)) {
2439        guint64 mask;
2440  
2441        if (gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
2442 @@ -422,10 +574,6 @@
2443          break;
2444      }
2445  
2446 -    /* TODO: handle context->channel_layouts here to set
2447 -     * the list of channel layouts supported by the encoder.
2448 -     * Unfortunately no encoder uses this yet....
2449 -     */
2450      /* regardless of encode/decode, open up channels if applicable */
2451      /* Until decoders/encoders expose the maximum number of channels
2452       * they support, we whitelist them here. */
2453 @@ -438,15 +586,40 @@
2454          break;
2455      }
2456  
2457 -    if (maxchannels == 1)
2458 -      caps = gst_caps_new_simple (mimetype,
2459 -          "channels", G_TYPE_INT, maxchannels, NULL);
2460 -    else
2461 -      caps = gst_caps_new_simple (mimetype,
2462 -          "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
2463 +    if (codec && codec->channel_layouts) {
2464 +      const uint64_t *layouts = codec->channel_layouts;
2465 +      GstAudioChannelPosition pos[64];
2466 +
2467 +      caps = gst_caps_new_empty ();
2468 +      while (*layouts) {
2469 +        gint nbits_set = get_nbits_set (*layouts);
2470 +
2471 +        if (gst_ffmpeg_channel_layout_to_gst (*layouts, nbits_set, pos)) {
2472 +          guint64 mask;
2473 +
2474 +          if (gst_audio_channel_positions_to_mask (pos, nbits_set, FALSE,
2475 +                  &mask)) {
2476 +            GstCaps *tmp =
2477 +                gst_caps_new_simple (mimetype, "channel-mask", GST_TYPE_BITMASK,
2478 +                mask,
2479 +                "channels", G_TYPE_INT, nbits_set, NULL);
2480 +
2481 +            gst_caps_append (caps, tmp);
2482 +          }
2483 +        }
2484 +        layouts++;
2485 +      }
2486 +    } else {
2487 +      if (maxchannels == 1)
2488 +        caps = gst_caps_new_simple (mimetype,
2489 +            "channels", G_TYPE_INT, maxchannels, NULL);
2490 +      else
2491 +        caps = gst_caps_new_simple (mimetype,
2492 +            "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
2493 +    }
2494 +
2495      if (n_rates) {
2496        GValue list = { 0, };
2497 -      GstStructure *structure;
2498  
2499        g_value_init (&list, GST_TYPE_LIST);
2500        for (i = 0; i < n_rates; i++) {
2501 @@ -457,21 +630,41 @@
2502          gst_value_list_append_value (&list, &v);
2503          g_value_unset (&v);
2504        }
2505 -      structure = gst_caps_get_structure (caps, 0);
2506 -      gst_structure_set_value (structure, "rate", &list);
2507 +      gst_caps_set_value (caps, "rate", &list);
2508        g_value_unset (&list);
2509 -    } else
2510 +    } else if (codec && codec->supported_samplerates
2511 +        && codec->supported_samplerates[0]) {
2512 +      GValue va = { 0, };
2513 +      GValue v = { 0, };
2514 +
2515 +      if (!codec->supported_samplerates[1]) {
2516 +        gst_caps_set_simple (caps, "rate", G_TYPE_INT,
2517 +            codec->supported_samplerates[0], NULL);
2518 +      } else {
2519 +        const int *rates = codec->supported_samplerates;
2520 +
2521 +        g_value_init (&va, GST_TYPE_LIST);
2522 +        g_value_init (&v, G_TYPE_INT);
2523 +
2524 +        while (*rates) {
2525 +          g_value_set_int (&v, *rates);
2526 +          gst_value_list_append_value (&va, &v);
2527 +          rates++;
2528 +        }
2529 +        gst_caps_set_value (caps, "rate", &va);
2530 +        g_value_unset (&va);
2531 +        g_value_unset (&v);
2532 +      }
2533 +    } else {
2534        gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
2535 +    }
2536    } else {
2537      caps = gst_caps_new_empty_simple (mimetype);
2538    }
2539  
2540 -  for (i = 0; i < gst_caps_get_size (caps); i++) {
2541 -    va_start (var_args, fieldname);
2542 -    structure = gst_caps_get_structure (caps, i);
2543 -    gst_structure_set_valist (structure, fieldname, var_args);
2544 -    va_end (var_args);
2545 -  }
2546 +  va_start (var_args, fieldname);
2547 +  gst_caps_set_simple_valist (caps, fieldname, var_args);
2548 +  va_end (var_args);
2549  
2550    return caps;
2551  }
2552 @@ -504,7 +697,7 @@
2553    switch (codec_id) {
2554      case CODEC_ID_MPEG1VIDEO:
2555        /* FIXME: bitrate */
2556 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
2557 +      caps = gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
2558            "mpegversion", G_TYPE_INT, 1,
2559            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
2560        break;
2561 @@ -512,9 +705,10 @@
2562      case CODEC_ID_MPEG2VIDEO:
2563        if (encode) {
2564          /* FIXME: bitrate */
2565 -        caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
2566 -            "mpegversion", G_TYPE_INT, 2,
2567 -            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
2568 +        caps =
2569 +            gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
2570 +            "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, FALSE,
2571 +            NULL);
2572        } else {
2573          /* decode both MPEG-1 and MPEG-2; width/height/fps are all in
2574           * the MPEG video stream headers, so may be omitted from caps. */
2575 @@ -530,23 +724,25 @@
2576  
2577      case CODEC_ID_H263:
2578        if (encode) {
2579 -        caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
2580 -            "variant", G_TYPE_STRING, "itu",
2581 -            "h263version", G_TYPE_STRING, "h263", NULL);
2582 +        caps =
2583 +            gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2584 +            "video/x-h263", "variant", G_TYPE_STRING, "itu", "h263version",
2585 +            G_TYPE_STRING, "h263", NULL);
2586        } else {
2587          /* don't pass codec_id, we can decode other variants with the H263
2588           * decoder that don't have specific size requirements
2589           */
2590          caps =
2591 -            gst_ff_vid_caps_new (context, CODEC_ID_NONE, encode, "video/x-h263",
2592 -            "variant", G_TYPE_STRING, "itu", NULL);
2593 +            gst_ff_vid_caps_new (context, NULL, CODEC_ID_NONE, encode,
2594 +            "video/x-h263", "variant", G_TYPE_STRING, "itu", NULL);
2595        }
2596        break;
2597  
2598      case CODEC_ID_H263P:
2599 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h263",
2600 -          "variant", G_TYPE_STRING, "itu",
2601 -          "h263version", G_TYPE_STRING, "h263p", NULL);
2602 +      caps =
2603 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h263",
2604 +          "variant", G_TYPE_STRING, "itu", "h263version", G_TYPE_STRING,
2605 +          "h263p", NULL);
2606        if (encode && context) {
2607  
2608          gst_caps_set_simple (caps,
2609 @@ -560,13 +756,14 @@
2610  
2611      case CODEC_ID_H263I:
2612        caps =
2613 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-intel-h263",
2614 -          "variant", G_TYPE_STRING, "intel", NULL);
2615 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2616 +          "video/x-intel-h263", "variant", G_TYPE_STRING, "intel", NULL);
2617        break;
2618  
2619      case CODEC_ID_H261:
2620        caps =
2621 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h261", NULL);
2622 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h261",
2623 +          NULL);
2624        break;
2625  
2626      case CODEC_ID_RV10:
2627 @@ -593,7 +790,7 @@
2628  
2629        /* FIXME: context->sub_id must be filled in during decoding */
2630        caps =
2631 -          gst_ff_vid_caps_new (context, codec_id, encode,
2632 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2633            "video/x-pn-realvideo", "systemstream", G_TYPE_BOOLEAN, FALSE,
2634            "rmversion", G_TYPE_INT, version, NULL);
2635        if (context) {
2636 @@ -609,20 +806,21 @@
2637  
2638      case CODEC_ID_MP1:
2639        /* FIXME: bitrate */
2640 -      caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
2641 +      caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
2642            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
2643        break;
2644  
2645      case CODEC_ID_MP2:
2646        /* FIXME: bitrate */
2647 -      caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
2648 +      caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
2649            "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
2650        break;
2651  
2652      case CODEC_ID_MP3:
2653        if (encode) {
2654          /* FIXME: bitrate */
2655 -        caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
2656 +        caps =
2657 +            gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
2658              "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
2659        } else {
2660          /* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
2661 @@ -635,14 +833,14 @@
2662  
2663      case CODEC_ID_MUSEPACK7:
2664        caps =
2665 -          gst_ff_aud_caps_new (context, codec_id, encode,
2666 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2667            "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
2668            NULL);
2669        break;
2670  
2671      case CODEC_ID_MUSEPACK8:
2672        caps =
2673 -          gst_ff_aud_caps_new (context, codec_id, encode,
2674 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2675            "audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
2676            NULL);
2677        break;
2678 @@ -650,41 +848,44 @@
2679      case CODEC_ID_AC3:
2680        /* FIXME: bitrate */
2681        caps =
2682 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-ac3", NULL);
2683 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-ac3",
2684 +          NULL);
2685        break;
2686  
2687      case CODEC_ID_EAC3:
2688        /* FIXME: bitrate */
2689        caps =
2690 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-eac3", NULL);
2691 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-eac3",
2692 +          NULL);
2693        break;
2694  
2695      case CODEC_ID_TRUEHD:
2696        caps =
2697 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-true-hd",
2698 -          NULL);
2699 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2700 +          "audio/x-true-hd", NULL);
2701        break;
2702  
2703      case CODEC_ID_ATRAC1:
2704        caps =
2705 -          gst_ff_aud_caps_new (context, codec_id, encode,
2706 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2707            "audio/x-vnd.sony.atrac1", NULL);
2708        break;
2709  
2710      case CODEC_ID_ATRAC3:
2711        caps =
2712 -          gst_ff_aud_caps_new (context, codec_id, encode,
2713 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2714            "audio/x-vnd.sony.atrac3", NULL);
2715        break;
2716  
2717      case CODEC_ID_DTS:
2718        caps =
2719 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dts", NULL);
2720 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dts",
2721 +          NULL);
2722        break;
2723  
2724      case CODEC_ID_APE:
2725        caps =
2726 -          gst_ff_aud_caps_new (context, codec_id, encode,
2727 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode,
2728            "audio/x-ffmpeg-parsed-ape", NULL);
2729        if (context) {
2730          gst_caps_set_simple (caps,
2731 @@ -694,12 +895,14 @@
2732  
2733      case CODEC_ID_MLP:
2734        caps =
2735 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mlp", NULL);
2736 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mlp",
2737 +          NULL);
2738        break;
2739  
2740      case CODEC_ID_IMC:
2741        caps =
2742 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-imc", NULL);
2743 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-imc",
2744 +          NULL);
2745        break;
2746  
2747        /* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
2748 @@ -710,18 +913,20 @@
2749      case CODEC_ID_MJPEG:
2750      case CODEC_ID_LJPEG:
2751        caps =
2752 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/jpeg", NULL);
2753 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/jpeg",
2754 +          NULL);
2755        break;
2756  
2757      case CODEC_ID_SP5X:
2758        caps =
2759 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/sp5x", NULL);
2760 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/sp5x",
2761 +          NULL);
2762        break;
2763  
2764      case CODEC_ID_MJPEGB:
2765        caps =
2766 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mjpeg-b",
2767 -          NULL);
2768 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2769 +          "video/x-mjpeg-b", NULL);
2770        break;
2771  
2772      case CODEC_ID_MPEG4:
2773 @@ -731,41 +936,42 @@
2774          switch (context->codec_tag) {
2775            case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
2776              caps =
2777 -                gst_ff_vid_caps_new (context, codec_id, encode, "video/x-divx",
2778 -                "divxversion", G_TYPE_INT, 5, NULL);
2779 +                gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2780 +                "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL);
2781              break;
2782            case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
2783            default:
2784              /* FIXME: bitrate */
2785 -            caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
2786 -                "systemstream", G_TYPE_BOOLEAN, FALSE,
2787 +            caps =
2788 +                gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2789 +                "video/mpeg", "systemstream", G_TYPE_BOOLEAN, FALSE,
2790                  "mpegversion", G_TYPE_INT, 4, NULL);
2791              break;
2792          }
2793        } else {
2794          /* The trick here is to separate xvid, divx, mpeg4, 3ivx et al */
2795 -        caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/mpeg",
2796 -            "mpegversion", G_TYPE_INT, 4,
2797 -            "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
2798 +        caps =
2799 +            gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/mpeg",
2800 +            "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE,
2801 +            NULL);
2802          if (encode) {
2803 -          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
2804 -                  "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
2805 +          gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
2806 +                  encode, "video/x-divx", "divxversion", G_TYPE_INT, 5, NULL));
2807          } else {
2808 -          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
2809 -                  "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5,
2810 -                  NULL));
2811 -          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
2812 -                  "video/x-xvid", NULL));
2813 -          gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
2814 -                  "video/x-3ivx", NULL));
2815 +          gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
2816 +                  encode, "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4,
2817 +                  5, NULL));
2818 +          gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
2819 +                  encode, "video/x-xvid", NULL));
2820 +          gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
2821 +                  encode, "video/x-3ivx", NULL));
2822          }
2823        }
2824        break;
2825  
2826      case CODEC_ID_RAWVIDEO:
2827        caps =
2828 -          gst_ffmpeg_codectype_to_caps (AVMEDIA_TYPE_VIDEO, context, codec_id,
2829 -          encode);
2830 +          gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
2831        break;
2832  
2833      case CODEC_ID_MSMPEG4V1:
2834 @@ -775,11 +981,12 @@
2835        gint version = 41 + codec_id - CODEC_ID_MSMPEG4V1;
2836  
2837        /* encode-FIXME: bitrate */
2838 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-msmpeg",
2839 -          "msmpegversion", G_TYPE_INT, version, NULL);
2840 +      caps =
2841 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2842 +          "video/x-msmpeg", "msmpegversion", G_TYPE_INT, version, NULL);
2843        if (!encode && codec_id == CODEC_ID_MSMPEG4V3) {
2844 -        gst_caps_append (caps, gst_ff_vid_caps_new (context, codec_id, encode,
2845 -                "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
2846 +        gst_caps_append (caps, gst_ff_vid_caps_new (context, NULL, codec_id,
2847 +                encode, "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
2848        }
2849      }
2850        break;
2851 @@ -789,30 +996,34 @@
2852      {
2853        gint version = (codec_id == CODEC_ID_WMV1) ? 1 : 2;
2854  
2855 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
2856 +      caps =
2857 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
2858            "wmvversion", G_TYPE_INT, version, NULL);
2859      }
2860        break;
2861  
2862      case CODEC_ID_FLV1:
2863        caps =
2864 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-flash-video",
2865 -          "flvversion", G_TYPE_INT, 1, NULL);
2866 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2867 +          "video/x-flash-video", "flvversion", G_TYPE_INT, 1, NULL);
2868        break;
2869  
2870      case CODEC_ID_SVQ1:
2871 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
2872 +      caps =
2873 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
2874            "svqversion", G_TYPE_INT, 1, NULL);
2875        break;
2876  
2877      case CODEC_ID_SVQ3:
2878 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-svq",
2879 +      caps =
2880 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-svq",
2881            "svqversion", G_TYPE_INT, 3, NULL);
2882        break;
2883  
2884      case CODEC_ID_DVAUDIO:
2885        caps =
2886 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dv", NULL);
2887 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dv",
2888 +          NULL);
2889        break;
2890  
2891      case CODEC_ID_DVVIDEO:
2892 @@ -846,11 +1057,13 @@
2893              format = "I420";
2894              break;
2895          }
2896 -        caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
2897 -            "systemstream", G_TYPE_BOOLEAN, FALSE,
2898 -            "format", G_TYPE_STRING, format, NULL);
2899 +        caps =
2900 +            gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
2901 +            "systemstream", G_TYPE_BOOLEAN, FALSE, "format", G_TYPE_STRING,
2902 +            format, NULL);
2903        } else {
2904 -        caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-dv",
2905 +        caps =
2906 +            gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-dv",
2907              "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
2908        }
2909      }
2910 @@ -862,21 +1075,24 @@
2911        gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
2912  
2913        if (context) {
2914 -        caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
2915 -            "wmaversion", G_TYPE_INT, version,
2916 -            "block_align", G_TYPE_INT, context->block_align,
2917 -            "bitrate", G_TYPE_INT, context->bit_rate, NULL);
2918 +        caps =
2919 +            gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
2920 +            "wmaversion", G_TYPE_INT, version, "block_align", G_TYPE_INT,
2921 +            context->block_align, "bitrate", G_TYPE_INT, context->bit_rate,
2922 +            NULL);
2923        } else {
2924 -        caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
2925 -            "wmaversion", G_TYPE_INT, version,
2926 -            "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
2927 -            "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
2928 +        caps =
2929 +            gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
2930 +            "wmaversion", G_TYPE_INT, version, "block_align",
2931 +            GST_TYPE_INT_RANGE, 0, G_MAXINT, "bitrate", GST_TYPE_INT_RANGE, 0,
2932 +            G_MAXINT, NULL);
2933        }
2934      }
2935        break;
2936      case CODEC_ID_WMAPRO:
2937      {
2938 -      caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
2939 +      caps =
2940 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
2941            "wmaversion", G_TYPE_INT, 3, NULL);
2942        break;
2943      }
2944 @@ -884,7 +1100,8 @@
2945      case CODEC_ID_WMAVOICE:
2946      {
2947        caps =
2948 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wms", NULL);
2949 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wms",
2950 +          NULL);
2951        break;
2952      }
2953  
2954 @@ -893,15 +1110,16 @@
2955      {
2956        gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
2957  
2958 -      caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mace",
2959 +      caps =
2960 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mace",
2961            "maceversion", G_TYPE_INT, version, NULL);
2962      }
2963        break;
2964  
2965      case CODEC_ID_HUFFYUV:
2966        caps =
2967 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-huffyuv",
2968 -          NULL);
2969 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2970 +          "video/x-huffyuv", NULL);
2971        if (context) {
2972          gst_caps_set_simple (caps,
2973              "bpp", G_TYPE_INT, context->bits_per_coded_sample, NULL);
2974 @@ -910,84 +1128,93 @@
2975  
2976      case CODEC_ID_CYUV:
2977        caps =
2978 -          gst_ff_vid_caps_new (context, codec_id, encode,
2979 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
2980            "video/x-compressed-yuv", NULL);
2981        break;
2982  
2983      case CODEC_ID_H264:
2984        caps =
2985 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-h264",
2986 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-h264",
2987            "alignment", G_TYPE_STRING, "au", NULL);
2988        break;
2989  
2990      case CODEC_ID_INDEO5:
2991 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
2992 +      caps =
2993 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
2994            "indeoversion", G_TYPE_INT, 5, NULL);
2995        break;
2996  
2997      case CODEC_ID_INDEO4:
2998 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
2999 +      caps =
3000 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
3001            "indeoversion", G_TYPE_INT, 4, NULL);
3002        break;
3003  
3004      case CODEC_ID_INDEO3:
3005 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
3006 +      caps =
3007 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
3008            "indeoversion", G_TYPE_INT, 3, NULL);
3009        break;
3010  
3011      case CODEC_ID_INDEO2:
3012 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-indeo",
3013 +      caps =
3014 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-indeo",
3015            "indeoversion", G_TYPE_INT, 2, NULL);
3016        break;
3017  
3018      case CODEC_ID_FLASHSV:
3019        caps =
3020 -          gst_ff_vid_caps_new (context, codec_id, encode,
3021 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3022            "video/x-flash-screen", NULL);
3023        break;
3024  
3025      case CODEC_ID_VP3:
3026        caps =
3027 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp3", NULL);
3028 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp3",
3029 +          NULL);
3030        break;
3031  
3032      case CODEC_ID_VP5:
3033        caps =
3034 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp5", NULL);
3035 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp5",
3036 +          NULL);
3037        break;
3038  
3039      case CODEC_ID_VP6:
3040        caps =
3041 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6", NULL);
3042 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp6",
3043 +          NULL);
3044        break;
3045  
3046      case CODEC_ID_VP6F:
3047        caps =
3048 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-flash",
3049 -          NULL);
3050 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3051 +          "video/x-vp6-flash", NULL);
3052        break;
3053  
3054      case CODEC_ID_VP6A:
3055        caps =
3056 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp6-alpha",
3057 -          NULL);
3058 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3059 +          "video/x-vp6-alpha", NULL);
3060        break;
3061  
3062      case CODEC_ID_VP8:
3063        caps =
3064 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-vp8", NULL);
3065 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-vp8",
3066 +          NULL);
3067        break;
3068  
3069      case CODEC_ID_THEORA:
3070        caps =
3071 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-theora",
3072 -          NULL);
3073 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3074 +          "video/x-theora", NULL);
3075        break;
3076  
3077      case CODEC_ID_AAC:
3078      {
3079        caps =
3080 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg", NULL);
3081 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
3082 +          NULL);
3083  
3084        if (!encode) {
3085          GValue arr = { 0, };
3086 @@ -1029,45 +1256,50 @@
3087        break;
3088      }
3089      case CODEC_ID_AAC_LATM:    /* LATM/LOAS AAC syntax */
3090 -      caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
3091 +      caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
3092            "mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "loas",
3093            NULL);
3094        break;
3095  
3096      case CODEC_ID_ASV1:
3097 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
3098 +      caps =
3099 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
3100            "asusversion", G_TYPE_INT, 1, NULL);
3101        break;
3102      case CODEC_ID_ASV2:
3103 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-asus",
3104 +      caps =
3105 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-asus",
3106            "asusversion", G_TYPE_INT, 2, NULL);
3107        break;
3108  
3109      case CODEC_ID_FFV1:
3110 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ffv",
3111 +      caps =
3112 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-ffv",
3113            "ffvversion", G_TYPE_INT, 1, NULL);
3114        break;
3115  
3116      case CODEC_ID_4XM:
3117        caps =
3118 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-4xm", NULL);
3119 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-4xm",
3120 +          NULL);
3121        break;
3122  
3123      case CODEC_ID_XAN_WC3:
3124      case CODEC_ID_XAN_WC4:
3125 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-xan",
3126 +      caps =
3127 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-xan",
3128            "wcversion", G_TYPE_INT, 3 - CODEC_ID_XAN_WC3 + codec_id, NULL);
3129        break;
3130  
3131      case CODEC_ID_CLJR:
3132        caps =
3133 -          gst_ff_vid_caps_new (context, codec_id, encode,
3134 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3135            "video/x-cirrus-logic-accupak", NULL);
3136        break;
3137  
3138      case CODEC_ID_FRAPS:
3139        caps =
3140 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-fraps",
3141 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-fraps",
3142            NULL);
3143        break;
3144  
3145 @@ -1078,26 +1310,28 @@
3146        break;
3147  
3148      case CODEC_ID_VCR1:
3149 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ati-vcr",
3150 -          "vcrversion", G_TYPE_INT, 1, NULL);
3151 +      caps =
3152 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3153 +          "video/x-ati-vcr", "vcrversion", G_TYPE_INT, 1, NULL);
3154        break;
3155  
3156      case CODEC_ID_RPZA:
3157        caps =
3158 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-apple-video",
3159 -          NULL);
3160 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3161 +          "video/x-apple-video", NULL);
3162        break;
3163  
3164      case CODEC_ID_CINEPAK:
3165        caps =
3166 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-cinepak",
3167 -          NULL);
3168 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3169 +          "video/x-cinepak", NULL);
3170        break;
3171  
3172        /* WS_VQA belogns here (order) */
3173  
3174      case CODEC_ID_MSRLE:
3175 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
3176 +      caps =
3177 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
3178            "layout", G_TYPE_STRING, "microsoft", NULL);
3179        if (context) {
3180          gst_caps_set_simple (caps,
3181 @@ -1108,7 +1342,8 @@
3182        break;
3183  
3184      case CODEC_ID_QTRLE:
3185 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-rle",
3186 +      caps =
3187 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-rle",
3188            "layout", G_TYPE_STRING, "quicktime", NULL);
3189        if (context) {
3190          gst_caps_set_simple (caps,
3191 @@ -1120,54 +1355,59 @@
3192  
3193      case CODEC_ID_MSVIDEO1:
3194        caps =
3195 -          gst_ff_vid_caps_new (context, codec_id, encode,
3196 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3197            "video/x-msvideocodec", "msvideoversion", G_TYPE_INT, 1, NULL);
3198        break;
3199  
3200      case CODEC_ID_WMV3:
3201 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
3202 +      caps =
3203 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
3204            "wmvversion", G_TYPE_INT, 3, NULL);
3205        break;
3206      case CODEC_ID_VC1:
3207 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "video/x-wmv",
3208 +      caps =
3209 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-wmv",
3210            "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
3211        break;
3212      case CODEC_ID_QDM2:
3213        caps =
3214 -          gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-qdm2", NULL);
3215 +          gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-qdm2",
3216 +          NULL);
3217        break;
3218  
3219      case CODEC_ID_MSZH:
3220        caps =
3221 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-mszh", NULL);
3222 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-mszh",
3223 +          NULL);
3224        break;
3225  
3226      case CODEC_ID_ZLIB:
3227        caps =
3228 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-zlib", NULL);
3229 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-zlib",
3230 +          NULL);
3231        break;
3232  
3233      case CODEC_ID_TRUEMOTION1:
3234        caps =
3235 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
3236 -          "trueversion", G_TYPE_INT, 1, NULL);
3237 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3238 +          "video/x-truemotion", "trueversion", G_TYPE_INT, 1, NULL);
3239        break;
3240      case CODEC_ID_TRUEMOTION2:
3241        caps =
3242 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-truemotion",
3243 -          "trueversion", G_TYPE_INT, 2, NULL);
3244 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3245 +          "video/x-truemotion", "trueversion", G_TYPE_INT, 2, NULL);
3246        break;
3247  
3248      case CODEC_ID_ULTI:
3249        caps =
3250 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-ultimotion",
3251 -          NULL);
3252 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3253 +          "video/x-ultimotion", NULL);
3254        break;
3255  
3256      case CODEC_ID_TSCC:
3257        caps =
3258 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-camtasia",
3259 -          NULL);
3260 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3261 +          "video/x-camtasia", NULL);
3262        if (context) {
3263          gst_caps_set_simple (caps,
3264              "depth", G_TYPE_INT, (gint) context->bits_per_coded_sample, NULL);
3265 @@ -1178,142 +1418,164 @@
3266  
3267      case CODEC_ID_KMVC:
3268        caps =
3269 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-kmvc", NULL);
3270 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-kmvc",
3271 +          NULL);
3272        break;
3273  
3274      case CODEC_ID_NUV:
3275        caps =
3276 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-nuv", NULL);
3277 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-nuv",
3278 +          NULL);
3279        break;
3280  
3281      case CODEC_ID_GIF:
3282 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/gif", NULL);
3283 +      caps =
3284 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/gif",
3285 +          NULL);
3286        break;
3287  
3288      case CODEC_ID_PNG:
3289 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/png", NULL);
3290 +      caps =
3291 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/png",
3292 +          NULL);
3293        break;
3294  
3295      case CODEC_ID_PPM:
3296 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/ppm", NULL);
3297 +      caps =
3298 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/ppm",
3299 +          NULL);
3300        break;
3301  
3302      case CODEC_ID_PBM:
3303 -      caps = gst_ff_vid_caps_new (context, codec_id, encode, "image/pbm", NULL);
3304 +      caps =
3305 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/pbm",
3306 +          NULL);
3307        break;
3308  
3309      case CODEC_ID_PAM:
3310        caps =
3311 -          gst_ff_vid_caps_new (context, codec_id, encode,
3312 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3313            "image/x-portable-anymap", NULL);
3314        break;
3315  
3316      case CODEC_ID_PGM:
3317        caps =
3318 -          gst_ff_vid_caps_new (context, codec_id, encode,
3319 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3320            "image/x-portable-graymap", NULL);
3321        break;
3322  
3323      case CODEC_ID_PCX:
3324        caps =
3325 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/x-pcx", NULL);
3326 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-pcx",
3327 +          NULL);
3328        break;
3329  
3330      case CODEC_ID_SGI:
3331        caps =
3332 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sgi", NULL);
3333 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-sgi",
3334 +          NULL);
3335        break;
3336  
3337      case CODEC_ID_TARGA:
3338        caps =
3339 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/x-tga", NULL);
3340 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/x-tga",
3341 +          NULL);
3342        break;
3343  
3344      case CODEC_ID_TIFF:
3345        caps =
3346 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/tiff", NULL);
3347 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "image/tiff",
3348 +          NULL);
3349        break;
3350  
3351      case CODEC_ID_SUNRAST:
3352        caps =
3353 -          gst_ff_vid_caps_new (context, codec_id, encode, "image/x-sun-raster",
3354 -          NULL);
3355 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode,
3356 +          "image/x-sun-raster", NULL);
3357        break;
3358  
3359      case CODEC_ID_SMC:
3360        caps =
3361 -          gst_ff_vid_caps_new (context, codec_id, encode, "video/x-smc", NULL);
3362 +          gst_ff_vid_caps_new (context, NULL, codec_id, encode, "video/x-smc",
3363 +          NULL);
3364        break;
3365