Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / gst / ffmpegcolorspace / gstffmpegcodecmap.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * This file:
4  * Copyright (c) 2002-2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include <gst/gst.h>
29
30 #include "avcodec.h"
31 #include "gstffmpegcodecmap.h"
32
33 GST_DEBUG_CATEGORY_EXTERN (ffmpegcolorspace_debug);
34 #define GST_CAT_DEFAULT ffmpegcolorspace_debug
35
36 static GstCaps *
37 gst_ff_vid_caps_new (AVCodecContext * context,
38     const char *mimetype, const char *fieldname, ...)
39     G_GNUC_NULL_TERMINATED;
40      static GstCaps *gst_ff_aud_caps_new (AVCodecContext * context,
41     const char *mimetype, const char *fieldname, ...) G_GNUC_NULL_TERMINATED;
42
43 /*
44  * Read a palette from a caps.
45  */
46
47      static void
48          gst_ffmpeg_get_palette (const GstCaps * caps, AVCodecContext * context)
49 {
50   GstStructure *str = gst_caps_get_structure (caps, 0);
51   const GValue *palette_v;
52
53   /* do we have a palette? */
54   if ((palette_v = gst_structure_get_value (str, "palette_data")) && context) {
55     const GstBuffer *palette;
56
57     palette = gst_value_get_buffer (palette_v);
58     if (palette && GST_BUFFER_SIZE (palette) >= 256 * 4) {
59       if (context->palctrl)
60         av_free (context->palctrl);
61       context->palctrl = av_malloc (sizeof (AVPaletteControl));
62       context->palctrl->palette_changed = 1;
63       memcpy (context->palctrl->palette, GST_BUFFER_DATA (palette),
64           AVPALETTE_SIZE);
65     }
66   }
67 }
68
69 static void
70 gst_ffmpeg_set_palette (GstCaps * caps, AVCodecContext * context)
71 {
72   if (context->palctrl) {
73     GstBuffer *palette = gst_buffer_new_and_alloc (256 * 4);
74
75     memcpy (GST_BUFFER_DATA (palette), context->palctrl->palette,
76         AVPALETTE_SIZE);
77     gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, palette, NULL);
78     gst_buffer_unref (palette);
79   }
80 }
81
82 /* this function creates caps with fixed or unfixed width/height
83  * properties depending on whether we've got a context.
84  *
85  * See below for why we use this.
86  *
87  * We should actually do this stuff at the end, like in riff-media.c,
88  * but I'm too lazy today. Maybe later.
89  */
90
91 static GstCaps *
92 gst_ff_vid_caps_new (AVCodecContext * context, const char *mimetype,
93     const char *fieldname, ...)
94 {
95   GstStructure *structure = NULL;
96   GstCaps *caps = NULL;
97   va_list var_args;
98
99   if (context != NULL) {
100     caps = gst_caps_new_simple (mimetype,
101         "width", G_TYPE_INT, context->width,
102         "height", G_TYPE_INT, context->height,
103         "framerate", GST_TYPE_FRACTION,
104         (gint) context->frame_rate, (gint) context->frame_rate_base, NULL);
105   } else {
106     caps = gst_caps_new_simple (mimetype,
107         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
108         "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
109         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
110   }
111
112   structure = gst_caps_get_structure (caps, 0);
113
114   if (structure) {
115     va_start (var_args, fieldname);
116     gst_structure_set_valist (structure, fieldname, var_args);
117     va_end (var_args);
118   }
119
120   return caps;
121 }
122
123 /* same for audio - now with channels/sample rate
124  */
125
126 static GstCaps *
127 gst_ff_aud_caps_new (AVCodecContext * context, const char *mimetype,
128     const char *fieldname, ...)
129 {
130   GstCaps *caps = NULL;
131   GstStructure *structure = NULL;
132   va_list var_args;
133
134   if (context != NULL) {
135     caps = gst_caps_new_simple (mimetype,
136         "rate", G_TYPE_INT, context->sample_rate,
137         "channels", G_TYPE_INT, context->channels, NULL);
138   } else {
139     caps = gst_caps_new_simple (mimetype, NULL);
140   }
141
142   structure = gst_caps_get_structure (caps, 0);
143
144   if (structure) {
145     va_start (var_args, fieldname);
146     gst_structure_set_valist (structure, fieldname, var_args);
147     va_end (var_args);
148   }
149
150   return caps;
151 }
152
153 /* Convert a FFMPEG Pixel Format and optional AVCodecContext
154  * to a GstCaps. If the context is ommitted, no fixed values
155  * for video/audio size will be included in the GstCaps
156  *
157  * See below for usefulness
158  */
159
160 static GstCaps *
161 gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
162 {
163   GstCaps *caps = NULL;
164
165   int bpp = 0, depth = 0, endianness = 0;
166   gulong g_mask = 0, r_mask = 0, b_mask = 0, a_mask = 0;
167   guint32 fmt = 0;
168
169   switch (pix_fmt) {
170     case PIX_FMT_YUV420P:
171       fmt = GST_MAKE_FOURCC ('I', '4', '2', '0');
172       break;
173     case PIX_FMT_YUVA420P:
174       fmt = GST_MAKE_FOURCC ('A', '4', '2', '0');
175       break;
176     case PIX_FMT_NV12:
177       fmt = GST_MAKE_FOURCC ('N', 'V', '1', '2');
178       break;
179     case PIX_FMT_NV21:
180       fmt = GST_MAKE_FOURCC ('N', 'V', '2', '1');
181       break;
182     case PIX_FMT_YVU420P:
183       fmt = GST_MAKE_FOURCC ('Y', 'V', '1', '2');
184       break;
185     case PIX_FMT_YUV422:
186       fmt = GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
187       break;
188     case PIX_FMT_UYVY422:
189       fmt = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
190       break;
191     case PIX_FMT_YVYU422:
192       fmt = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
193       break;
194     case PIX_FMT_UYVY411:
195       fmt = GST_MAKE_FOURCC ('I', 'Y', 'U', '1');
196       break;
197     case PIX_FMT_RGB24:
198       bpp = depth = 24;
199       endianness = G_BIG_ENDIAN;
200       r_mask = 0xff0000;
201       g_mask = 0x00ff00;
202       b_mask = 0x0000ff;
203       break;
204     case PIX_FMT_BGR24:
205       bpp = depth = 24;
206       endianness = G_BIG_ENDIAN;
207       r_mask = 0x0000ff;
208       g_mask = 0x00ff00;
209       b_mask = 0xff0000;
210       break;
211     case PIX_FMT_YUV422P:
212       fmt = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
213       break;
214     case PIX_FMT_YUV444P:
215       fmt = GST_MAKE_FOURCC ('Y', '4', '4', '4');
216       break;
217     case PIX_FMT_RGB32:
218       bpp = 32;
219       depth = 24;
220       endianness = G_BIG_ENDIAN;
221 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
222       r_mask = 0x00ff0000;
223       g_mask = 0x0000ff00;
224       b_mask = 0x000000ff;
225 #else
226       r_mask = 0x0000ff00;
227       g_mask = 0x00ff0000;
228       b_mask = 0xff000000;
229 #endif
230       break;
231     case PIX_FMT_BGR32:
232       bpp = 32;
233       depth = 24;
234       endianness = G_BIG_ENDIAN;
235 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
236       r_mask = 0x0000ff00;
237       g_mask = 0x00ff0000;
238       b_mask = 0xff000000;
239 #else
240       r_mask = 0x00ff0000;
241       g_mask = 0x0000ff00;
242       b_mask = 0x000000ff;
243 #endif
244       break;
245     case PIX_FMT_xRGB32:
246       bpp = 32;
247       depth = 24;
248       endianness = G_BIG_ENDIAN;
249 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
250       r_mask = 0xff000000;
251       g_mask = 0x00ff0000;
252       b_mask = 0x0000ff00;
253 #else
254       r_mask = 0x000000ff;
255       g_mask = 0x0000ff00;
256       b_mask = 0x00ff0000;
257 #endif
258       break;
259     case PIX_FMT_BGRx32:
260       bpp = 32;
261       depth = 24;
262       endianness = G_BIG_ENDIAN;
263 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
264       r_mask = 0x000000ff;
265       g_mask = 0x0000ff00;
266       b_mask = 0x00ff0000;
267 #else
268       r_mask = 0xff000000;
269       g_mask = 0x00ff0000;
270       b_mask = 0x0000ff00;
271 #endif
272       break;
273     case PIX_FMT_RGBA32:
274       bpp = 32;
275       depth = 32;
276       endianness = G_BIG_ENDIAN;
277 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
278       r_mask = 0x00ff0000;
279       g_mask = 0x0000ff00;
280       b_mask = 0x000000ff;
281       a_mask = 0xff000000;
282 #else
283       r_mask = 0x0000ff00;
284       g_mask = 0x00ff0000;
285       b_mask = 0xff000000;
286       a_mask = 0x000000ff;
287 #endif
288       break;
289     case PIX_FMT_BGRA32:
290       bpp = 32;
291       depth = 32;
292       endianness = G_BIG_ENDIAN;
293 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
294       r_mask = 0x0000ff00;
295       g_mask = 0x00ff0000;
296       b_mask = 0xff000000;
297       a_mask = 0x000000ff;
298 #else
299       r_mask = 0x00ff0000;
300       g_mask = 0x0000ff00;
301       b_mask = 0x000000ff;
302       a_mask = 0xff000000;
303 #endif
304       break;
305     case PIX_FMT_ARGB32:
306       bpp = 32;
307       depth = 32;
308       endianness = G_BIG_ENDIAN;
309 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
310       r_mask = 0xff000000;
311       g_mask = 0x00ff0000;
312       b_mask = 0x0000ff00;
313       a_mask = 0x000000ff;
314 #else
315       r_mask = 0x000000ff;
316       g_mask = 0x0000ff00;
317       b_mask = 0x00ff0000;
318       a_mask = 0xff000000;
319 #endif
320       break;
321     case PIX_FMT_ABGR32:
322       bpp = 32;
323       depth = 32;
324       endianness = G_BIG_ENDIAN;
325 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
326       r_mask = 0x000000ff;
327       g_mask = 0x0000ff00;
328       b_mask = 0x00ff0000;
329       a_mask = 0xff000000;
330 #else
331       r_mask = 0xff000000;
332       g_mask = 0x00ff0000;
333       b_mask = 0x0000ff00;
334       a_mask = 0x000000ff;
335 #endif
336       break;
337     case PIX_FMT_YUV410P:
338       fmt = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
339       break;
340     case PIX_FMT_YVU410P:
341       fmt = GST_MAKE_FOURCC ('Y', 'V', 'U', '9');
342       break;
343     case PIX_FMT_YUV411P:
344       fmt = GST_MAKE_FOURCC ('Y', '4', '1', 'B');
345       break;
346     case PIX_FMT_Y800:{
347       GstCaps *tmp;
348
349       caps = gst_ff_vid_caps_new (context, "video/x-raw-yuv",
350           "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', '8', '0', '0'),
351           NULL);
352       tmp =
353           gst_ff_vid_caps_new (context, "video/x-raw-yuv", "format",
354           GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', '8', ' ', ' '), NULL);
355       gst_caps_append (caps, tmp);
356       tmp = gst_ff_vid_caps_new (context, "video/x-raw-yuv",
357           "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'),
358           NULL);
359       gst_caps_append (caps, tmp);
360       break;
361     }
362     case PIX_FMT_Y16:
363       fmt = GST_MAKE_FOURCC ('Y', '1', '6', ' ');
364       break;
365     case PIX_FMT_RGB565:
366       bpp = depth = 16;
367       endianness = G_BYTE_ORDER;
368       r_mask = 0xf800;
369       g_mask = 0x07e0;
370       b_mask = 0x001f;
371       break;
372     case PIX_FMT_RGB555:
373       bpp = 16;
374       depth = 15;
375       endianness = G_BYTE_ORDER;
376       r_mask = 0x7c00;
377       g_mask = 0x03e0;
378       b_mask = 0x001f;
379       break;
380     case PIX_FMT_PAL8:
381       bpp = depth = 8;
382       endianness = G_BYTE_ORDER;
383       break;
384     case PIX_FMT_V308:
385       fmt = GST_MAKE_FOURCC ('v', '3', '0', '8');
386       break;
387     case PIX_FMT_AYUV4444:
388       fmt = GST_MAKE_FOURCC ('A', 'Y', 'U', 'V');
389       break;
390     case PIX_FMT_GRAY8:
391       bpp = depth = 8;
392       caps = gst_ff_vid_caps_new (context, "video/x-raw-gray",
393           "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth, NULL);
394       break;
395     case PIX_FMT_GRAY16_L:
396       bpp = depth = 16;
397       caps = gst_ff_vid_caps_new (context, "video/x-raw-gray",
398           "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth,
399           "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL);
400       break;
401     case PIX_FMT_GRAY16_B:
402       bpp = depth = 16;
403       caps = gst_ff_vid_caps_new (context, "video/x-raw-gray",
404           "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth,
405           "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
406       break;
407     default:
408       /* give up ... */
409       break;
410   }
411
412   if (caps == NULL) {
413     if (bpp != 0) {
414       if (a_mask != 0) {
415         caps = gst_ff_vid_caps_new (context, "video/x-raw-rgb",
416             "bpp", G_TYPE_INT, bpp,
417             "depth", G_TYPE_INT, depth,
418             "red_mask", G_TYPE_INT, r_mask,
419             "green_mask", G_TYPE_INT, g_mask,
420             "blue_mask", G_TYPE_INT, b_mask,
421             "alpha_mask", G_TYPE_INT, a_mask,
422             "endianness", G_TYPE_INT, endianness, NULL);
423       } else if (r_mask != 0) {
424         caps = gst_ff_vid_caps_new (context, "video/x-raw-rgb",
425             "bpp", G_TYPE_INT, bpp,
426             "depth", G_TYPE_INT, depth,
427             "red_mask", G_TYPE_INT, r_mask,
428             "green_mask", G_TYPE_INT, g_mask,
429             "blue_mask", G_TYPE_INT, b_mask,
430             "endianness", G_TYPE_INT, endianness, NULL);
431       } else {
432         caps = gst_ff_vid_caps_new (context, "video/x-raw-rgb",
433             "bpp", G_TYPE_INT, bpp,
434             "depth", G_TYPE_INT, depth,
435             "endianness", G_TYPE_INT, endianness, NULL);
436         if (context && context->pix_fmt == PIX_FMT_PAL8) {
437           gst_ffmpeg_set_palette (caps, context);
438         }
439       }
440     } else if (fmt) {
441       caps = gst_ff_vid_caps_new (context, "video/x-raw-yuv",
442           "format", GST_TYPE_FOURCC, fmt, NULL);
443     }
444   }
445
446   if (caps != NULL) {
447     GST_DEBUG ("caps for pix_fmt=%d: %" GST_PTR_FORMAT, pix_fmt, caps);
448   } else {
449     GST_LOG ("No caps found for pix_fmt=%d", pix_fmt);
450   }
451
452   return caps;
453 }
454
455 /* Convert a FFMPEG Sample Format and optional AVCodecContext
456  * to a GstCaps. If the context is ommitted, no fixed values
457  * for video/audio size will be included in the GstCaps
458  *
459  * See below for usefulness
460  */
461
462 static GstCaps *
463 gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
464     AVCodecContext * context)
465 {
466   GstCaps *caps = NULL;
467
468   int bpp = 0;
469   gboolean signedness = FALSE;
470
471   switch (sample_fmt) {
472     case SAMPLE_FMT_S16:
473       signedness = TRUE;
474       bpp = 16;
475       break;
476
477     default:
478       /* .. */
479       break;
480   }
481
482   if (bpp) {
483     caps = gst_ff_aud_caps_new (context, "audio/x-raw-int",
484         "signed", G_TYPE_BOOLEAN, signedness,
485         "endianness", G_TYPE_INT, G_BYTE_ORDER,
486         "width", G_TYPE_INT, bpp, "depth", G_TYPE_INT, bpp, NULL);
487   }
488
489   if (caps != NULL) {
490     GST_DEBUG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
491   } else {
492     GST_LOG ("No caps found for sample_fmt=%d", sample_fmt);
493   }
494
495   return caps;
496 }
497
498 /* Convert a FFMPEG codec Type and optional AVCodecContext
499  * to a GstCaps. If the context is ommitted, no fixed values
500  * for video/audio size will be included in the GstCaps
501  *
502  * CodecType is primarily meant for uncompressed data GstCaps!
503  */
504
505 GstCaps *
506 gst_ffmpegcsp_codectype_to_caps (enum CodecType codec_type,
507     AVCodecContext * context)
508 {
509   GstCaps *caps;
510
511   switch (codec_type) {
512     case CODEC_TYPE_VIDEO:
513       if (context) {
514         caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt,
515             context->width == -1 ? NULL : context);
516       } else {
517         GstCaps *temp;
518         enum PixelFormat i;
519
520         caps = gst_caps_new_empty ();
521         for (i = 0; i < PIX_FMT_NB; i++) {
522           temp = gst_ffmpeg_pixfmt_to_caps (i, NULL);
523           if (temp != NULL) {
524             gst_caps_append (caps, temp);
525           }
526         }
527       }
528       break;
529
530     case CODEC_TYPE_AUDIO:
531       if (context) {
532         caps = gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context);
533       } else {
534         GstCaps *temp;
535         enum SampleFormat i;
536
537         caps = gst_caps_new_empty ();
538         for (i = 0; i <= SAMPLE_FMT_S16; i++) {
539           temp = gst_ffmpeg_smpfmt_to_caps (i, NULL);
540           if (temp != NULL) {
541             gst_caps_append (caps, temp);
542           }
543         }
544       }
545       break;
546
547     default:
548       /* .. */
549       caps = NULL;
550       break;
551   }
552
553   return caps;
554 }
555
556 /* Convert a GstCaps (audio/raw) to a FFMPEG SampleFmt
557  * and other audio properties in a AVCodecContext.
558  *
559  * For usefulness, see below
560  */
561
562 static void
563 gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps,
564     AVCodecContext * context, gboolean raw)
565 {
566   GstStructure *structure;
567   gint depth = 0, width = 0, endianness = 0;
568   gboolean signedness = FALSE;
569
570   g_return_if_fail (gst_caps_get_size (caps) == 1);
571   structure = gst_caps_get_structure (caps, 0);
572
573   gst_structure_get_int (structure, "channels", &context->channels);
574   gst_structure_get_int (structure, "rate", &context->sample_rate);
575
576   if (!raw)
577     return;
578
579   if (gst_structure_get_int (structure, "width", &width) &&
580       gst_structure_get_int (structure, "depth", &depth) &&
581       gst_structure_get_boolean (structure, "signed", &signedness) &&
582       gst_structure_get_int (structure, "endianness", &endianness)) {
583     if (width == 16 && depth == 16 &&
584         endianness == G_BYTE_ORDER && signedness == TRUE) {
585       context->sample_fmt = SAMPLE_FMT_S16;
586     }
587   }
588 }
589
590
591 /* Convert a GstCaps (video/raw) to a FFMPEG PixFmt
592  * and other video properties in a AVCodecContext.
593  *
594  * For usefulness, see below
595  */
596
597 static void
598 gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
599     AVCodecContext * context, gboolean raw)
600 {
601   GstStructure *structure;
602   const GValue *fps;
603   gboolean ret;
604
605   g_return_if_fail (gst_caps_get_size (caps) == 1);
606   structure = gst_caps_get_structure (caps, 0);
607
608   ret = gst_structure_get_int (structure, "width", &context->width);
609   ret &= gst_structure_get_int (structure, "height", &context->height);
610   g_return_if_fail (ret == TRUE);
611
612   fps = gst_structure_get_value (structure, "framerate");
613   g_return_if_fail (GST_VALUE_HOLDS_FRACTION (fps));
614
615   /* framerate does not really matter */
616   context->frame_rate = gst_value_get_fraction_numerator (fps);
617   context->frame_rate_base = gst_value_get_fraction_denominator (fps);
618
619   if (!raw)
620     return;
621
622   if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
623     guint32 fourcc;
624
625     if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
626       switch (fourcc) {
627         case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
628           context->pix_fmt = PIX_FMT_YUV422;
629           break;
630         case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
631           context->pix_fmt = PIX_FMT_UYVY422;
632           break;
633         case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
634           context->pix_fmt = PIX_FMT_YVYU422;
635           break;
636         case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
637           context->pix_fmt = PIX_FMT_UYVY411;
638           break;
639         case GST_MAKE_FOURCC ('I', '4', '2', '0'):
640           context->pix_fmt = PIX_FMT_YUV420P;
641           break;
642         case GST_MAKE_FOURCC ('A', '4', '2', '0'):
643           context->pix_fmt = PIX_FMT_YUVA420P;
644           break;
645         case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
646           context->pix_fmt = PIX_FMT_NV12;
647           break;
648         case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
649           context->pix_fmt = PIX_FMT_NV21;
650           break;
651         case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
652           context->pix_fmt = PIX_FMT_YVU420P;
653           break;
654         case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
655           context->pix_fmt = PIX_FMT_YUV411P;
656           break;
657         case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
658           context->pix_fmt = PIX_FMT_YUV422P;
659           break;
660         case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
661           context->pix_fmt = PIX_FMT_YUV410P;
662           break;
663         case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
664           context->pix_fmt = PIX_FMT_YVU410P;
665           break;
666         case GST_MAKE_FOURCC ('v', '3', '0', '8'):
667           context->pix_fmt = PIX_FMT_V308;
668           break;
669         case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
670           context->pix_fmt = PIX_FMT_AYUV4444;
671           break;
672         case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
673           context->pix_fmt = PIX_FMT_YUV444P;
674           break;
675         case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
676         case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
677         case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
678           context->pix_fmt = PIX_FMT_Y800;
679           break;
680         case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
681           context->pix_fmt = PIX_FMT_Y16;
682           break;
683       }
684     }
685   } else if (gst_structure_has_name (structure, "video/x-raw-rgb")) {
686     gint bpp = 0, rmask = 0, endianness = 0, amask = 0, depth = 0;
687
688     if (gst_structure_get_int (structure, "bpp", &bpp) &&
689         gst_structure_get_int (structure, "endianness", &endianness)) {
690       if (gst_structure_get_int (structure, "red_mask", &rmask)) {
691         switch (bpp) {
692           case 32:
693             if (gst_structure_get_int (structure, "alpha_mask", &amask)) {
694 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
695               if (rmask == 0x0000ff00)
696                 context->pix_fmt = PIX_FMT_BGRA32;
697               else if (rmask == 0x00ff0000)
698                 context->pix_fmt = PIX_FMT_RGBA32;
699               else if (rmask == 0xff000000)
700                 context->pix_fmt = PIX_FMT_ARGB32;
701               else              // if (r_mask = 0x000000ff)
702                 context->pix_fmt = PIX_FMT_ABGR32;
703 #else
704               if (rmask == 0x00ff0000)
705                 context->pix_fmt = PIX_FMT_BGRA32;
706               else if (rmask == 0x0000ff00)
707                 context->pix_fmt = PIX_FMT_RGBA32;
708               else if (rmask == 0x000000ff)
709                 context->pix_fmt = PIX_FMT_ARGB32;
710               else              // if (rmask == 0xff000000)
711                 context->pix_fmt = PIX_FMT_ABGR32;
712 #endif
713             } else {
714 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
715               if (rmask == 0x00ff0000)
716                 context->pix_fmt = PIX_FMT_RGB32;
717               else if (rmask == 0x0000ff00)
718                 context->pix_fmt = PIX_FMT_BGR32;
719               else if (rmask == 0xff000000)
720                 context->pix_fmt = PIX_FMT_xRGB32;
721               else              // if (rmask == 0x000000ff)
722                 context->pix_fmt = PIX_FMT_BGRx32;
723 #else
724               if (rmask == 0x0000ff00)
725                 context->pix_fmt = PIX_FMT_RGB32;
726               else if (rmask == 0x00ff0000)
727                 context->pix_fmt = PIX_FMT_BGR32;
728               else if (rmask == 0x000000ff)
729                 context->pix_fmt = PIX_FMT_xRGB32;
730               else              // if (rmask == 0xff000000)
731                 context->pix_fmt = PIX_FMT_BGRx32;
732 #endif
733             }
734             break;
735           case 24:
736             if (rmask == 0x0000FF)
737               context->pix_fmt = PIX_FMT_BGR24;
738             else
739               context->pix_fmt = PIX_FMT_RGB24;
740             break;
741           case 16:
742             if (endianness == G_BYTE_ORDER) {
743               context->pix_fmt = PIX_FMT_RGB565;
744               if (gst_structure_get_int (structure, "depth", &depth)) {
745                 if (depth == 15)
746                   context->pix_fmt = PIX_FMT_RGB555;
747               }
748             }
749             break;
750           case 15:
751             if (endianness == G_BYTE_ORDER)
752               context->pix_fmt = PIX_FMT_RGB555;
753             break;
754           default:
755             /* nothing */
756             break;
757         }
758       } else {
759         if (bpp == 8) {
760           context->pix_fmt = PIX_FMT_PAL8;
761           gst_ffmpeg_get_palette (caps, context);
762         }
763       }
764     }
765   } else if (gst_structure_has_name (structure, "video/x-raw-gray")) {
766     gint bpp = 0;
767
768     if (gst_structure_get_int (structure, "bpp", &bpp)) {
769       switch (bpp) {
770         case 8:
771           context->pix_fmt = PIX_FMT_GRAY8;
772           break;
773         case 16:{
774           gint endianness = 0;
775
776           if (gst_structure_get_int (structure, "endianness", &endianness)) {
777             if (endianness == G_LITTLE_ENDIAN)
778               context->pix_fmt = PIX_FMT_GRAY16_L;
779             else if (endianness == G_BIG_ENDIAN)
780               context->pix_fmt = PIX_FMT_GRAY16_B;
781           }
782         }
783           break;
784       }
785     }
786   }
787 }
788
789 /* Convert a GstCaps and a FFMPEG codec Type to a
790  * AVCodecContext. If the context is ommitted, no fixed values
791  * for video/audio size will be included in the context
792  *
793  * CodecType is primarily meant for uncompressed data GstCaps!
794  */
795
796 void
797 gst_ffmpegcsp_caps_with_codectype (enum CodecType type,
798     const GstCaps * caps, AVCodecContext * context)
799 {
800   if (context == NULL)
801     return;
802
803   switch (type) {
804     case CODEC_TYPE_VIDEO:
805       gst_ffmpeg_caps_to_pixfmt (caps, context, TRUE);
806       break;
807
808     case CODEC_TYPE_AUDIO:
809       gst_ffmpeg_caps_to_smpfmt (caps, context, TRUE);
810       break;
811
812     default:
813       /* unknown */
814       break;
815   }
816 }
817
818 #define GEN_MASK(x) ((1<<(x))-1)
819 #define ROUND_UP_X(v,x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
820 #define DIV_ROUND_UP_X(v,x) (((v) + GEN_MASK(x)) >> (x))
821
822 /*
823  * Fill in pointers to memory in a AVPicture, where
824  * everything is aligned by 4 (as required by X).
825  * This is mostly a copy from imgconvert.c with some
826  * small changes.
827  */
828 int
829 gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
830     uint8_t * ptr, enum PixelFormat pix_fmt, int width, int height,
831     int interlaced)
832 {
833   int size, w2, h2, size2;
834   int stride, stride2;
835   PixFmtInfo *pinfo;
836
837   pinfo = get_pix_fmt_info (pix_fmt);
838
839   picture->interlaced = interlaced;
840
841   switch (pix_fmt) {
842     case PIX_FMT_YUV420P:
843     case PIX_FMT_YUV422P:
844     case PIX_FMT_YUV444P:
845     case PIX_FMT_YUV410P:
846     case PIX_FMT_YUV411P:
847     case PIX_FMT_YUVJ420P:
848     case PIX_FMT_YUVJ422P:
849     case PIX_FMT_YUVJ444P:
850       stride = GST_ROUND_UP_4 (width);
851       h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
852       size = stride * h2;
853       w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
854       stride2 = GST_ROUND_UP_4 (w2);
855       h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
856       size2 = stride2 * h2;
857       picture->data[0] = ptr;
858       picture->data[1] = picture->data[0] + size;
859       picture->data[2] = picture->data[1] + size2;
860       picture->linesize[0] = stride;
861       picture->linesize[1] = stride2;
862       picture->linesize[2] = stride2;
863       return size + 2 * size2;
864       /* PIX_FMT_YVU420P = YV12: same as PIX_FMT_YUV420P, but
865        *  with U and V plane swapped. Strides as in videotestsrc */
866     case PIX_FMT_YUVA420P:
867       stride = GST_ROUND_UP_4 (width);
868       h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
869       size = stride * h2;
870       w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
871       stride2 = GST_ROUND_UP_4 (w2);
872       h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
873       size2 = stride2 * h2;
874       picture->data[0] = ptr;
875       picture->data[1] = picture->data[0] + size;
876       picture->data[2] = picture->data[1] + size2;
877       picture->data[3] = picture->data[2] + size2;
878       picture->linesize[0] = stride;
879       picture->linesize[1] = stride2;
880       picture->linesize[2] = stride2;
881       picture->linesize[3] = stride;
882       return 2 * size + 2 * size2;
883     case PIX_FMT_YVU410P:
884     case PIX_FMT_YVU420P:
885       stride = GST_ROUND_UP_4 (width);
886       h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
887       size = stride * h2;
888       w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
889       stride2 = GST_ROUND_UP_4 (w2);
890       h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
891       size2 = stride2 * h2;
892       picture->data[0] = ptr;
893       picture->data[2] = picture->data[0] + size;
894       picture->data[1] = picture->data[2] + size2;
895       picture->linesize[0] = stride;
896       picture->linesize[1] = stride2;
897       picture->linesize[2] = stride2;
898       return size + 2 * size2;
899     case PIX_FMT_NV12:
900     case PIX_FMT_NV21:
901       stride = GST_ROUND_UP_4 (width);
902       h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
903       size = stride * h2;
904       w2 = 2 * DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
905       stride2 = GST_ROUND_UP_4 (w2);
906       h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
907       size2 = stride2 * h2;
908       picture->data[0] = ptr;
909       picture->data[1] = picture->data[0] + size;
910       picture->data[2] = NULL;
911       picture->linesize[0] = stride;
912       picture->linesize[1] = stride2;
913       picture->linesize[2] = 0;
914       return size + size2;
915     case PIX_FMT_RGB24:
916     case PIX_FMT_BGR24:
917       stride = GST_ROUND_UP_4 (width * 3);
918       size = stride * height;
919       picture->data[0] = ptr;
920       picture->data[1] = NULL;
921       picture->data[2] = NULL;
922       picture->linesize[0] = stride;
923       return size;
924     case PIX_FMT_AYUV4444:
925     case PIX_FMT_RGB32:
926     case PIX_FMT_RGBA32:
927     case PIX_FMT_ARGB32:
928     case PIX_FMT_BGR32:
929     case PIX_FMT_BGRA32:
930     case PIX_FMT_ABGR32:
931     case PIX_FMT_xRGB32:
932     case PIX_FMT_BGRx32:
933       stride = width * 4;
934       size = stride * height;
935       picture->data[0] = ptr;
936       picture->data[1] = NULL;
937       picture->data[2] = NULL;
938       picture->linesize[0] = stride;
939       return size;
940     case PIX_FMT_RGB555:
941     case PIX_FMT_RGB565:
942     case PIX_FMT_YUV422:
943     case PIX_FMT_UYVY422:
944     case PIX_FMT_YVYU422:
945       stride = GST_ROUND_UP_4 (width * 2);
946       size = stride * height;
947       picture->data[0] = ptr;
948       picture->data[1] = NULL;
949       picture->data[2] = NULL;
950       picture->linesize[0] = stride;
951       return size;
952     case PIX_FMT_V308:
953       stride = GST_ROUND_UP_4 (width * 3);
954       size = stride * height;
955       picture->data[0] = ptr;
956       picture->data[1] = NULL;
957       picture->data[2] = NULL;
958       picture->linesize[0] = stride;
959       return size;
960     case PIX_FMT_UYVY411:
961       stride =
962           GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) + GST_ROUND_UP_4 (width) / 2);
963       size = stride * height;
964       picture->data[0] = ptr;
965       picture->data[1] = NULL;
966       picture->data[2] = NULL;
967       picture->linesize[0] = stride;
968       return size;
969     case PIX_FMT_Y800:
970     case PIX_FMT_GRAY8:
971       stride = GST_ROUND_UP_4 (width);
972       size = stride * height;
973       picture->data[0] = ptr;
974       picture->data[1] = NULL;
975       picture->data[2] = NULL;
976       picture->linesize[0] = stride;
977       return size;
978     case PIX_FMT_Y16:
979     case PIX_FMT_GRAY16_L:
980     case PIX_FMT_GRAY16_B:
981       stride = GST_ROUND_UP_4 (width * 2);
982       size = stride * height;
983       picture->data[0] = ptr;
984       picture->data[1] = NULL;
985       picture->data[2] = NULL;
986       picture->linesize[0] = stride;
987       return size;
988     case PIX_FMT_MONOWHITE:
989     case PIX_FMT_MONOBLACK:
990       stride = GST_ROUND_UP_4 ((width + 7) >> 3);
991       size = stride * height;
992       picture->data[0] = ptr;
993       picture->data[1] = NULL;
994       picture->data[2] = NULL;
995       picture->linesize[0] = stride;
996       return size;
997     case PIX_FMT_PAL8:
998       /* already forced to be with stride, so same result as other function */
999       stride = GST_ROUND_UP_4 (width);
1000       size = stride * height;
1001       picture->data[0] = ptr;
1002       picture->data[1] = ptr + size;    /* palette is stored here as 256 32 bit words */
1003       picture->data[2] = NULL;
1004       picture->linesize[0] = stride;
1005       picture->linesize[1] = 4;
1006       return size + 256 * 4;
1007     default:
1008       picture->data[0] = NULL;
1009       picture->data[1] = NULL;
1010       picture->data[2] = NULL;
1011       picture->data[3] = NULL;
1012       return -1;
1013   }
1014
1015   return 0;
1016 }