2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "gstmaruutils.h"
22 #include <gst/audio/audio-channels.h>
23 #include <gst/pbutils/codec-utils.h>
27 GstVideoFormat format;
28 enum PixelFormat pixfmt;
32 static const PixToFmt pixtofmttable[] = {
33 /* GST_VIDEO_FORMAT_I420, */
34 {GST_VIDEO_FORMAT_I420, PIX_FMT_YUV420P},
35 /* Note : this should use a different chroma placement */
36 {GST_VIDEO_FORMAT_I420, PIX_FMT_YUVJ420P},
38 /* GST_VIDEO_FORMAT_YV12, */
39 /* GST_VIDEO_FORMAT_YUY2, */
40 {GST_VIDEO_FORMAT_YUY2, PIX_FMT_YUYV422},
41 /* GST_VIDEO_FORMAT_UYVY, */
42 {GST_VIDEO_FORMAT_UYVY, PIX_FMT_UYVY422},
43 /* GST_VIDEO_FORMAT_AYUV, */
44 /* GST_VIDEO_FORMAT_RGBx, */
45 /* GST_VIDEO_FORMAT_BGRx, */
46 /* GST_VIDEO_FORMAT_xRGB, */
47 /* GST_VIDEO_FORMAT_xBGR, */
48 /* GST_VIDEO_FORMAT_RGBA, */
49 {GST_VIDEO_FORMAT_RGBA, PIX_FMT_RGBA},
50 /* GST_VIDEO_FORMAT_BGRA, */
51 {GST_VIDEO_FORMAT_BGRA, PIX_FMT_BGRA},
52 /* GST_VIDEO_FORMAT_ARGB, */
53 {GST_VIDEO_FORMAT_ARGB, PIX_FMT_ARGB},
54 /* GST_VIDEO_FORMAT_ABGR, */
55 {GST_VIDEO_FORMAT_ABGR, PIX_FMT_ABGR},
56 /* GST_VIDEO_FORMAT_RGB, */
57 {GST_VIDEO_FORMAT_RGB, PIX_FMT_RGB24},
58 /* GST_VIDEO_FORMAT_BGR, */
59 {GST_VIDEO_FORMAT_BGR, PIX_FMT_BGR24},
60 /* GST_VIDEO_FORMAT_Y41B, */
61 {GST_VIDEO_FORMAT_Y41B, PIX_FMT_YUV411P},
62 /* GST_VIDEO_FORMAT_Y42B, */
63 {GST_VIDEO_FORMAT_Y42B, PIX_FMT_YUV422P},
64 {GST_VIDEO_FORMAT_Y42B, PIX_FMT_YUVJ422P},
65 /* GST_VIDEO_FORMAT_YVYU, */
66 /* GST_VIDEO_FORMAT_Y444, */
67 {GST_VIDEO_FORMAT_Y444, PIX_FMT_YUV444P},
68 {GST_VIDEO_FORMAT_Y444, PIX_FMT_YUVJ444P},
69 /* GST_VIDEO_FORMAT_v210, */
70 /* GST_VIDEO_FORMAT_v216, */
71 /* GST_VIDEO_FORMAT_NV12, */
72 {GST_VIDEO_FORMAT_NV12, PIX_FMT_NV12},
73 /* GST_VIDEO_FORMAT_NV21, */
74 {GST_VIDEO_FORMAT_NV21, PIX_FMT_NV21},
75 /* GST_VIDEO_FORMAT_GRAY8, */
76 {GST_VIDEO_FORMAT_GRAY8, PIX_FMT_GRAY8},
77 /* GST_VIDEO_FORMAT_GRAY16_BE, */
78 {GST_VIDEO_FORMAT_GRAY16_BE, PIX_FMT_GRAY16BE},
79 /* GST_VIDEO_FORMAT_GRAY16_LE, */
80 {GST_VIDEO_FORMAT_GRAY16_LE, PIX_FMT_GRAY16LE},
81 /* GST_VIDEO_FORMAT_v308, */
82 /* GST_VIDEO_FORMAT_Y800, */
83 /* GST_VIDEO_FORMAT_Y16, */
84 /* GST_VIDEO_FORMAT_RGB16, */
85 {GST_VIDEO_FORMAT_RGB16, PIX_FMT_RGB565},
86 /* GST_VIDEO_FORMAT_BGR16, */
87 /* GST_VIDEO_FORMAT_RGB15, */
88 {GST_VIDEO_FORMAT_RGB15, PIX_FMT_RGB555},
89 /* GST_VIDEO_FORMAT_BGR15, */
90 /* GST_VIDEO_FORMAT_UYVP, */
91 /* GST_VIDEO_FORMAT_A420, */
92 {GST_VIDEO_FORMAT_A420, PIX_FMT_YUVA420P},
93 /* GST_VIDEO_FORMAT_RGB8_PALETTED, */
94 {GST_VIDEO_FORMAT_RGB8P, PIX_FMT_PAL8},
95 /* GST_VIDEO_FORMAT_YUV9, */
96 {GST_VIDEO_FORMAT_YUV9, PIX_FMT_YUV410P},
97 /* GST_VIDEO_FORMAT_YVU9, */
98 /* GST_VIDEO_FORMAT_IYU1, */
99 /* GST_VIDEO_FORMAT_ARGB64, */
100 /* GST_VIDEO_FORMAT_AYUV64, */
101 /* GST_VIDEO_FORMAT_r210, */
102 {GST_VIDEO_FORMAT_I420_10LE, PIX_FMT_YUV420P10LE},
103 {GST_VIDEO_FORMAT_I420_10BE, PIX_FMT_YUV420P10BE},
104 {GST_VIDEO_FORMAT_I422_10LE, PIX_FMT_YUV422P10LE},
105 {GST_VIDEO_FORMAT_I422_10BE, PIX_FMT_YUV422P10BE},
106 {GST_VIDEO_FORMAT_Y444_10LE, PIX_FMT_YUV444P10LE},
107 {GST_VIDEO_FORMAT_Y444_10BE, PIX_FMT_YUV444P10BE},
111 gst_maru_smpfmt_depth (int32_t smp_fmt)
113 GST_DEBUG (" >> ENTER ");
122 case SAMPLE_FMT_S16P:
127 case SAMPLE_FMT_S32P:
128 case SAMPLE_FMT_FLTP:
132 case SAMPLE_FMT_DBLP:
136 GST_ERROR ("Unhandled sample format !");
147 GstAudioChannelPosition gst;
148 } _ff_to_gst_layout[] = {
150 CH_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
151 CH_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
152 CH_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
153 CH_LOW_FREQUENCY, GST_AUDIO_CHANNEL_POSITION_LFE1}, {
154 CH_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT}, {
155 CH_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
156 CH_FRONT_LEFT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER}, {
157 CH_FRONT_RIGHT_OF_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER}, {
158 CH_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
159 CH_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT}, {
160 CH_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}, {
161 CH_TOP_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
162 CH_TOP_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
163 CH_TOP_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
164 CH_TOP_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
165 CH_TOP_BACK_LEFT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
166 CH_TOP_BACK_CENTER, GST_AUDIO_CHANNEL_POSITION_NONE}, {
167 CH_TOP_BACK_RIGHT, GST_AUDIO_CHANNEL_POSITION_NONE}, {
168 CH_STEREO_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT}, {
169 CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
173 gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos,
178 gint channels_found = 0;
183 for (i = 0; i < channels; i++) {
184 for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) {
185 if (_ff_to_gst_layout[j].gst == pos[i]) {
186 ret |= _ff_to_gst_layout[j].ff;
193 if (channels_found != channels)
199 gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
200 GstAudioChannelPosition * pos)
203 gboolean none_layout = FALSE;
205 if (channel_layout == 0) {
206 nchannels = channels;
211 for (i = 0; i < 64; i++) {
212 if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
217 if (nchannels != channels) {
218 GST_ERROR ("Number of channels is different (%u != %u)", channels,
220 nchannels = channels;
224 for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
225 if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
226 pos[j++] = _ff_to_gst_layout[i].gst;
228 if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE)
233 if (j != nchannels) {
235 ("Unknown channels in channel layout - assuming NONE layout");
242 && !gst_audio_check_valid_channel_positions (pos, nchannels, FALSE)) {
243 GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
244 " - assuming NONE layout", channel_layout);
249 if (nchannels == 1) {
250 pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
251 } else if (nchannels == 2) {
252 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
253 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
257 for (i = 0; i < nchannels; i++)
258 pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
266 _gst_value_list_contains (const GValue * list, const GValue * value)
271 n = gst_value_list_get_size (list);
272 for (i = 0; i < n; i++) {
273 tmp = gst_value_list_get_value (list, i);
274 if (gst_value_compare (value, tmp) == GST_VALUE_EQUAL)
282 gst_maru_video_set_pix_fmts (GstCaps * caps, const int32_t *fmts)
286 GstVideoFormat format;
289 if (!fmts || fmts[0] == -1) {
291 g_value_init (&va, GST_TYPE_LIST);
292 g_value_init (&v, G_TYPE_STRING);
293 for (i = 0; i <= PIX_FMT_NB; i++) {
294 format = gst_maru_pixfmt_to_videoformat (i);
295 if (format == GST_VIDEO_FORMAT_UNKNOWN)
297 g_value_set_string (&v, gst_video_format_to_string (format));
298 gst_value_list_append_value (&va, &v);
300 gst_caps_set_value (caps, "format", &va);
306 /* Only a single format */
307 g_value_init (&va, GST_TYPE_LIST);
308 g_value_init (&v, G_TYPE_STRING);
311 format = gst_maru_pixfmt_to_videoformat (fmts[i]);
312 if (format != GST_VIDEO_FORMAT_UNKNOWN) {
313 g_value_set_string (&v, gst_video_format_to_string (format));
314 /* Only append values we don't have yet */
315 if (!_gst_value_list_contains (&va, &v))
316 gst_value_list_append_value (&va, &v);
320 if (gst_value_list_get_size (&va) == 1) {
321 /* The single value is still in v */
322 gst_caps_set_value (caps, "format", &v);
323 } else if (gst_value_list_get_size (&va) > 1) {
324 gst_caps_set_value (caps, "format", &va);
331 caps_has_field (GstCaps * caps, const gchar * field)
335 n = gst_caps_get_size (caps);
336 for (i = 0; i < n; i++) {
337 GstStructure *s = gst_caps_get_structure (caps, i);
339 if (gst_structure_has_field (s, field))
347 gst_maru_codectype_to_video_caps (CodecContext *ctx, const char *name,
348 gboolean encode, CodecElement *codec)
350 GST_DEBUG (" >> ENTER ");
354 GST_DEBUG ("context: %p, codec: %s, encode: %d, pixel format: %d",
355 ctx, name, encode, ctx->video.pix_fmt);
357 GST_DEBUG ("context: %p, codec: %s, encode: %d",
362 caps = gst_maru_pixfmt_to_caps (ctx->video.pix_fmt, ctx, name);
365 gst_maru_video_caps_new (ctx, name, "video/x-raw", NULL);
366 if (!caps_has_field (caps, "format"))
367 gst_maru_video_set_pix_fmts (caps, codec ? codec->pix_fmts : NULL);
374 gst_maru_codectype_to_audio_caps (CodecContext *ctx, const char *name,
375 gboolean encode, CodecElement *codec)
377 GST_DEBUG (" >> ENTER ");
378 GstCaps *caps = NULL;
380 GST_DEBUG ("context: %p, codec: %s, encode: %d, codec: %p",
381 ctx, name, encode, codec);
384 caps = gst_maru_smpfmt_to_caps (ctx->audio.sample_fmt, ctx, name);
385 } else if (codec && codec->sample_fmts[0] != -1){
389 caps = gst_caps_new_empty ();
390 for (i = 0; codec->sample_fmts[i] != -1; i++) {
391 int8_t sample_fmt = -1;
393 sample_fmt = codec->sample_fmts[i];
394 if (!strcmp(name, "aac") && encode) {
395 sample_fmt = SAMPLE_FMT_S16;
396 GST_DEBUG ("convert sample_fmt. codec %s, encode %d, sample_fmt %d",
397 name, encode, sample_fmt);
401 gst_maru_smpfmt_to_caps (sample_fmt, ctx, name);
403 gst_caps_append (caps, temp);
409 CodecContext ctx = {{0}, {0}, 0};
411 ctx.audio.channels = -1;
412 caps = gst_caps_new_empty ();
413 for (i = 0; i <= SAMPLE_FMT_DBL; i++) {
414 temp = gst_maru_smpfmt_to_caps (i, encode ? &ctx : NULL, name);
416 gst_caps_append (caps, temp);
425 gst_maru_codectype_to_caps (int media_type, CodecContext *ctx,
426 const char *name, gboolean encode)
428 GST_DEBUG (" >> ENTER ");
431 switch (media_type) {
432 case AVMEDIA_TYPE_VIDEO:
434 gst_maru_codectype_to_video_caps (ctx, name, encode, NULL);
436 case AVMEDIA_TYPE_AUDIO:
438 gst_maru_codectype_to_audio_caps (ctx, name, encode, NULL);
449 gst_maru_caps_to_pixfmt (const GstCaps *caps, CodecContext *ctx, gboolean raw)
451 GST_DEBUG (" >> ENTER ");
454 const GValue *par = NULL;
456 GST_DEBUG ("converting caps %" GST_PTR_FORMAT, caps);
457 g_return_if_fail (gst_caps_get_size (caps) == 1);
458 str = gst_caps_get_structure (caps, 0);
460 gst_structure_get_int (str, "width", &ctx->video.width);
461 gst_structure_get_int (str, "height", &ctx->video.height);
462 gst_structure_get_int (str, "bpp", &ctx->video.bpp);
464 fps = gst_structure_get_value (str, "framerate");
465 if (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)) {
466 ctx->video.fps_d = gst_value_get_fraction_numerator (fps);
467 ctx->video.fps_n = gst_value_get_fraction_denominator (fps);
468 ctx->video.ticks_per_frame = 1;
470 GST_DEBUG ("setting framerate %d/%d = %lf",
471 ctx->video.fps_d, ctx->video.fps_n,
472 1. * ctx->video.fps_d / ctx->video.fps_n);
475 par = gst_structure_get_value (str, "pixel-aspect-ratio");
476 if (par && GST_VALUE_HOLDS_FRACTION (par)) {
477 ctx->video.par_n = gst_value_get_fraction_numerator (par);
478 ctx->video.par_d = gst_value_get_fraction_denominator (par);
485 g_return_if_fail (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps));
487 if (strcmp (gst_structure_get_name (str), "video/x-raw-yuv") == 0) {
490 if ((format = gst_structure_get_string (str, "format"))) {
491 if (g_str_equal (format, "YUY2"))
492 ctx->video.pix_fmt = PIX_FMT_YUYV422;
493 else if (g_str_equal (format, "I420"))
494 ctx->video.pix_fmt = PIX_FMT_YUV420P;
495 else if (g_str_equal (format, "A420"))
496 ctx->video.pix_fmt = PIX_FMT_YUVA420P;
497 else if (g_str_equal (format, "Y41B"))
498 ctx->video.pix_fmt = PIX_FMT_YUV411P;
499 else if (g_str_equal (format, "Y42B"))
500 ctx->video.pix_fmt = PIX_FMT_YUV422P;
501 else if (g_str_equal (format, "YUV9"))
502 ctx->video.pix_fmt = PIX_FMT_YUV410P;
504 GST_WARNING ("couldn't convert format %s" " to a pixel format",
508 } else if (strcmp (gst_structure_get_name (str), "video/x-raw-rgb") == 0) {
509 gint bpp = 0, rmask = 0, endianness = 0;
511 if (gst_structure_get_int (str, "bpp", &bpp) &&
512 gst_structure_get_int (str, "endianness", &endianness)) {
513 if (gst_structure_get_int (str, "red_mask", &rmask)) {
516 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
517 if (rmask == 0x00ff0000) {
519 if (rmask == 0x00ff0000) {
521 ctx->video.pix_fmt = PIX_FMT_RGB32;
525 if (rmask == 0x0000FF) {
526 ctx->video.pix_fmt = PIX_FMT_BGR24;
528 ctx->video.pix_fmt = PIX_FMT_RGB24;
532 if (endianness == G_BYTE_ORDER) {
533 ctx->video.pix_fmt = PIX_FMT_RGB565;
537 if (endianness == G_BYTE_ORDER) {
538 ctx->video.pix_fmt = PIX_FMT_RGB555;
547 ctx->video.pix_fmt = PIX_FMT_PAL8;
551 } else if (strcmp (gst_structure_get_name (str), "video/x-raw-gray") == 0) {
554 if (gst_structure_get_int (str, "bpp", &bpp)) {
557 ctx->video.pix_fmt = PIX_FMT_GRAY8;
565 gst_maru_caps_to_smpfmt (const GstCaps *caps, CodecContext *ctx, gboolean raw)
567 GST_DEBUG (" >> ENTER ");
569 gint depth = 0, width = 0, endianness = 0;
570 gboolean signedness = FALSE;
573 g_return_if_fail (gst_caps_get_size (caps) == 1);
574 str = gst_caps_get_structure (caps, 0);
576 gst_structure_get_int (str, "channels", &ctx->audio.channels);
577 gst_structure_get_int (str, "rate", &ctx->audio.sample_rate);
578 gst_structure_get_int (str, "block_align", &ctx->audio.block_align);
579 gst_structure_get_int (str, "bitrate", &ctx->bit_rate);
585 name = gst_structure_get_name (str);
587 GST_ERROR ("Couldn't get audio sample format from caps %" GST_PTR_FORMAT, caps);
591 if (!strcmp (name, "audio/x-raw-float")) {
592 if (gst_structure_get_int (str, "width", &width) &&
593 gst_structure_get_int (str, "endianness", &endianness)) {
594 if (endianness == G_BYTE_ORDER) {
596 ctx->audio.sample_fmt = SAMPLE_FMT_FLT;
597 } else if (width == 64) {
598 ctx->audio.sample_fmt = SAMPLE_FMT_DBL;
603 if (gst_structure_get_int (str, "width", &width) &&
604 gst_structure_get_int (str, "depth", &depth) &&
605 gst_structure_get_boolean (str, "signed", &signedness) &&
606 gst_structure_get_int (str, "endianness", &endianness)) {
607 if ((endianness == G_BYTE_ORDER) && (signedness == TRUE)) {
608 if ((width == 16) && (depth == 16)) {
609 ctx->audio.sample_fmt = SAMPLE_FMT_S16;
610 } else if ((width == 32) && (depth == 32)) {
611 ctx->audio.sample_fmt = SAMPLE_FMT_S32;
619 gst_maru_caps_with_codecname (const char *name, int media_type,
620 const GstCaps *caps, CodecContext *ctx)
622 GST_DEBUG (" >> ENTER ");
623 GstStructure *structure;
627 if (!ctx || !gst_caps_get_size (caps)) {
631 structure = gst_caps_get_structure (caps, 0);
633 if ((value = gst_structure_get_value (structure, "codec_data"))) {
638 buf = (GstBuffer *) gst_value_get_buffer (value);
639 gst_buffer_map (buf, &mapinfo, GST_MAP_READ);
642 gst_buffer_unmap (buf, &mapinfo);
643 GST_DEBUG ("extradata: %p, size: %d", data, size);
645 if (ctx->codecdata) {
646 g_free (ctx->codecdata);
650 g_malloc0 (GST_ROUND_UP_16 (size + FF_INPUT_BUFFER_PADDING_SIZE));
651 memcpy (ctx->codecdata, data, size);
652 ctx->codecdata_size = size;
654 if ((strcmp (name, "vc1") == 0) && size > 0 && data[0] == 0) {
655 ctx->codecdata[0] = (guint8) size;
657 } else if (ctx->codecdata == NULL) {
658 ctx->codecdata_size = 0;
659 ctx->codecdata = g_malloc0 (GST_ROUND_UP_16(FF_INPUT_BUFFER_PADDING_SIZE));
660 GST_DEBUG ("no extra data");
663 if ((strcmp (name, "mpeg4") == 0)) {
664 const gchar *mime = gst_structure_get_name (structure);
666 GST_ERROR ("Couldn't get mime type from caps %" GST_PTR_FORMAT, caps);
670 if (!strcmp (mime, "video/x-divx")) {
671 ctx->codec_tag = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
672 } else if (!strcmp (mime, "video/x-xvid")) {
673 ctx->codec_tag = GST_MAKE_FOURCC ('X', 'V', 'I', 'D');
674 } else if (!strcmp (mime, "video/x-3ivx")) {
675 ctx->codec_tag = GST_MAKE_FOURCC ('3', 'I', 'V', '1');
676 } else if (!strcmp (mime, "video/mpeg")) {
677 ctx->codec_tag = GST_MAKE_FOURCC ('m', 'p', '4', 'v');
683 if (!gst_caps_is_fixed (caps)) {
687 switch (media_type) {
688 case AVMEDIA_TYPE_VIDEO:
689 gst_maru_caps_to_pixfmt (caps, ctx, FALSE);
692 case AVMEDIA_TYPE_AUDIO:
693 gst_maru_caps_to_smpfmt (caps, ctx, FALSE);
700 #define CODEC_NAME_BUFFER_SIZE 32
703 gst_maru_caps_to_codecname (const GstCaps *caps,
705 CodecContext *context)
707 GST_DEBUG (" >> ENTER ");
708 const gchar *mimetype;
709 const GstStructure *str;
710 int media_type = AVMEDIA_TYPE_UNKNOWN;
712 str = gst_caps_get_structure (caps, 0);
714 mimetype = gst_structure_get_name (str);
716 GST_ERROR ("Couldn't get mimetype from caps %" GST_PTR_FORMAT, caps);
720 if (!strcmp (mimetype, "video/x-h263")) {
721 const gchar *h263version = gst_structure_get_string (str, "h263version");
722 if (h263version && !strcmp (h263version, "h263p")) {
723 g_strlcpy (codec_name, "h263p", CODEC_NAME_BUFFER_SIZE);
725 g_strlcpy (codec_name, "h263", CODEC_NAME_BUFFER_SIZE);
727 media_type = AVMEDIA_TYPE_VIDEO;
728 } else if (!strcmp (mimetype, "video/mpeg")) {
732 if (gst_structure_get_boolean (str, "systemstream", &sys_strm) &&
733 gst_structure_get_int (str, "mpegversion", &mpegversion) &&
735 switch (mpegversion) {
737 g_strlcpy (codec_name, "mpeg1video", CODEC_NAME_BUFFER_SIZE);
740 g_strlcpy (codec_name, "mpeg2video", CODEC_NAME_BUFFER_SIZE);
743 g_strlcpy (codec_name, "mpeg4", CODEC_NAME_BUFFER_SIZE);
748 media_type = AVMEDIA_TYPE_VIDEO;
749 } else if (!strcmp (mimetype, "video/x-wmv")) {
752 if (gst_structure_get_int (str, "wmvversion", &wmvversion)) {
753 switch (wmvversion) {
755 g_strlcpy (codec_name, "wmv1", CODEC_NAME_BUFFER_SIZE);
758 g_strlcpy (codec_name, "wmv2", CODEC_NAME_BUFFER_SIZE);
762 g_strlcpy (codec_name, "wmv3", CODEC_NAME_BUFFER_SIZE);
764 if ((format = gst_structure_get_string (str, "format"))) {
765 if ((g_str_equal (format, "WVC1")) || (g_str_equal (format, "WMVA"))) {
766 g_strlcpy (codec_name, "vc1", CODEC_NAME_BUFFER_SIZE);
774 media_type = AVMEDIA_TYPE_VIDEO;
775 } else if (!strcmp (mimetype, "audio/mpeg")) {
777 gint mpegversion = 0;
779 if (gst_structure_get_int (str, "mpegversion", &mpegversion)) {
780 switch (mpegversion) {
783 g_strlcpy (codec_name, "aac", CODEC_NAME_BUFFER_SIZE);
786 if (gst_structure_get_int (str, "layer", &layer)) {
789 g_strlcpy (codec_name, "mp1", CODEC_NAME_BUFFER_SIZE);
792 g_strlcpy (codec_name, "mp2", CODEC_NAME_BUFFER_SIZE);
795 g_strlcpy (codec_name, "mp3", CODEC_NAME_BUFFER_SIZE);
803 media_type = AVMEDIA_TYPE_AUDIO;
804 } else if (!strcmp (mimetype, "audio/x-wma")) {
807 if (gst_structure_get_int (str, "wmaversion", &wmaversion)) {
808 switch (wmaversion) {
810 g_strlcpy (codec_name, "wmav1", CODEC_NAME_BUFFER_SIZE);
813 g_strlcpy (codec_name, "wmav2", CODEC_NAME_BUFFER_SIZE);
816 g_strlcpy (codec_name, "wmapro", CODEC_NAME_BUFFER_SIZE);
821 media_type = AVMEDIA_TYPE_AUDIO;
822 } else if (!strcmp (mimetype, "audio/x-ac3")) {
823 g_strlcpy (codec_name, "ac3", CODEC_NAME_BUFFER_SIZE);
824 media_type = AVMEDIA_TYPE_AUDIO;
825 } else if (!strcmp (mimetype, "audio/x-msmpeg")) {
826 gint msmpegversion = 0;
828 if (gst_structure_get_int (str, "msmpegversion", &msmpegversion)) {
829 switch (msmpegversion) {
831 g_strlcpy (codec_name, "msmpeg4v1", CODEC_NAME_BUFFER_SIZE);
834 g_strlcpy (codec_name, "msmpeg4v2", CODEC_NAME_BUFFER_SIZE);
837 g_strlcpy (codec_name, "msmpeg4", CODEC_NAME_BUFFER_SIZE);
842 media_type = AVMEDIA_TYPE_VIDEO;
843 } else if (!strcmp (mimetype, "video/x-h264")) {
844 g_strlcpy (codec_name, "h264", CODEC_NAME_BUFFER_SIZE);
845 media_type = AVMEDIA_TYPE_VIDEO;
848 if (context != NULL) {
849 gst_maru_caps_with_codecname (codec_name, media_type, caps, context);
852 if (codec_name != NULL) {
853 GST_DEBUG ("The %s belongs to the caps %" GST_PTR_FORMAT, codec_name, caps);
855 GST_WARNING ("Couldn't figure out the name for caps %" GST_PTR_FORMAT, caps);
860 gst_maru_caps_with_codectype (int media_type, const GstCaps *caps, CodecContext *ctx)
862 GST_DEBUG (" >> ENTER ");
867 switch (media_type) {
868 case AVMEDIA_TYPE_VIDEO:
869 gst_maru_caps_to_pixfmt (caps, ctx, TRUE);
871 case AVMEDIA_TYPE_AUDIO:
872 gst_maru_caps_to_smpfmt (caps, ctx, TRUE);
880 gst_maru_video_caps_new (CodecContext *ctx, const char *name,
881 const char *mimetype, const char *fieldname, ...)
883 GST_DEBUG (" >> ENTER ");
884 GstCaps *caps = NULL;
888 GST_DEBUG ("context: %p, name: %s, mimetype: %s", ctx, name, mimetype);
890 if (ctx != NULL && ctx->video.width != -1) {
893 caps = gst_caps_new_simple (mimetype,
894 "width", G_TYPE_INT, ctx->video.width,
895 "height", G_TYPE_INT, ctx->video.height, NULL);
897 num = ctx->video.fps_d / ctx->video.ticks_per_frame;
898 denom = ctx->video.fps_n;
901 GST_DEBUG ("invalid framerate: %d/0, -> %d/1", num, num);
904 if (gst_util_fraction_compare (num, denom, 1000, 1) > 0) {
905 GST_DEBUG ("excessive framerate: %d/%d, -> 0/1", num, denom);
909 GST_DEBUG ("setting framerate: %d/%d", num, denom);
910 gst_caps_set_simple (caps,
911 "framerate", GST_TYPE_FRACTION, num, denom, NULL);
913 if (strcmp (name, "h263") == 0) {
914 /* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
915 * because we want automatic negotiation to go as close to 320x240 as
917 const static gint widths[] = { 352, 704, 176, 1408, 128 };
918 const static gint heights[] = { 288, 576, 144, 1152, 96 };
920 gint n_sizes = G_N_ELEMENTS (widths);
922 caps = gst_caps_new_empty ();
923 for (i = 0; i < n_sizes; i++) {
924 temp = gst_caps_new_simple (mimetype,
925 "width", G_TYPE_INT, widths[i],
926 "height", G_TYPE_INT, heights[i],
927 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
929 gst_caps_append (caps, temp);
931 } else if (strcmp (name, "none") == 0) {
932 GST_DEBUG ("default caps");
936 /* no fixed caps or special restrictions applied;
937 * default unfixed setting */
939 GST_DEBUG ("Creating default caps");
940 caps = gst_caps_new_empty_simple (mimetype);
943 va_start (var_args, fieldname);
944 gst_caps_set_simple_valist (caps, fieldname, var_args);
951 gst_maru_audio_caps_new (CodecContext *ctx, const char *name,
952 const char *mimetype, const char *fieldname, ...)
954 GST_DEBUG (" >> ENTER ");
956 GstCaps *caps = NULL;
960 if (ctx != NULL && ctx->audio.channels != -1) {
961 GstAudioChannelPosition pos[64];
964 caps = gst_caps_new_simple (mimetype,
965 "rate", G_TYPE_INT, ctx->audio.sample_rate,
966 "channels", G_TYPE_INT, ctx->audio.channels, NULL);
968 if (ctx->audio.channels > 1 &&
969 gst_ffmpeg_channel_layout_to_gst (ctx->audio.channel_layout,
970 ctx->audio.channels, pos) &&
971 gst_audio_channel_positions_to_mask (pos, ctx->audio.channels, FALSE,
973 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, mask, NULL);
976 gint maxchannels = 2;
977 const gint *rates = NULL;
980 if (strcmp (name, "aac") == 0) {
982 } else if (g_str_has_prefix(name, "ac3")) {
983 const static gint l_rates[] = { 48000, 44100, 32000 };
985 n_rates = G_N_ELEMENTS (l_rates);
990 //TODO Not use the mono type at the moment.
991 /* if (maxchannels == 1) {
992 caps = gst_caps_new_simple(mimetype,
993 "channels", G_TYPE_INT, maxchannels, NULL);
995 caps = gst_caps_new_simple(mimetype,
996 "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
999 caps = gst_caps_new_simple(mimetype,
1000 "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
1002 GValue list = { 0, };
1003 //GstStructure *structure;
1005 g_value_init(&list, GST_TYPE_LIST);
1006 for (i = 0; i < n_rates; i++) {
1009 g_value_init(&v, G_TYPE_INT);
1010 g_value_set_int(&v, rates[i]);
1011 gst_value_list_append_value(&list, &v);
1014 gst_caps_set_value (caps, "rate", &list);
1015 g_value_unset(&list);
1017 gst_caps_set_simple(caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
1021 va_start (var_args, fieldname);
1022 gst_caps_set_simple_valist (caps, fieldname, var_args);
1029 gst_maru_pixfmt_to_caps (enum PixelFormat pix_fmt, CodecContext *ctx, const char *name)
1031 GST_DEBUG (" >> ENTER ");
1032 GstCaps *caps = NULL;
1033 GstVideoFormat format;
1035 format = gst_maru_pixfmt_to_videoformat (pix_fmt);
1037 if (format != GST_VIDEO_FORMAT_UNKNOWN) {
1038 caps = gst_maru_video_caps_new (ctx, name, "video/x-raw",
1039 "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
1043 GST_DEBUG ("caps for pix_fmt=%d: %" GST_PTR_FORMAT, pix_fmt, caps);
1045 GST_DEBUG ("No caps found for pix_fmt=%d", pix_fmt);
1052 gst_maru_pixfmt_to_videoformat (enum PixelFormat pixfmt)
1056 for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++)
1057 if (pixtofmttable[i].pixfmt == pixfmt)
1058 return pixtofmttable[i].format;
1060 return GST_VIDEO_FORMAT_UNKNOWN;
1064 gst_maru_videoformat_to_pixfmt (GstVideoFormat format)
1068 for (i = 0; i < G_N_ELEMENTS (pixtofmttable); i++)
1069 if (pixtofmttable[i].format == format)
1070 return pixtofmttable[i].pixfmt;
1071 return PIX_FMT_NONE;
1075 gst_maru_videoinfo_to_context (GstVideoInfo * info, CodecContext * context)
1079 context->video.width = GST_VIDEO_INFO_WIDTH (info);
1080 context->video.height = GST_VIDEO_INFO_HEIGHT (info);
1081 for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
1082 bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
1083 context->video.bpp = bpp;
1085 context->video.ticks_per_frame = 1;
1086 if (GST_VIDEO_INFO_FPS_N (info) == 0) {
1087 GST_DEBUG ("Using 25/1 framerate");
1088 context->video.fps_d = 25;
1089 context->video.fps_n = 1;
1091 context->video.fps_d = GST_VIDEO_INFO_FPS_N (info);
1092 context->video.fps_n = GST_VIDEO_INFO_FPS_D (info);
1095 context->video.par_n = GST_VIDEO_INFO_PAR_N (info);
1096 context->video.par_d = GST_VIDEO_INFO_PAR_D (info);
1098 context->video.pix_fmt =
1099 gst_maru_videoformat_to_pixfmt (GST_VIDEO_INFO_FORMAT (info));
1103 gst_maru_smpfmt_to_caps (int8_t sample_fmt, CodecContext *ctx, const char *name)
1105 GstCaps *caps = NULL;
1106 GstAudioFormat format;
1108 format = gst_maru_smpfmt_to_audioformat (sample_fmt);
1110 if (format != GST_AUDIO_FORMAT_UNKNOWN) {
1111 caps = gst_maru_audio_caps_new (ctx, name, "audio/x-raw",
1112 "format", G_TYPE_STRING, gst_audio_format_to_string (format),
1113 "layout", G_TYPE_STRING, "interleaved", NULL);
1114 GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
1116 GST_LOG ("No caps found for sample_fmt=%d", sample_fmt);
1123 gst_maru_codecname_to_caps (const char *name, CodecContext *ctx, gboolean encode)
1125 GST_DEBUG (" >> ENTER");
1126 GstCaps *caps = NULL;
1128 GST_DEBUG ("codec: %s, context: %p, encode: %d", name, ctx, encode);
1130 if (strcmp (name, "mpegvideo") == 0) {
1131 caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1132 "mpegversion", G_TYPE_INT, 1,
1133 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1134 } else if (strcmp (name, "h263") == 0) {
1136 caps = gst_maru_video_caps_new (ctx, name, "video/x-h263",
1137 "variant", G_TYPE_STRING, "itu", NULL);
1139 caps = gst_maru_video_caps_new (ctx, "none", "video/x-h263",
1140 "variant", G_TYPE_STRING, "itu", NULL);
1142 } else if (strcmp (name, "h263p") == 0) {
1143 caps = gst_maru_video_caps_new (ctx, name, "video/x-h263",
1144 "variant", G_TYPE_STRING, "itu",
1145 "h263version", G_TYPE_STRING, "h263p", NULL);
1146 } else if (strcmp (name, "mpeg2video") == 0) {
1148 caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1149 "mpegversion", G_TYPE_INT, 2,
1150 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1152 caps = gst_caps_new_simple ("video/mpeg",
1153 "mpegversion", GST_TYPE_INT_RANGE, 1, 2,
1154 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1156 } else if (strcmp (name, "mpeg4") == 0) {
1157 if (encode && ctx != NULL) {
1159 switch (ctx->codec_tag) {
1160 case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'):
1161 caps = gst_maru_video_caps_new (ctx, name, "video/x-divx",
1162 "divxversion", G_TYPE_INT, 5, NULL);
1164 case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
1166 caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1167 "systemstream", G_TYPE_BOOLEAN, FALSE,
1168 "mpegversion", G_TYPE_INT, 4, NULL);
1172 caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1173 "mpegversion", G_TYPE_INT, 4,
1174 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1176 caps = gst_maru_video_caps_new (ctx, name, "video/mpeg",
1177 "mpegversion", G_TYPE_INT, 4,
1178 "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
1180 gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1181 "video/x-divx", "divxversion", GST_TYPE_INT_RANGE, 4, 5, NULL));
1182 gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1183 "video/x-xvid", NULL));
1184 gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1185 "video/x-3ivx", NULL));
1188 } else if ((strcmp (name, "h264") == 0) || (strcmp (name, "libx264") == 0)) {
1189 caps = gst_maru_video_caps_new (ctx, name, "video/x-h264", NULL);
1190 } else if (g_str_has_prefix(name, "msmpeg4")) {
1191 // msmpeg4v1,m msmpeg4v2, msmpeg4
1194 if (strcmp (name, "msmpeg4v1") == 0) {
1196 } else if (strcmp (name, "msmpeg4v2") == 0) {
1202 caps = gst_maru_video_caps_new (ctx, name, "video/x-msmpeg",
1203 "msmpegversion", G_TYPE_INT, version, NULL);
1204 if (!encode && !strcmp (name, "msmpeg4")) {
1205 gst_caps_append (caps, gst_maru_video_caps_new (ctx, name,
1206 "video/x-divx", "divxversion", G_TYPE_INT, 3, NULL));
1208 } else if (strcmp (name, "wmv3") == 0) {
1209 caps = gst_maru_video_caps_new (ctx, name, "video/x-wmv",
1210 "wmvversion", G_TYPE_INT, 3, NULL);
1211 } else if (strcmp (name, "vc1") == 0) {
1212 caps = gst_maru_video_caps_new (ctx, name, "video/x-wmv",
1213 "wmvversion", G_TYPE_INT, 3, "format",
1214 G_TYPE_STRING, "WVC1", NULL);
1215 } else if (strcmp (name, "aac") == 0) {
1216 caps = gst_maru_audio_caps_new (ctx, name, "audio/mpeg", NULL);
1218 GValue arr = { 0, };
1219 GValue item = { 0, };
1221 g_value_init (&arr, GST_TYPE_LIST);
1222 g_value_init (&item, G_TYPE_INT);
1223 g_value_set_int (&item, 2);
1224 gst_value_list_append_value (&arr, &item);
1225 g_value_set_int (&item, 4);
1226 gst_value_list_append_value (&arr, &item);
1227 g_value_unset (&item);
1229 gst_caps_set_value (caps, "mpegversion", &arr);
1230 g_value_unset (&arr);
1232 g_value_init (&arr, GST_TYPE_LIST);
1233 g_value_init (&item, G_TYPE_STRING);
1234 g_value_set_string (&item, "raw");
1235 gst_value_list_append_value (&arr, &item);
1236 g_value_set_string (&item, "adts");
1237 gst_value_list_append_value (&arr, &item);
1238 g_value_set_string (&item, "adif");
1239 gst_value_list_append_value (&arr, &item);
1240 g_value_unset (&item);
1242 gst_caps_set_value (caps, "stream-format", &arr);
1243 g_value_unset (&arr);
1245 gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 4,
1246 "stream-format", G_TYPE_STRING, "raw",
1247 "base-profile", G_TYPE_STRING, "lc", NULL);
1249 if (ctx && ctx->codecdata_size > 0) {
1250 gst_codec_utils_aac_caps_set_level_and_profile (caps,
1251 ctx->codecdata, ctx->codecdata_size);
1254 } else if (strcmp (name, "ac3") == 0) {
1255 caps = gst_maru_audio_caps_new (ctx, name, "audio/x-ac3", NULL);
1256 } else if (strcmp (name, "mp3") == 0) {
1258 caps = gst_maru_audio_caps_new (ctx, name, "audio/mpeg",
1259 "mpegversion", G_TYPE_INT, 1,
1260 "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
1262 caps = gst_caps_new_simple("audio/mpeg",
1263 "mpegversion", G_TYPE_INT, 1,
1264 "layer", GST_TYPE_INT_RANGE, 1, 3, NULL);
1266 } else if (strcmp (name, "mp3adu") == 0) {
1269 mime_type = g_strdup_printf ("audio/x-gst_ff-%s", name);
1270 caps = gst_maru_audio_caps_new (ctx, name, mime_type, NULL);
1275 } else if (g_str_has_prefix(name, "wmav")) {
1277 if (strcmp (name, "wmav2") == 0) {
1280 caps = gst_maru_audio_caps_new (ctx, name, "audio/x-wma", "wmaversion",
1281 G_TYPE_INT, version, "block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
1282 "bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
1284 GST_ERROR("failed to new caps for %s", name);
1288 GST_DEBUG ("caps is NOT null");
1289 if (ctx && ctx->codecdata_size > 0) {
1290 GST_DEBUG ("codec_data size %d", ctx->codecdata_size);
1292 GstBuffer *data = gst_buffer_new_and_alloc (ctx->codecdata_size);
1294 gst_buffer_fill (data, 0, ctx->codecdata, ctx->codecdata_size);
1295 gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, data, NULL);
1296 gst_buffer_unref (data);
1298 GST_DEBUG ("caps for codec %s %" GST_PTR_FORMAT, name, caps);
1300 GST_DEBUG ("No caps found for codec %s", name);
1306 typedef struct PixFmtInfo
1308 uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */
1309 uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */
1312 static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
1315 gst_maru_init_pix_fmt_info (void)
1317 GST_DEBUG (" >> ENTER ");
1318 pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1,
1319 pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
1321 pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
1322 pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
1324 pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 0;
1325 pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
1327 pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
1328 pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
1330 pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
1331 pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
1333 pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
1334 pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
1337 pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
1338 pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
1340 pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
1341 pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
1343 pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
1344 pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
1346 pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
1347 pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
1349 pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
1350 pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
1354 gst_maru_avpicture_size (int pix_fmt, int width, int height)
1356 GST_DEBUG (" >> ENTER ");
1357 int size, w2, h2, size2;
1358 int stride, stride2;
1362 pinfo = &pix_fmt_info[pix_fmt];
1365 case PIX_FMT_YUV420P:
1366 case PIX_FMT_YUV422P:
1367 case PIX_FMT_YUV444P:
1368 case PIX_FMT_YUV410P:
1369 case PIX_FMT_YUV411P:
1370 stride = ROUND_UP_4(width);
1371 h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
1373 w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
1374 stride2 = ROUND_UP_4(w2);
1375 h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
1376 size2 = stride2 * h2;
1377 fsize = size + 2 * size2;
1381 stride = ROUND_UP_4 (width * 3);
1382 fsize = stride * height;
1386 fsize = stride * height;
1388 case PIX_FMT_RGB555:
1389 case PIX_FMT_RGB565:
1390 stride = ROUND_UP_4 (width * 2);
1391 fsize = stride * height;
1402 gst_maru_align_size (int buf_size)
1404 GST_DEBUG (" >> ENTER ");
1407 align_size = buf_size / 1024;
1409 for (i = 0; i < 14; i++) {
1410 if (align_size < (1 << i)) {
1411 align_size = 1024 * (1 << i);
1420 gst_maru_smpfmt_to_audioformat(int32_t sample_fmt)
1422 switch (sample_fmt) {
1424 case SAMPLE_FMT_U8P:
1425 return GST_AUDIO_FORMAT_U8;
1427 case SAMPLE_FMT_S16:
1428 case SAMPLE_FMT_S16P:
1429 return GST_AUDIO_FORMAT_S16;
1431 case SAMPLE_FMT_S32:
1432 case SAMPLE_FMT_S32P:
1433 return GST_AUDIO_FORMAT_S32;
1435 case SAMPLE_FMT_FLT:
1436 case SAMPLE_FMT_FLTP:
1437 return GST_AUDIO_FORMAT_F32;
1439 case SAMPLE_FMT_DBL:
1440 case SAMPLE_FMT_DBLP:
1441 return GST_AUDIO_FORMAT_F64;
1445 return GST_AUDIO_FORMAT_UNKNOWN;
1451 gst_maru_channel_layout_to_gst (guint64 channel_layout, gint channels,
1452 GstAudioChannelPosition * pos)
1454 guint nchannels = 0;
1455 gboolean none_layout = FALSE;
1457 if (channel_layout == 0) {
1458 nchannels = channels;
1463 for (i = 0; i < 64; i++) {
1464 if ((channel_layout & (G_GUINT64_CONSTANT (1) << i)) != 0) {
1469 if (nchannels != channels) {
1470 GST_ERROR ("Number of channels is different (%u != %u)", channels,
1472 nchannels = channels;
1476 for (i = 0, j = 0; i < G_N_ELEMENTS (_ff_to_gst_layout); i++) {
1477 if ((channel_layout & _ff_to_gst_layout[i].ff) != 0) {
1478 pos[j++] = _ff_to_gst_layout[i].gst;
1480 if (_ff_to_gst_layout[i].gst == GST_AUDIO_CHANNEL_POSITION_NONE)
1485 if (j != nchannels) {
1487 ("Unknown channels in channel layout - assuming NONE layout");
1494 && !gst_audio_check_valid_channel_positions (pos, nchannels, FALSE)) {
1495 GST_ERROR ("Invalid channel layout %" G_GUINT64_FORMAT
1496 " - assuming NONE layout", channel_layout);
1501 if (nchannels == 1) {
1502 pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
1503 } else if (nchannels == 2) {
1504 pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
1505 pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
1509 for (i = 0; i < nchannels; i++)
1510 pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
1518 gst_maru_audioinfo_to_context (GstAudioInfo *info, CodecContext *context)
1520 const CodecElement *codec = context->codec;
1521 enum SampleFormat smpl_fmts[4];
1522 enum SampleFormat smpl_fmt = -1;
1525 context->audio.channels = info->channels;
1526 context->audio.sample_rate = info->rate;
1527 context->audio.channel_layout =
1528 gst_ffmpeg_channel_positions_to_layout (info->position, info->channels);
1531 GST_ERROR ("invalid codec");
1535 for (i = 0; i < 4; i++) {
1536 smpl_fmts[i] = codec->sample_fmts[i];
1539 switch (info->finfo->format) {
1540 case GST_AUDIO_FORMAT_F32:
1541 if (smpl_fmts[0] != -1) {
1542 while (smpl_fmts[i] != -1) {
1543 if (smpl_fmts[i] == SAMPLE_FMT_FLT) {
1544 smpl_fmt = smpl_fmts[i];
1546 } else if (smpl_fmts[i] == SAMPLE_FMT_FLTP) {
1547 smpl_fmt = smpl_fmts[i];
1553 smpl_fmt = SAMPLE_FMT_FLT;
1556 case GST_AUDIO_FORMAT_F64:
1557 if (smpl_fmts[0] != -1) {
1558 while (smpl_fmts[i] != -1) {
1559 if (smpl_fmts[i] == SAMPLE_FMT_DBL) {
1560 smpl_fmt = smpl_fmts[i];
1562 } else if (smpl_fmts[i] == SAMPLE_FMT_DBLP) {
1563 smpl_fmt = smpl_fmts[i];
1569 smpl_fmt = SAMPLE_FMT_DBL;
1572 case GST_AUDIO_FORMAT_S32:
1573 if (smpl_fmts[0] != -1) {
1574 while (smpl_fmts[i] != -1) {
1575 if (smpl_fmts[i] == SAMPLE_FMT_S32) {
1576 smpl_fmt = smpl_fmts[i];
1578 } else if (smpl_fmts[i] == SAMPLE_FMT_S32P) {
1579 smpl_fmt = smpl_fmts[i];
1585 smpl_fmt = SAMPLE_FMT_S32;
1588 case GST_AUDIO_FORMAT_S16:
1589 if (smpl_fmts[0] != -1) {
1590 while (smpl_fmts[i] != -1) {
1591 if (smpl_fmts[i] == SAMPLE_FMT_S16) {
1592 smpl_fmt = smpl_fmts[i];
1594 } else if (smpl_fmts[i] == SAMPLE_FMT_S16P) {
1595 smpl_fmt = smpl_fmts[i];
1601 smpl_fmt = SAMPLE_FMT_S16;
1604 case GST_AUDIO_FORMAT_U8:
1605 if (smpl_fmts[0] != -1) {
1606 while (smpl_fmts[i] != -1) {
1607 if (smpl_fmts[i] == SAMPLE_FMT_U8) {
1608 smpl_fmt = smpl_fmts[i];
1610 } else if (smpl_fmts[i] == SAMPLE_FMT_U8P) {
1611 smpl_fmt = smpl_fmts[i];
1617 smpl_fmt = SAMPLE_FMT_U8;
1624 g_assert (smpl_fmt != -1);
1626 context->audio.sample_fmt = smpl_fmt;