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