Removed compile warnings.
[platform/adaptation/emulator/gst-plugins-emulator.git] / src / gstmaruutils.c
1 /*
2  * GStreamer codec plugin for Tizen Emulator.
3  *
4  * Copyright (C) 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  * KiTae Kim <kt920.kim@samsung.com>
8  * SeokYeon Hwang <syeon.hwang@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  *
29  */
30
31 #include "gstmaruutils.h"
32 #include <gst/audio/multichannel.h>
33 #include <gst/pbutils/codec-utils.h>
34
35 gint
36 gst_maru_smpfmt_depth (int smp_fmt)
37 {
38   gint depth = -1;
39
40   switch (smp_fmt) {
41   case SAMPLE_FMT_U8:
42     depth = 1;
43     break;
44   case SAMPLE_FMT_S16:
45     depth = 2;
46     break;
47   case SAMPLE_FMT_S32:
48   case SAMPLE_FMT_FLT:
49     depth = 4;
50     break;
51   case SAMPLE_FMT_DBL:
52     depth = 8;
53     break;
54   default:
55     GST_ERROR ("Unhandled sample format !");
56     break;
57   }
58
59   return depth;
60 }
61
62 // FFmpeg
63 static const struct
64 {
65   guint64 ff;
66   GstAudioChannelPosition gst;
67 } _ff_to_gst_layout[] = {
68   {
69   CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
70   CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
71   CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
72   CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE}, {
73   CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
74   CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
75   CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
76   CH_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
77   CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
78   CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
79   CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
80   CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
81   CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
82   CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
83   CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
84   CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
85   CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
86   CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
87   CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
88   CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
89 };
90
91 static GstAudioChannelPosition *
92 gst_ff_channel_layout_to_gst (guint64 channel_layout, guint channels)
93 {
94   guint nchannels = 0, i, j;
95   GstAudioChannelPosition *pos = NULL;
96   gboolean none_layout = FALSE;
97
98   for (i = 0; i < 64; i++) {
99     if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
100       nchannels++;
101     }
102   }
103
104   if (channel_layout == 0) {
105     nchannels = channels;
106     none_layout = TRUE;
107   }
108
109   if (nchannels != channels) {
110     GST_ERROR ("Number of channels is different (%u != %u)", channels,
111         nchannels);
112     return NULL;
113   }
114
115   pos = g_new (GstAudioChannelPosition, nchannels);
116
117   for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
118     if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
119       pos[j++] = _ff_to_gst_layout[i].gst;
120
121       if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE) {
122         none_layout = TRUE;
123       }
124     }
125   }
126
127   if (j != nchannels) {
128     GST_WARNING ("Unknown channels in channel layout - assuming NONE layout");
129     none_layout = TRUE;
130   }
131
132   if (!none_layout && !gst_audio_check_channel_positions (pos, nchannels)) {
133     GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
134       " - assuming NONE layout", channel_layout);
135     none_layout = TRUE;
136   }
137
138   if (none_layout) {
139     if (nchannels == 1) {
140       pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
141     } else if (nchannels == 2) {
142       pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
143       pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
144     } else if (channel_layout == 0) {
145       g_free (pos);
146       pos = NULL;
147     } else {
148       for (i = 0; i < nchannels; i++) {
149         pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
150       }
151     }
152   }
153
154   if (nchannels == 1 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER) {
155     GST_DEBUG ("mono common case; won't set channel positions");
156     g_free (pos);
157     pos = NULL;
158   } else if (nchannels == 2 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
159     && pos[1] == GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT) {
160     GST_DEBUG ("stereo common case; won't set channel positions");
161     g_free (pos);
162     pos = NULL;
163   }
164
165   return pos;
166 }
167
168 GstCaps*
169 gst_maru_codectype_to_video_caps (CodecContext *ctx, const char *name,
170     gboolean encode, CodecElement *codec)
171 {
172   GstCaps *caps;
173
174   GST_DEBUG ("context: %p, codec: %s, encode: %d, pixel format: %d",
175       ctx, name, encode, ctx->video.pix_fmt);
176
177   if (ctx) {
178     caps = gst_maru_pixfmt_to_caps (ctx->video.pix_fmt, ctx, name);
179   } else {
180     GstCaps *temp;
181     enum PixelFormat i;
182     CodecContext ctx;
183
184     caps = gst_caps_new_empty ();
185     for (i = 0; i <= PIX_FMT_NB; i++) {
186       temp = gst_maru_pixfmt_to_caps (i, encode ? &ctx : NULL, name);
187       if (temp != NULL) {
188         gst_caps_append (caps, temp);
189       }
190     }
191   }
192
193   return caps;
194 }
195
196 GstCaps *
197 gst_maru_codectype_to_audio_caps (CodecContext *ctx, const char *name,
198     gboolean encode, CodecElement *codec)
199 {
200   GstCaps *caps = NULL;
201
202   GST_DEBUG ("context: %p, codec: %s, encode: %d, codec: %p",
203       ctx, name, encode, codec);
204
205   if (ctx) {
206     caps = gst_maru_smpfmt_to_caps (ctx->audio.sample_fmt, ctx, name);
207   } else if (codec && codec->sample_fmts[0] != -1){
208     GstCaps *temp;
209     int i;
210
211     caps = gst_caps_new_empty ();
212     for (i = 0; codec->sample_fmts[i] != -1; i++) {
213       temp =
214           gst_maru_smpfmt_to_caps (codec->sample_fmts[i], ctx, name);
215       if (temp != NULL) {
216         gst_caps_append (caps, temp);
217       }
218     }
219   } else {
220     GstCaps *temp;
221     int i;
222     CodecContext ctx = {{0}, {0}, 0};
223
224     ctx.audio.channels = -1;
225     caps = gst_caps_new_empty ();
226     for (i = 0; i <= SAMPLE_FMT_DBL; i++) {
227       temp = gst_maru_smpfmt_to_caps (i, encode ? &ctx : NULL, name);
228       if (temp != NULL) {
229         gst_caps_append (caps, temp);
230       }
231     }
232   }
233
234   return caps;
235 }
236
237 GstCaps*
238 gst_maru_codectype_to_caps (int media_type, CodecContext *ctx,
239     const char *name, gboolean encode)
240 {
241   GstCaps *caps;
242
243   switch (media_type) {
244   case AVMEDIA_TYPE_VIDEO:
245     caps =
246         gst_maru_codectype_to_video_caps (ctx, name, encode, NULL);
247     break;
248   case AVMEDIA_TYPE_AUDIO:
249     caps =
250         gst_maru_codectype_to_audio_caps (ctx, name, encode, NULL);
251    break;
252   default:
253     caps = NULL;
254     break;
255   }
256
257   return caps;
258 }
259
260 void
261 gst_maru_caps_to_pixfmt (const GstCaps *caps, CodecContext *ctx, gboolean raw)
262 {
263   GstStructure *str;
264   const GValue *fps;
265   const GValue *par = NULL;
266
267   GST_DEBUG ("converting caps %" GST_PTR_FORMAT, caps);
268   g_return_if_fail (gst_caps_get_size (caps) == 1);
269   str = gst_caps_get_structure (caps, 0);
270
271   gst_structure_get_int (str, "width", &ctx->video.width);
272   gst_structure_get_int (str, "height", &ctx->video.height);
273   gst_structure_get_int (str, "bpp", &ctx->video.bpp);
274
275   fps = gst_structure_get_value (str, "framerate");
276   if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
277     ctx->video.fps_d = gst_value_get_fraction_numerator (fps);
278     ctx->video.fps_n = gst_value_get_fraction_denominator (fps);
279   ctx->video.ticks_per_frame = 1;
280
281     GST_DEBUG ("setting framerate %d/%d = %lf",
282         ctx->video.fps_d, ctx->video.fps_n,
283         1. * ctx->video.fps_d / ctx->video.fps_n);
284   }
285
286   par = gst_structure_get_value (str, "pixel-aspect-ratio");
287   if (par && GST_VALUE_HOLDS_FRACTION (par)) {
288     ctx->video.par_n = gst_value_get_fraction_numerator (par);
289     ctx->video.par_d = gst_value_get_fraction_denominator (par);
290   }
291
292   if (!raw) {
293     return;
294   }
295
296   g_return_if_fail (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps));
297
298   if (strcmp (gst_structure_get_name (str), "video/x-raw-yuv") == 0) {
299     guint32 fourcc;
300
301     if (gst_structure_get_fourcc (str, "format", &fourcc)) {
302     switch (fourcc) {
303       case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
304         ctx->video.pix_fmt = PIX_FMT_YUYV422;
305         break;
306       case GST_MAKE_FOURCC ('I', '4', '2', '0'):
307         ctx->video.pix_fmt = PIX_FMT_YUV420P;
308         break;
309       case GST_MAKE_FOURCC ('A', '4', '2', '0'):
310         ctx->video.pix_fmt = PIX_FMT_YUVA420P;
311         break;
312       case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
313         ctx->video.pix_fmt = PIX_FMT_YUV411P;
314         break;
315       case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
316         ctx->video.pix_fmt = PIX_FMT_YUV422P;
317         break;
318       case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
319         ctx->video.pix_fmt = PIX_FMT_YUV410P;
320         break;
321       }
322     }
323 //    printf ("get pixel format: %d, fourcc: %d\n", ctx->video.pix_fmt, fourcc);
324   } else if (strcmp (gst_structure_get_name (str), "video/x-raw-rgb") == 0) {
325     gint bpp = 0, rmask = 0, endianness = 0;
326
327     if (gst_structure_get_int (str, "bpp", &bpp) &&
328       gst_structure_get_int (str, "endianness", &endianness)) {
329       if (gst_structure_get_int (str, "red_mask", &rmask)) {
330         switch (bpp) {
331         case 32:
332 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
333           if (rmask == 0x00ff0000) {
334 #else
335           if (rmask == 0x00ff0000) {
336 #endif
337             ctx->video.pix_fmt = PIX_FMT_RGB32;
338           }
339           break;
340         case 24:
341           if (rmask == 0x0000FF) {
342             ctx->video.pix_fmt = PIX_FMT_BGR24;
343           } else {
344             ctx->video.pix_fmt = PIX_FMT_RGB24;
345           }
346           break;
347         case 16:
348           if (endianness == G_BYTE_ORDER) {
349             ctx->video.pix_fmt = PIX_FMT_RGB565;
350           }
351           break;
352         case 15:
353           if (endianness == G_BYTE_ORDER) {
354             ctx->video.pix_fmt = PIX_FMT_RGB555;
355           }
356           break;
357         default:
358           break;
359         }
360       }
361     } else {
362       if (bpp == 8) {
363         ctx->video.pix_fmt = PIX_FMT_PAL8;
364         // get palette
365       }
366     }
367   } else if (strcmp (gst_structure_get_name (str), "video/x-raw-gray") == 0) {
368     gint bpp = 0;
369
370     if (gst_structure_get_int (str, "bpp", &bpp)) {
371       switch (bpp) {
372       case 8:
373         ctx->video.pix_fmt = PIX_FMT_GRAY8;
374         break;
375       }
376     }
377   }
378 }
379
380 void
381 gst_maru_caps_to_smpfmt (const GstCaps *caps, CodecContext *ctx, gboolean raw)
382 {
383   GstStructure *str;
384   gint depth = 0, width = 0, endianness = 0;
385   gboolean signedness = FALSE;
386   const gchar *name;
387
388   g_return_if_fail (gst_caps_get_size (caps) == 1);
389   str = gst_caps_get_structure (caps, 0);
390
391   gst_structure_get_int (str, "channels", &ctx->audio.channels);
392   gst_structure_get_int (str, "rate", &ctx->audio.sample_rate);
393   gst_structure_get_int (str, "block_align", &ctx->audio.block_align);
394 //  gst_structure_get_int (str, "bitrate", &ctx->audio.bit_rate);
395   gst_structure_get_int (str, "bitrate", &ctx->bit_rate);
396
397   if (!raw) {
398     return;
399   }
400
401   name = gst_structure_get_name (str);
402
403   if (!strcmp (name, "audio/x-raw-float")) {
404     if (gst_structure_get_int (str, "width", &width) &&
405       gst_structure_get_int (str, "endianness", &endianness)) {
406       if (endianness == G_BYTE_ORDER) {
407         if (width == 32) {
408           ctx->audio.sample_fmt = SAMPLE_FMT_FLT;
409         } else if (width == 64) {
410           ctx->audio.sample_fmt = SAMPLE_FMT_DBL;
411         }
412       }
413     }
414   } else {
415     if (gst_structure_get_int (str, "width", &width) &&
416       gst_structure_get_int (str, "depth", &depth) &&
417       gst_structure_get_boolean (str, "signed", &signedness) &&
418       gst_structure_get_int (str, "endianness", &endianness)) {
419       if ((endianness == G_BYTE_ORDER) && (signedness == TRUE)) {
420         if ((width == 16) && (depth == 16)) {
421           ctx->audio.sample_fmt = SAMPLE_FMT_S16;
422         } else if ((width == 32) && (depth == 32)) {
423           ctx->audio.sample_fmt = SAMPLE_FMT_S32;
424         }
425       }
426     }
427   }
428 }
429
430 void
431 gst_maru_caps_with_codecname (const char *name, int media_type,
432     const GstCaps *caps, CodecContext *ctx)
433 {
434   GstStructure *structure;
435   const GValue *value;
436   const GstBuffer *buf;
437
438   if (!ctx || !gst_caps_get_size (caps)) {
439     return;
440   }
441
442   structure = gst_caps_get_structure (caps, 0);
443
444   if ((value = gst_structure_get_value (structure, "codec_data"))) {
445     guint size;
446     guint8 *data;
447
448     buf = GST_BUFFER_CAST (gst_value_get_mini_object (value));
449     size = GST_BUFFER_SIZE (buf);
450     data = GST_BUFFER_DATA (buf);
451     GST_DEBUG ("extradata: %p, size: %d\n", data, size);
452
453     if (ctx->codecdata) {
454       g_free (ctx->codecdata);
455     }
456
457     ctx->codecdata =
458         g_malloc0 (GST_ROUND_UP_16 (size + FF_INPUT_BUFFER_PADDING_SIZE));
459     memcpy (ctx->codecdata, data, size);
460     ctx->codecdata_size = size;
461
462     if ((strcmp (name, "vc1") == 0) && size > 0 && data[0] == 0) {
463       ctx->codecdata[0] = (guint8) size;
464     }
465   } else if (ctx->codecdata == NULL) {
466     ctx->codecdata_size = 0;
467     ctx->codecdata = g_malloc0 (GST_ROUND_UP_16(FF_INPUT_BUFFER_PADDING_SIZE));
468     GST_DEBUG ("no extra data.\n");
469   }
470
471   if ((strcmp (name, "mpeg4") == 0)) {
472     const gchar *mime = gst_structure_get_name (structure);
473
474     if (!strcmp (mime, "video/x-divx")) {
475       ctx->codec_tag = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
476     } else if (!strcmp (mime, "video/x-xvid")) {
477       ctx->codec_tag = GST_MAKE_FOURCC ('X', 'V', 'I', 'D');
478     } else if (!strcmp (mime, "video/x-3ivx")) {
479       ctx->codec_tag = GST_MAKE_FOURCC ('3', 'I', 'V', '1');
480     } else if (!strcmp (mime, "video/mpeg")) {
481       ctx->codec_tag = GST_MAKE_FOURCC ('m', 'p', '4', 'v');
482     }
483 #if 0
484   } else if (strcmp (name, "h263p") == 0) {
485     gboolean val;
486
487     if (!gst_structure_get_boolean (structure, "annex-f", &val) || val) {
488       ctx->flags |= CODEC_FLAG_4MV;
489     } else {
490       ctx->flags &= ~CODEC_FLAG_4MV;
491     }
492     if ((!gst_structure_get_boolean (structure, "annex-i", &val) || val) &&
493       (!gst_structure_get_boolean (structure, "annex-t", &val) || val)) {
494       ctx->flags |= CODEC_FLAG_AC_PRED;
495     } else {
496       ctx->flags &= ~CODEC_FLAG_AC_PRED;
497     }
498     if ((!gst_structure_get_boolean (structure, "annex-j", &val) || val)) {
499       ctx->flags |= CODEC_FLAG_LOOP_FILTER;
500     } else {
501       ctx->flags &= ~CODEC_FLAG_LOOP_FILTER;
502     }
503 #endif
504   } else {
505     // TODO
506   }
507
508   if (!gst_caps_is_fixed (caps)) {
509     return;
510   }
511
512   switch (media_type) {
513   case AVMEDIA_TYPE_VIDEO:
514     gst_maru_caps_to_pixfmt (caps, ctx, FALSE);
515   // get_palette
516     break;
517   case AVMEDIA_TYPE_AUDIO:
518     gst_maru_caps_to_smpfmt (caps, ctx, FALSE);
519     break;
520   default:
521     break;
522   }
523 }
524
525 void
526 gst_maru_caps_to_codecname (const GstCaps *caps,
527                             gchar *codec_name,
528                             CodecContext *context)
529 {
530   const gchar *mimetype;
531   const GstStructure *str;
532
533   str = gst_caps_get_structure (caps, 0);
534
535   mimetype = gst_structure_get_name (str);
536
537   if (!strcmp (mimetype, "video/x-wmv")) {
538     gint wmvversion = 0;
539
540     if (gst_structure_get_int (str, "wmvversion", &wmvversion)) {
541       switch (wmvversion) {
542         case 1:
543           g_strlcpy(codec_name, "wmv1", 32);
544           break;
545         case 2:
546           g_strlcpy(codec_name, "wmv2", 32);
547           break;
548         case 3:
549         {
550           guint32 fourcc;
551
552           g_strlcpy(codec_name, "wmv3", 32);
553
554           if (gst_structure_get_fourcc (str, "format", &fourcc)) {
555             if ((fourcc == GST_MAKE_FOURCC ('W', 'V', 'C', '1')) ||
556                 (fourcc == GST_MAKE_FOURCC ('W', 'M', 'V', 'A'))) {
557               g_strlcpy(codec_name, "vc1", 32);
558             }
559           }
560         }
561           break;
562       }
563     }
564   }
565
566 #if 0
567   if (context != NULL) {
568     if (video == TRUE) {
569       context->codec_type = CODEC_TYPE_VIDEO;
570     } else if (audio == TRUE) {
571       context->codec_type = CODEC_TYPE_AUDIO;
572     } else {
573       context->codec_type = CODEC_TYPE_UNKNOWN;
574     }
575     context->codec_id = id;
576     gst_maru_caps_with_codecname (name, context->codec_type, caps, context);
577   }
578 #endif
579
580   if (codec_name != NULL) {
581     GST_DEBUG ("The %s belongs to the caps %" GST_PTR_FORMAT, codec_name, caps);
582   } else {
583     GST_WARNING ("Couldn't figure out the name for caps %" GST_PTR_FORMAT, caps);
584   }
585 }
586
587 void
588 gst_maru_caps_with_codectype (int media_type, const GstCaps *caps, CodecContext *ctx)
589 {
590   if (ctx == NULL) {
591     return;
592   }
593
594   switch (media_type) {
595   case AVMEDIA_TYPE_VIDEO:
596     gst_maru_caps_to_pixfmt (caps, ctx, TRUE);
597     break;
598   case AVMEDIA_TYPE_AUDIO:
599     gst_maru_caps_to_smpfmt (caps, ctx, TRUE);
600     break;
601   default:
602     break;
603   }
604 }
605
606 GstCaps *
607 gst_maru_video_caps_new (CodecContext *ctx, const char *name,
608         const char *mimetype, const char *fieldname, ...)
609 {
610   GstStructure *structure = NULL;
611   GstCaps *caps = NULL;
612   va_list var_args;
613   gint i;
614
615   GST_LOG ("context: %p, name: %s, mimetype: %s", ctx, name, mimetype);
616
617   if (ctx != NULL && ctx->video.width != -1) {
618     gint num, denom;
619
620     caps = gst_caps_new_simple (mimetype,
621       "width", G_TYPE_INT, ctx->video.width,
622       "height", G_TYPE_INT, ctx->video.height, NULL);
623
624     num = ctx->video.fps_d / ctx->video.ticks_per_frame;
625     denom = ctx->video.fps_n;
626
627     if (!denom) {
628       GST_LOG ("invalid framerate: %d/0, -> %d/1", num, num);
629     }
630     if (gst_util_fraction_compare (num, denom, 1000, 1) > 0) {
631       GST_LOG ("excessive framerate: %d/%d, -> 0/1", num, denom);
632       num = 0;
633       denom = 1;
634     }
635     GST_LOG ("setting framerate: %d/%d", num, denom);
636     gst_caps_set_simple (caps,
637       "framerate", GST_TYPE_FRACTION, num, denom, NULL);
638   } else {
639     if (strcmp (name, "h263") == 0) {
640       /* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
641        * because we want automatic negotiation to go as close to 320x240 as
642        * possible. */
643       const static gint widths[] = { 352, 704, 176, 1408, 128 };
644       const static gint heights[] = { 288, 576, 144, 1152, 96 };
645       GstCaps *temp;
646       gint n_sizes = G_N_ELEMENTS (widths);
647
648       caps = gst_caps_new_empty ();
649       for (i = 0; i < n_sizes; i++) {
650         temp = gst_caps_new_simple (mimetype,
651             "width", G_TYPE_INT, widths[i],
652             "height", G_TYPE_INT, heights[i],
653             "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
654
655         gst_caps_append (caps, temp);
656       }
657     } else if (strcmp (name, "none") == 0) {
658       GST_LOG ("default caps");
659     }
660   }
661
662   /* no fixed caps or special restrictions applied;
663    * default unfixed setting */
664   if (!caps) {
665     GST_DEBUG ("Creating default caps");
666     caps = gst_caps_new_simple (mimetype,
667             "width", GST_TYPE_INT_RANGE, 16, 4096,
668             "height", GST_TYPE_INT_RANGE, 16, 4096,
669              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
670   }
671
672   for (i = 0; i < gst_caps_get_size (caps); i++) {
673     va_start (var_args, fieldname);
674     structure = gst_caps_get_structure (caps, i);
675     gst_structure_set_valist (structure, fieldname, var_args);
676     va_end (var_args);
677   }
678
679   return caps;
680 }
681
682 GstCaps *
683 gst_maru_audio_caps_new (CodecContext *ctx, const char *name,
684         const char *mimetype, const char *fieldname, ...)
685 {
686   GstStructure *structure = NULL;
687   GstCaps *caps = NULL;
688   gint i;
689   va_list var_args;
690
691   if (ctx != NULL && ctx->audio.channels != -1) {
692     GstAudioChannelPosition *pos;
693     guint64 channel_layout = ctx->audio.channel_layout;
694
695     if (channel_layout == 0) {
696       const guint64 default_channel_set[] = {
697         0, 0, CH_LAYOUT_SURROUND, CH_LAYOUT_QUAD, CH_LAYOUT_5POINT0,
698         CH_LAYOUT_5POINT1, 0, CH_LAYOUT_7POINT1
699       };
700
701       if (strcmp (name, "ac3") == 0) {
702         if (ctx->audio.channels > 0 &&
703           ctx->audio.channels < G_N_ELEMENTS (default_channel_set)) {
704           channel_layout = default_channel_set[ctx->audio.channels - 1];
705         }
706       } else {
707         // TODO
708       }
709     }
710
711     caps = gst_caps_new_simple (mimetype,
712             "rate", G_TYPE_INT, ctx->audio.sample_rate,
713             "channels", G_TYPE_INT, ctx->audio.channels, NULL);
714
715     pos = gst_ff_channel_layout_to_gst (channel_layout, ctx->audio.channels);
716     if (pos != NULL) {
717       gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
718       g_free (pos);
719     }
720   } else {
721     gint maxchannels = 2;
722     const gint *rates = NULL;
723     gint n_rates = 0;
724
725     if (strcmp (name, "aac") == 0) {
726       maxchannels = 6;
727     } else if (g_str_has_prefix(name, "ac3")) {
728       const static gint l_rates[] = { 48000, 44100, 32000 };
729       maxchannels = 6;
730       n_rates = G_N_ELEMENTS (l_rates);
731       rates = l_rates;
732     } else {
733      // TODO
734     }
735
736     if (maxchannels == 1) {
737       caps = gst_caps_new_simple(mimetype,
738               "channels", G_TYPE_INT, maxchannels, NULL);
739     } else {
740       caps = gst_caps_new_simple(mimetype,
741               "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
742     }
743
744     if (n_rates) {
745       GValue list = { 0, };
746       GstStructure *structure;
747
748       g_value_init(&list, GST_TYPE_LIST);
749       for (i = 0; i < n_rates; i++) {
750         GValue v = { 0, };
751
752         g_value_init(&v, G_TYPE_INT);
753         g_value_set_int(&v, rates[i]);
754         gst_value_list_append_value(&list, &v);
755         g_value_unset(&v);
756       }
757       structure = gst_caps_get_structure(caps, 0);
758       gst_structure_set_value(structure, "rate", &list);
759       g_value_unset(&list);
760     } else {
761       gst_caps_set_simple(caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
762     }
763   }
764
765   for (i = 0; i < gst_caps_get_size (caps); i++) {
766     va_start (var_args, fieldname);
767     structure = gst_caps_get_structure (caps, i);
768     gst_structure_set_valist (structure, fieldname, var_args);
769     va_end (var_args);
770   }
771
772   return caps;
773 }
774
775 GstCaps *
776 gst_maru_pixfmt_to_caps (enum PixelFormat pix_fmt, CodecContext *ctx, const char *name)
777 {
778   GstCaps *caps = NULL;
779
780   int bpp = 0, depth = 0, endianness = 0;
781   gulong g_mask = 0, r_mask = 0, b_mask = 0, a_mask = 0;
782   guint32 fmt = 0;
783
784   switch (pix_fmt) {
785   case PIX_FMT_YUV420P:
786     fmt = GST_MAKE_FOURCC ('I', '4', '2', '0');
787     break;
788   case PIX_FMT_YUYV422:
789     fmt = GST_MAKE_FOURCC ('A', '4', '2', '0');
790     break;
791   case PIX_FMT_RGB24:
792     bpp = depth = 24;
793     endianness = G_BIG_ENDIAN;
794     r_mask = 0xff0000;
795     g_mask = 0x00ff00;
796     b_mask = 0x0000ff;
797     break;
798   case PIX_FMT_BGR24:
799     bpp = depth = 24;
800     endianness = G_BIG_ENDIAN;
801     r_mask = 0x0000ff;
802     g_mask = 0x00ff00;
803     b_mask = 0xff0000;
804     break;
805   case PIX_FMT_YUV422P:
806     fmt = GST_MAKE_FOURCC ('Y', '4', '2', 'B');
807     break;
808   case PIX_FMT_YUV444P:
809     fmt = GST_MAKE_FOURCC ('Y', '4', '4', '4');
810     break;
811   case PIX_FMT_RGB32:
812     bpp = 32;
813     depth = 32;
814     endianness = G_BIG_ENDIAN;
815 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
816     r_mask = 0x00ff0000;
817     g_mask = 0x0000ff00;
818     b_mask = 0x000000ff;
819     a_mask = 0xff000000;
820 #else
821     r_mask = 0x00ff0000;
822     g_mask = 0x0000ff00;
823     b_mask = 0x000000ff;
824     a_mask = 0xff000000;
825 #endif
826     break;
827   case PIX_FMT_YUV410P:
828     fmt = GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
829     break;
830   case PIX_FMT_YUV411P:
831     fmt = GST_MAKE_FOURCC ('Y', '4', '1', 'b');
832     break;
833   case PIX_FMT_RGB565:
834     bpp = depth = 16;
835     endianness = G_BYTE_ORDER;
836     r_mask = 0xf800;
837     g_mask = 0x07e0;
838     b_mask = 0x001f;
839     break;
840   case PIX_FMT_RGB555:
841     bpp = 16;
842     depth = 15;
843     endianness = G_BYTE_ORDER;
844     r_mask = 0x7c00;
845     g_mask = 0x03e0;
846     b_mask = 0x001f;
847     break;
848   default:
849     break;
850   }
851
852   if (caps == NULL) {
853     if (bpp != 0) {
854       if (r_mask != 0) {
855         if (a_mask) {
856         caps = gst_maru_video_caps_new (ctx, name, "video/x-raw-rgb",
857                 "bpp", G_TYPE_INT, bpp,
858                 "depth", G_TYPE_INT, depth,
859                 "red_mask", G_TYPE_INT, r_mask,
860                 "green_mask", G_TYPE_INT, g_mask,
861                 "blue_mask", G_TYPE_INT, b_mask,
862                 "alpha_mask", G_TYPE_INT, a_mask,
863                 "endianness", G_TYPE_INT, endianness, NULL);
864         } else {
865           caps = gst_maru_video_caps_new (ctx, name, "video/x-raw-rgb",
866                   "bpp", G_TYPE_INT, bpp,
867                   "depth", G_TYPE_INT, depth,
868                   "red_mask", G_TYPE_INT, r_mask,
869                   "green_mask", G_TYPE_INT, g_mask,
870                   "blue_mask", G_TYPE_INT, b_mask,
871                   "alpha_mask", G_TYPE_INT, a_mask,
872                   "endianness", G_TYPE_INT, endianness, NULL);
873         }
874       } else {
875         caps = gst_maru_video_caps_new (ctx, name, "video/x-raw-rgb",
876                   "bpp", G_TYPE_INT, bpp,
877                   "depth", G_TYPE_INT, depth,
878                   "endianness", G_TYPE_INT, endianness, NULL);
879         if (caps && ctx) {
880           // set paletee
881         }
882       }
883     } else if (fmt) {
884       caps = gst_maru_video_caps_new (ctx, name, "video/x-raw-yuv",
885                "format", GST_TYPE_FOURCC, fmt, NULL);
886     }
887   }
888
889   if (caps != NULL) {
890     GST_DEBUG ("caps for pix_fmt=%d: %", GST_PTR_FORMAT, pix_fmt, caps);
891   } else {
892     GST_LOG ("No caps found for pix_fmt=%d", pix_fmt);
893   }
894
895   return caps;
896 }
897
898 GstCaps *
899 gst_maru_smpfmt_to_caps (int8_t sample_fmt, CodecContext *ctx, const char *name)
900 {
901   GstCaps *caps = NULL;
902
903   int bpp = 0;
904   gboolean integer = TRUE;
905   gboolean signedness = FALSE;
906
907   switch (sample_fmt) {
908   case SAMPLE_FMT_S16:
909     signedness = TRUE;
910     bpp = 16;
911     break;
912   case SAMPLE_FMT_S32:
913     signedness = TRUE;
914     bpp = 32;
915     break;
916   case SAMPLE_FMT_FLT:
917     integer = FALSE;
918     bpp = 32;
919     break;
920   case SAMPLE_FMT_DBL:
921     integer = FALSE;
922     bpp = 64;
923     break;
924   default:
925     break;
926   }
927
928   if (bpp) {
929     if (integer) {
930       caps = gst_maru_audio_caps_new (ctx, name, "audio/x-raw-int",
931           "signed", G_TYPE_BOOLEAN, signedness,
932           "endianness", G_TYPE_INT, G_BYTE_ORDER,
933           "width", G_TYPE_INT, bpp, "depth", G_TYPE_INT, bpp, NULL);
934     } else {
935       caps = gst_maru_audio_caps_new (ctx, name, "audio/x-raw-float",
936           "endianness", G_TYPE_INT, G_BYTE_ORDER,
937           "width", G_TYPE_INT, bpp, NULL);
938     }
939   }
940
941   if (caps != NULL) {
942     GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
943   } else {
944     GST_LOG ("No caps found for sample_fmt=%d", sample_fmt);
945   }
946
947   return caps;
948 }
949
950 GstCaps *
951 gst_maru_codecname_to_caps (const char *name, CodecContext *ctx, gboolean encode)
952 {
953   GstCaps *caps = NULL;
954
955   GST_LOG ("codec: %s, context: %p, encode: %d", name, ctx, encode);
956
957   if (strcmp (name, "mpegvideo") == 0) {
958     caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
959                 "mpegversion", G_TYPE_INT, 1,
960                 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
961   } else if (strcmp (name, "h263") == 0) {
962     if (encode) {
963       caps = gst_maru_video_caps_new (ctx, name, "video/x-h263",
964                   "variant", G_TYPE_STRING, "itu", NULL);
965     } else {
966       caps = gst_maru_video_caps_new (ctx, "none", "video/x-h263",
967                   "variant", G_TYPE_STRING, "itu", NULL);
968     }
969   } else if (strcmp (name, "h263p") == 0) {
970     caps = gst_maru_video_caps_new (ctx, name, "video/x-h263",
971               "variant", G_TYPE_STRING, "itu",
972               "h263version", G_TYPE_STRING, "h263p", NULL);
973 #if 0
974     if (encode && ctx) {
975       gst_caps_set_simple (caps,
976         "annex-f", G_TYPE_BOOLEAN, ctx->flags & CODEC_FLAG_4MV,
977         "annex-j", G_TYPE_BOOLEAN, ctx->flags & CODEC_FLAG_LOOP_FILTER,
978         "annex-i", G_TYPE_BOOLEAN, ctx->flags & CODEC_FLAG_AC_PRED,
979         "annex-t", G_TYPE_BOOLEAN, ctx->flags & CODEC_FLAG_AC_PRED,
980         NULL);
981     }
982 #endif
983   } else if (strcmp (name, "mpeg4") == 0) {
984     if (encode && ctx != NULL) {
985       // TODO
986     switch (ctx->codec_tag) {
987     case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
988       caps = gst_maru_video_caps_new (ctx, name, "video/x-divx",
989         "divxversion", G_TYPE_INT, 5, NULL);
990       break;
991     case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
992     default:
993       caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
994         "systemstream", G_TYPE_BOOLEAN, FALSE,
995         "mpegversion", G_TYPE_INT, 4, NULL);
996       break;
997     }
998     } else {
999       caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1000             "mpegversion", G_TYPE_INT, 4,
1001             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1002       if (encode) {
1003         caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1004             "mpegversion", G_TYPE_INT, 4,
1005             "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1006       } else {
1007         gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1008             "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL));
1009         gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1010             "video/x-xvid", NULL));
1011         gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1012             "video/x-3ivx", NULL));
1013       }
1014     }
1015   } else if (strcmp (name, "h264") == 0) {
1016       caps = gst_maru_video_caps_new (ctx, name, "video/x-h264", NULL);
1017   } else if (g_str_has_prefix(name, "msmpeg4")) {
1018     // msmpeg4v1,m msmpeg4v2, msmpeg4
1019     gint version;
1020
1021     if (strcmp (name, "msmpeg4v1") == 0) {
1022       version = 41;
1023     } else if (strcmp (name, "msmpeg4v2") == 0) {
1024       version = 42;
1025     } else {
1026       version = 43;
1027     }
1028
1029     caps = gst_maru_video_caps_new (ctx, name, "video/x-msmpeg",
1030           "msmpegversion", G_TYPE_INT, version, NULL);
1031     if (!encode && !strcmp (name, "msmpeg4")) {
1032        gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1033             "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
1034     }
1035   } else if (strcmp (name, "wmv3") == 0) {
1036     caps = gst_maru_video_caps_new (ctx, name, "video/x-wmv",
1037                 "wmvversion", G_TYPE_INT, 3, NULL);
1038   } else if (strcmp (name, "vc1") == 0) {
1039     caps = gst_maru_video_caps_new (ctx, name, "video/x-wmv",
1040                 "wmvversion", G_TYPE_INT, 3, "format", GST_TYPE_FOURCC,
1041                 GST_MAKE_FOURCC ('W', 'V', 'C', '1'),  NULL);
1042 #if 0
1043   } else if (strcmp (name, "vp3") == 0) {
1044     mime_type = g_strdup ("video/x-vp3");
1045   } else if (strcmp (name, "vp8") == 0) {
1046     mime_type = g_strdup ("video/x-vp8");
1047 #endif
1048   } else if (strcmp (name, "aac") == 0) {
1049     caps = gst_maru_audio_caps_new (ctx, name, "audio/mpeg", NULL);
1050     if (!encode) {
1051         GValue arr = { 0, };
1052         GValue item = { 0, };
1053
1054         g_value_init (&arr, GST_TYPE_LIST);
1055         g_value_init (&item, G_TYPE_INT);
1056         g_value_set_int (&item, 2);
1057         gst_value_list_append_value (&arr, &item);
1058         g_value_set_int (&item, 4);
1059         gst_value_list_append_value (&arr, &item);
1060         g_value_unset (&item);
1061
1062         gst_caps_set_value (caps, "mpegversion", &arr);
1063         g_value_unset (&arr);
1064
1065         g_value_init (&arr, GST_TYPE_LIST);
1066         g_value_init (&item, G_TYPE_STRING);
1067         g_value_set_string (&item, "raw");
1068         gst_value_list_append_value (&arr, &item);
1069         g_value_set_string (&item, "adts");
1070         gst_value_list_append_value (&arr, &item);
1071         g_value_set_string (&item, "adif");
1072         gst_value_list_append_value (&arr, &item);
1073         g_value_unset (&item);
1074
1075         gst_caps_set_value (caps, "stream-format", &arr);
1076         g_value_unset (&arr);
1077     } else {
1078       gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 4,
1079         "stream-format", G_TYPE_STRING, "raw",
1080         "base-profile", G_TYPE_STRING, "lc", NULL);
1081
1082         if (ctx && ctx->codecdata_size > 0) {
1083           gst_codec_utils_aac_caps_set_level_and_profile (caps,
1084             ctx->codecdata, ctx->codecdata_size);
1085         }
1086     }
1087   } else if (strcmp (name, "ac3") == 0) {
1088     caps = gst_maru_audio_caps_new (ctx, name, "audio/x-ac3", NULL);
1089   } else if (strcmp (name, "mp3") == 0) {
1090     if (encode) {
1091       caps = gst_maru_audio_caps_new (ctx, name, "audio/mpeg",
1092               "mpegversion", G_TYPE_INT, 1,
1093               "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
1094     } else {
1095       caps = gst_caps_new_simple("audio/mpeg",
1096               "mpegversion", G_TYPE_INT, 1,
1097               "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
1098     }
1099   } else if (strcmp (name, "mp3adu") == 0) {
1100     gchar *mime_type;
1101
1102     mime_type = g_strdup_printf ("audio/x-gst_ff-%s", name);
1103     caps = gst_maru_audio_caps_new (ctx, name, mime_type, NULL);
1104
1105     if (mime_type) {
1106       g_free(mime_type);
1107     }
1108   } else if (g_str_has_prefix(name, "wmav")) {
1109     gint version = 1;
1110     if (strcmp (name, "wmav2") == 0) {
1111       version = 2;
1112     }
1113     caps = gst_maru_audio_caps_new (ctx, name, "audio/x-wma", "wmaversion",
1114           G_TYPE_INT, version, "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
1115           "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
1116   } else {
1117     GST_ERROR("failed to new caps for %s.\n", name);
1118   }
1119
1120   return caps;
1121 }
1122
1123 typedef struct PixFmtInfo
1124 {
1125   uint8_t x_chroma_shift;       /* X chroma subsampling factor is 2 ^ shift */
1126   uint8_t y_chroma_shift;       /* Y chroma subsampling factor is 2 ^ shift */
1127 } PixFmtInfo;
1128
1129 static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
1130
1131 void
1132 gst_maru_init_pix_fmt_info (void)
1133 {
1134   pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1,
1135   pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
1136
1137   pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
1138   pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
1139
1140   pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 0;
1141   pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
1142
1143   pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
1144   pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
1145
1146   pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
1147   pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
1148
1149   pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
1150   pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
1151
1152   /* RGB formats */
1153   pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
1154   pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
1155
1156   pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
1157   pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
1158
1159   pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
1160   pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
1161
1162   pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
1163   pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
1164
1165   pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
1166   pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
1167 }
1168
1169 int
1170 gst_maru_avpicture_size (int pix_fmt, int width, int height)
1171 {
1172   int size, w2, h2, size2;
1173   int stride, stride2;
1174   int fsize;
1175   PixFmtInfo *pinfo;
1176
1177   pinfo = &pix_fmt_info[pix_fmt];
1178
1179   switch (pix_fmt) {
1180   case PIX_FMT_YUV420P:
1181   case PIX_FMT_YUV422P:
1182   case PIX_FMT_YUV444P:
1183   case PIX_FMT_YUV410P:
1184   case PIX_FMT_YUV411P:
1185     stride = ROUND_UP_4(width);
1186     h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
1187     size = stride * h2;
1188     w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
1189     stride2 = ROUND_UP_4(w2);
1190     h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
1191     size2 = stride2 * h2;
1192     fsize = size + 2 * size2;
1193     break;
1194   case PIX_FMT_RGB24:
1195   case PIX_FMT_BGR24:
1196     stride = ROUND_UP_4 (width * 3);
1197     fsize = stride * height;
1198     break;
1199   case PIX_FMT_RGB32:
1200     stride = width * 4;
1201     fsize = stride * height;
1202     break;
1203   case PIX_FMT_RGB555:
1204   case PIX_FMT_RGB565:
1205     stride = ROUND_UP_4 (width * 2);
1206     fsize = stride * height;
1207     break;
1208   default:
1209     fsize = -1;
1210     break;
1211   }
1212
1213   return fsize;
1214 }
1215
1216 int
1217 gst_maru_align_size (int buf_size)
1218 {
1219   int i, align_size;
1220
1221   align_size = buf_size / 1024;
1222
1223   for (i = 0; i < 14; i++) {
1224     if (align_size < (1 << i)) {
1225       align_size = 1024 * (1 << i);
1226       break;
1227     }
1228   }
1229
1230   return align_size;
1231 }