cmd: DIR command outputs free space for the path.
[wine.git] / dlls / winegstreamer / wg_format.c
blobbd0ebf892c19362d804e3bdd0c7b9bf95064fe54
1 /*
2 * GStreamer format helpers
4 * Copyright 2010 Maarten Lankhorst for CodeWeavers
5 * Copyright 2010 Aric Stewart for CodeWeavers
6 * Copyright 2019-2020 Zebediah Figura
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #if 0
24 #pragma makedep unix
25 #endif
27 #include "config.h"
29 #include <assert.h>
30 #include <stdarg.h>
31 #include <stdio.h>
33 #include <gst/gst.h>
34 #include <gst/video/video.h>
35 #include <gst/audio/audio.h>
37 #include "winternl.h"
38 #include "codecapi.h"
39 #include "dshow.h"
41 #include "unix_private.h"
43 static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format)
45 switch (format)
47 case GST_AUDIO_FORMAT_U8:
48 return WG_AUDIO_FORMAT_U8;
49 case GST_AUDIO_FORMAT_S16LE:
50 return WG_AUDIO_FORMAT_S16LE;
51 case GST_AUDIO_FORMAT_S24LE:
52 return WG_AUDIO_FORMAT_S24LE;
53 case GST_AUDIO_FORMAT_S32LE:
54 return WG_AUDIO_FORMAT_S32LE;
55 case GST_AUDIO_FORMAT_F32LE:
56 return WG_AUDIO_FORMAT_F32LE;
57 case GST_AUDIO_FORMAT_F64LE:
58 return WG_AUDIO_FORMAT_F64LE;
59 default:
60 return WG_AUDIO_FORMAT_UNKNOWN;
64 static uint32_t wg_channel_position_from_gst(GstAudioChannelPosition position)
66 static const uint32_t position_map[] =
68 SPEAKER_FRONT_LEFT,
69 SPEAKER_FRONT_RIGHT,
70 SPEAKER_FRONT_CENTER,
71 SPEAKER_LOW_FREQUENCY,
72 SPEAKER_BACK_LEFT,
73 SPEAKER_BACK_RIGHT,
74 SPEAKER_FRONT_LEFT_OF_CENTER,
75 SPEAKER_FRONT_RIGHT_OF_CENTER,
76 SPEAKER_BACK_CENTER,
78 SPEAKER_SIDE_LEFT,
79 SPEAKER_SIDE_RIGHT,
80 SPEAKER_TOP_FRONT_LEFT,
81 SPEAKER_TOP_FRONT_RIGHT,
82 SPEAKER_TOP_FRONT_CENTER,
83 SPEAKER_TOP_CENTER,
84 SPEAKER_TOP_BACK_LEFT,
85 SPEAKER_TOP_BACK_RIGHT,
88 SPEAKER_TOP_BACK_CENTER,
91 if (position == GST_AUDIO_CHANNEL_POSITION_MONO)
92 return SPEAKER_FRONT_CENTER;
94 if (position >= 0 && position < ARRAY_SIZE(position_map))
95 return position_map[position];
96 return 0;
99 static uint32_t wg_channel_mask_from_gst(const GstAudioInfo *info)
101 uint32_t mask = 0, position;
102 unsigned int i;
104 for (i = 0; i < GST_AUDIO_INFO_CHANNELS(info); ++i)
106 if (!(position = wg_channel_position_from_gst(GST_AUDIO_INFO_POSITION(info, i))))
108 GST_WARNING("Unsupported channel %#x.", GST_AUDIO_INFO_POSITION(info, i));
109 return 0;
111 /* Make sure it's also in WinMM order. WinMM mandates that channels be
112 * ordered, as it were, from least to most significant SPEAKER_* bit.
113 * Hence we fail if the current channel was already specified, or if any
114 * higher bit was already specified. */
115 if (mask & ~(position - 1))
117 GST_WARNING("Unsupported channel order.");
118 return 0;
120 mask |= position;
122 return mask;
125 static void wg_format_from_audio_info(struct wg_format *format, const GstAudioInfo *info)
127 format->major_type = WG_MAJOR_TYPE_AUDIO;
128 format->u.audio.format = wg_audio_format_from_gst(GST_AUDIO_INFO_FORMAT(info));
129 format->u.audio.channels = GST_AUDIO_INFO_CHANNELS(info);
130 format->u.audio.channel_mask = wg_channel_mask_from_gst(info);
131 format->u.audio.rate = GST_AUDIO_INFO_RATE(info);
134 static enum wg_video_format wg_video_format_from_gst(GstVideoFormat format)
136 switch (format)
138 case GST_VIDEO_FORMAT_BGRA:
139 return WG_VIDEO_FORMAT_BGRA;
140 case GST_VIDEO_FORMAT_BGRx:
141 return WG_VIDEO_FORMAT_BGRx;
142 case GST_VIDEO_FORMAT_BGR:
143 return WG_VIDEO_FORMAT_BGR;
144 case GST_VIDEO_FORMAT_RGB15:
145 return WG_VIDEO_FORMAT_RGB15;
146 case GST_VIDEO_FORMAT_RGB16:
147 return WG_VIDEO_FORMAT_RGB16;
148 case GST_VIDEO_FORMAT_AYUV:
149 return WG_VIDEO_FORMAT_AYUV;
150 case GST_VIDEO_FORMAT_I420:
151 return WG_VIDEO_FORMAT_I420;
152 case GST_VIDEO_FORMAT_NV12:
153 return WG_VIDEO_FORMAT_NV12;
154 case GST_VIDEO_FORMAT_UYVY:
155 return WG_VIDEO_FORMAT_UYVY;
156 case GST_VIDEO_FORMAT_YUY2:
157 return WG_VIDEO_FORMAT_YUY2;
158 case GST_VIDEO_FORMAT_YV12:
159 return WG_VIDEO_FORMAT_YV12;
160 case GST_VIDEO_FORMAT_YVYU:
161 return WG_VIDEO_FORMAT_YVYU;
162 default:
163 return WG_VIDEO_FORMAT_UNKNOWN;
167 static void wg_format_from_video_info(struct wg_format *format, const GstVideoInfo *info)
169 format->major_type = WG_MAJOR_TYPE_VIDEO;
170 format->u.video.format = wg_video_format_from_gst(GST_VIDEO_INFO_FORMAT(info));
171 format->u.video.width = GST_VIDEO_INFO_WIDTH(info);
172 format->u.video.height = GST_VIDEO_INFO_HEIGHT(info);
173 format->u.video.fps_n = GST_VIDEO_INFO_FPS_N(info);
174 format->u.video.fps_d = GST_VIDEO_INFO_FPS_D(info);
177 static void wg_format_from_caps_audio_mpeg1(struct wg_format *format, const GstCaps *caps)
179 const GstStructure *structure = gst_caps_get_structure(caps, 0);
180 gint layer, channels, rate;
182 if (!gst_structure_get_int(structure, "layer", &layer))
184 GST_WARNING("Missing \"layer\" value.");
185 return;
187 if (!gst_structure_get_int(structure, "channels", &channels))
189 GST_WARNING("Missing \"channels\" value.");
190 return;
192 if (!gst_structure_get_int(structure, "rate", &rate))
194 GST_WARNING("Missing \"rate\" value.");
195 return;
198 format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG1;
199 format->u.audio_mpeg1.layer = layer;
200 format->u.audio_mpeg1.channels = channels;
201 format->u.audio_mpeg1.rate = rate;
204 static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps)
206 const GstStructure *structure = gst_caps_get_structure(caps, 0);
207 gint width, height, fps_n, fps_d;
209 if (!gst_structure_get_int(structure, "width", &width))
211 GST_WARNING("Missing \"width\" value.");
212 return;
214 if (!gst_structure_get_int(structure, "height", &height))
216 GST_WARNING("Missing \"height\" value.");
217 return;
219 if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d))
221 fps_n = 0;
222 fps_d = 1;
225 format->major_type = WG_MAJOR_TYPE_VIDEO_CINEPAK;
226 format->u.video_cinepak.width = width;
227 format->u.video_cinepak.height = height;
228 format->u.video_cinepak.fps_n = fps_n;
229 format->u.video_cinepak.fps_d = fps_d;
232 static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCaps *caps)
234 const GstStructure *structure = gst_caps_get_structure(caps, 0);
235 gint width, height, fps_n, fps_d, wmv_version = 0;
236 gchar format_buffer[5] = {'W','M','V','0',0};
237 enum wg_wmv_video_format wmv_format;
238 const gchar *wmv_format_str = NULL;
240 if (!gst_structure_get_int(structure, "width", &width))
242 GST_WARNING("Missing \"width\" value.");
243 return;
245 if (!gst_structure_get_int(structure, "height", &height))
247 GST_WARNING("Missing \"height\" value.");
248 return;
251 if (!(wmv_format_str = gst_structure_get_string(structure, "format")))
253 if (!gst_structure_get_int(structure, "wmvversion", &wmv_version))
254 GST_WARNING("Unable to get WMV format.");
255 format_buffer[3] += wmv_version;
256 wmv_format_str = format_buffer;
258 if (!strcmp(wmv_format_str, "WMV1"))
259 wmv_format = WG_WMV_VIDEO_FORMAT_WMV1;
260 else if (!strcmp(wmv_format_str, "WMV2"))
261 wmv_format = WG_WMV_VIDEO_FORMAT_WMV2;
262 else if (!strcmp(wmv_format_str, "WMV3"))
263 wmv_format = WG_WMV_VIDEO_FORMAT_WMV3;
264 else if (!strcmp(wmv_format_str, "WMVA"))
265 wmv_format = WG_WMV_VIDEO_FORMAT_WMVA;
266 else if (!strcmp(wmv_format_str, "WVC1"))
267 wmv_format = WG_WMV_VIDEO_FORMAT_WVC1;
268 else
269 wmv_format = WG_WMV_VIDEO_FORMAT_UNKNOWN;
271 if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d))
273 fps_n = 0;
274 fps_d = 1;
277 format->major_type = WG_MAJOR_TYPE_VIDEO_WMV;
278 format->u.video_wmv.width = width;
279 format->u.video_wmv.height = height;
280 format->u.video_wmv.format = wmv_format;
281 format->u.video_wmv.fps_n = fps_n;
282 format->u.video_wmv.fps_d = fps_d;
285 void wg_format_from_caps(struct wg_format *format, const GstCaps *caps)
287 const GstStructure *structure = gst_caps_get_structure(caps, 0);
288 const char *name = gst_structure_get_name(structure);
290 memset(format, 0, sizeof(*format));
292 if (!strcmp(name, "audio/x-raw"))
294 GstAudioInfo info;
296 if (gst_audio_info_from_caps(&info, caps))
297 wg_format_from_audio_info(format, &info);
299 else if (!strcmp(name, "video/x-raw"))
301 GstVideoInfo info;
303 if (gst_video_info_from_caps(&info, caps))
304 wg_format_from_video_info(format, &info);
306 else if (!strcmp(name, "audio/mpeg"))
308 wg_format_from_caps_audio_mpeg1(format, caps);
310 else if (!strcmp(name, "video/x-cinepak"))
312 wg_format_from_caps_video_cinepak(format, caps);
314 else if (!strcmp(name, "video/x-wmv"))
316 wg_format_from_caps_video_wmv(format, caps);
318 else
320 gchar *str = gst_caps_to_string(caps);
322 GST_FIXME("Unhandled caps %s.", str);
323 g_free(str);
327 static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format)
329 switch (format)
331 case WG_AUDIO_FORMAT_U8: return GST_AUDIO_FORMAT_U8;
332 case WG_AUDIO_FORMAT_S16LE: return GST_AUDIO_FORMAT_S16LE;
333 case WG_AUDIO_FORMAT_S24LE: return GST_AUDIO_FORMAT_S24LE;
334 case WG_AUDIO_FORMAT_S32LE: return GST_AUDIO_FORMAT_S32LE;
335 case WG_AUDIO_FORMAT_F32LE: return GST_AUDIO_FORMAT_F32LE;
336 case WG_AUDIO_FORMAT_F64LE: return GST_AUDIO_FORMAT_F64LE;
337 default: return GST_AUDIO_FORMAT_UNKNOWN;
341 static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t mask, uint32_t channel_count)
343 const uint32_t orig_mask = mask;
344 unsigned int i;
345 DWORD bit;
347 static const GstAudioChannelPosition position_map[] =
349 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
350 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
351 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
352 GST_AUDIO_CHANNEL_POSITION_LFE1,
353 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
354 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
355 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
356 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
357 GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
358 GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
359 GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
360 GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
361 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
362 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
363 GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
364 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
365 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
366 GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
369 for (i = 0; i < channel_count; ++i)
371 positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
372 if (BitScanForward(&bit, mask))
374 if (bit < ARRAY_SIZE(position_map))
375 positions[i] = position_map[bit];
376 else
377 GST_WARNING("Invalid channel mask %#x.", orig_mask);
378 mask &= ~(1 << bit);
380 else
382 GST_WARNING("Incomplete channel mask %#x.", orig_mask);
387 static GstCaps *wg_format_to_caps_audio_mpeg1(const struct wg_format *format)
389 GstCaps *caps;
391 if (!(caps = gst_caps_new_empty_simple("audio/mpeg")))
392 return NULL;
394 gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, 1, NULL);
395 gst_caps_set_simple(caps, "layer", G_TYPE_INT, format->u.audio_mpeg1.layer, NULL);
396 gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio_mpeg1.rate, NULL);
397 gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio_mpeg1.channels, NULL);
398 gst_caps_set_simple(caps, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
400 return caps;
403 static GstCaps *wg_format_to_caps_audio_mpeg4(const struct wg_format *format)
405 GstBuffer *buffer;
406 GstCaps *caps;
408 if (!(caps = gst_caps_new_empty_simple("audio/mpeg")))
409 return NULL;
411 gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, 4, NULL);
413 switch (format->u.audio_mpeg4.payload_type)
415 case 0: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "raw", NULL); break;
416 case 1: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "adts", NULL); break;
417 case 2: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "adif", NULL); break;
418 case 3: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "loas", NULL); break;
421 /* FIXME: Use gst_codec_utils_aac_caps_set_level_and_profile from GStreamer pbutils library */
423 if (format->u.audio_mpeg4.codec_data_len)
425 buffer = gst_buffer_new_and_alloc(format->u.audio_mpeg4.codec_data_len);
426 gst_buffer_fill(buffer, 0, format->u.audio_mpeg4.codec_data, format->u.audio_mpeg4.codec_data_len);
427 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
428 gst_buffer_unref(buffer);
431 return caps;
434 static GstCaps *wg_format_to_caps_audio(const struct wg_format *format)
436 GstAudioChannelPosition positions[32];
437 GstAudioFormat audio_format;
438 GstAudioInfo info;
440 if ((audio_format = wg_audio_format_to_gst(format->u.audio.format)) == GST_AUDIO_FORMAT_UNKNOWN)
441 return NULL;
443 wg_channel_mask_to_gst(positions, format->u.audio.channel_mask, format->u.audio.channels);
444 gst_audio_info_set_format(&info, audio_format, format->u.audio.rate, format->u.audio.channels, positions);
445 return gst_audio_info_to_caps(&info);
448 static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format)
450 switch (format)
452 case WG_VIDEO_FORMAT_BGRA: return GST_VIDEO_FORMAT_BGRA;
453 case WG_VIDEO_FORMAT_BGRx: return GST_VIDEO_FORMAT_BGRx;
454 case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR;
455 case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15;
456 case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16;
457 case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV;
458 case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420;
459 case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12;
460 case WG_VIDEO_FORMAT_UYVY: return GST_VIDEO_FORMAT_UYVY;
461 case WG_VIDEO_FORMAT_YUY2: return GST_VIDEO_FORMAT_YUY2;
462 case WG_VIDEO_FORMAT_YV12: return GST_VIDEO_FORMAT_YV12;
463 case WG_VIDEO_FORMAT_YVYU: return GST_VIDEO_FORMAT_YVYU;
464 default: return GST_VIDEO_FORMAT_UNKNOWN;
468 static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
470 GstVideoFormat video_format;
471 GstVideoInfo info;
472 unsigned int i;
473 GstCaps *caps;
475 if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN)
476 return NULL;
478 gst_video_info_set_format(&info, video_format, format->u.video.width, abs(format->u.video.height));
479 if ((caps = gst_video_info_to_caps(&info)))
481 for (i = 0; i < gst_caps_get_size(caps); ++i)
483 GstStructure *structure = gst_caps_get_structure(caps, i);
485 if (!format->u.video.width)
486 gst_structure_remove_fields(structure, "width", NULL);
487 if (!format->u.video.height)
488 gst_structure_remove_fields(structure, "height", NULL);
489 if (!format->u.video.fps_d && !format->u.video.fps_n)
490 gst_structure_remove_fields(structure, "framerate", NULL);
492 /* Remove fields which we don't specify but might have some default value */
493 gst_structure_remove_fields(structure, "colorimetry", "chroma-site", NULL);
496 return caps;
499 static GstCaps *wg_format_to_caps_video_cinepak(const struct wg_format *format)
501 GstCaps *caps;
503 if (!(caps = gst_caps_new_empty_simple("video/x-cinepak")))
504 return NULL;
506 if (format->u.video_cinepak.width)
507 gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_cinepak.width, NULL);
508 if (format->u.video_cinepak.height)
509 gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_cinepak.height, NULL);
510 if (format->u.video_cinepak.fps_d || format->u.video_cinepak.fps_n)
511 gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_cinepak.fps_n, format->u.video_cinepak.fps_d, NULL);
513 return caps;
516 static GstCaps *wg_format_to_caps_audio_wma(const struct wg_format *format)
518 GstBuffer *buffer;
519 GstCaps *caps;
521 if (!(caps = gst_caps_new_empty_simple("audio/x-wma")))
522 return NULL;
523 if (format->u.audio_wma.version)
524 gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.audio_wma.version, NULL);
526 if (format->u.audio_wma.bitrate)
527 gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.audio_wma.bitrate, NULL);
528 if (format->u.audio_wma.rate)
529 gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio_wma.rate, NULL);
530 if (format->u.audio_wma.depth)
531 gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.audio_wma.depth, NULL);
532 if (format->u.audio_wma.channels)
533 gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio_wma.channels, NULL);
534 if (format->u.audio_wma.block_align)
535 gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.audio_wma.block_align, NULL);
537 if (format->u.audio_wma.codec_data_len)
539 if (!(buffer = gst_buffer_new_and_alloc(format->u.audio_wma.codec_data_len)))
541 gst_caps_unref(caps);
542 return NULL;
545 gst_buffer_fill(buffer, 0, format->u.audio_wma.codec_data, format->u.audio_wma.codec_data_len);
546 gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
547 gst_buffer_unref(buffer);
550 return caps;
553 static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format)
555 const char *profile, *level;
556 GstCaps *caps;
558 if (!(caps = gst_caps_new_empty_simple("video/x-h264")))
559 return NULL;
560 gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL);
561 gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL);
563 if (format->u.video_h264.width)
564 gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_h264.width, NULL);
565 if (format->u.video_h264.height)
566 gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_h264.height, NULL);
567 if (format->u.video_h264.fps_n || format->u.video_h264.fps_d)
568 gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_h264.fps_n, format->u.video_h264.fps_d, NULL);
570 switch (format->u.video_h264.profile)
572 case eAVEncH264VProfile_Main: profile = "main"; break;
573 case eAVEncH264VProfile_High: profile = "high"; break;
574 case eAVEncH264VProfile_444: profile = "high-4:4:4"; break;
575 default:
576 GST_FIXME("H264 profile attribute %u not implemented.", format->u.video_h264.profile);
577 /* fallthrough */
578 case eAVEncH264VProfile_unknown:
579 profile = "baseline";
580 break;
582 gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL);
584 switch (format->u.video_h264.level)
586 case eAVEncH264VLevel1: level = "1"; break;
587 case eAVEncH264VLevel1_1: level = "1.1"; break;
588 case eAVEncH264VLevel1_2: level = "1.2"; break;
589 case eAVEncH264VLevel1_3: level = "1.3"; break;
590 case eAVEncH264VLevel2: level = "2"; break;
591 case eAVEncH264VLevel2_1: level = "2.1"; break;
592 case eAVEncH264VLevel2_2: level = "2.2"; break;
593 case eAVEncH264VLevel3: level = "3"; break;
594 case eAVEncH264VLevel3_1: level = "3.1"; break;
595 case eAVEncH264VLevel3_2: level = "3.2"; break;
596 case eAVEncH264VLevel4: level = "4"; break;
597 case eAVEncH264VLevel4_1: level = "4.1"; break;
598 case eAVEncH264VLevel4_2: level = "4.2"; break;
599 case eAVEncH264VLevel5: level = "5"; break;
600 case eAVEncH264VLevel5_1: level = "5.1"; break;
601 case eAVEncH264VLevel5_2: level = "5.2"; break;
602 default:
603 GST_FIXME("H264 level attribute %u not implemented.", format->u.video_h264.level);
604 /* fallthrough */
605 case 0:
606 level = NULL;
607 break;
609 if (level)
610 gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL);
612 return caps;
615 static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format)
617 unsigned int wmv_version;
618 const char *wmv_format;
619 GstCaps *caps;
621 if (!(caps = gst_caps_new_empty_simple("video/x-wmv")))
622 return NULL;
624 switch (format->u.video_wmv.format)
626 case WG_WMV_VIDEO_FORMAT_WMV1:
627 wmv_format = "WMV1";
628 wmv_version = 1;
629 break;
630 case WG_WMV_VIDEO_FORMAT_WMV2:
631 wmv_format = "WMV2";
632 wmv_version = 2;
633 break;
634 case WG_WMV_VIDEO_FORMAT_WMV3:
635 wmv_format = "WMV3";
636 wmv_version = 3;
637 break;
638 case WG_WMV_VIDEO_FORMAT_WMVA:
639 wmv_format = "WMVA";
640 wmv_version = 3;
641 break;
642 case WG_WMV_VIDEO_FORMAT_WVC1:
643 wmv_format = "WVC1";
644 wmv_version = 3;
645 break;
646 default:
647 GST_WARNING("Unknown WMV format %u.", format->u.video_wmv.format);
648 /* fallthrough */
649 case WG_WMV_VIDEO_FORMAT_UNKNOWN:
650 wmv_format = NULL;
651 wmv_version = 0;
652 break;
655 if (wmv_format)
656 gst_caps_set_simple(caps, "format", G_TYPE_STRING, wmv_format, NULL);
657 if (wmv_version)
658 gst_caps_set_simple(caps, "wmvversion", G_TYPE_INT, wmv_version, NULL);
659 if (format->u.video_wmv.width)
660 gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_wmv.width, NULL);
661 if (format->u.video_wmv.height)
662 gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_wmv.height, NULL);
663 if (format->u.video_wmv.fps_d || format->u.video_wmv.fps_n)
664 gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_wmv.fps_n, format->u.video_wmv.fps_d, NULL);
666 return caps;
669 static GstCaps *wg_format_to_caps_video_indeo(const struct wg_format *format)
671 GstCaps *caps;
673 if (!(caps = gst_caps_new_empty_simple("video/x-indeo")))
674 return NULL;
676 if (format->u.video_indeo.width)
677 gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_indeo.width, NULL);
678 if (format->u.video_indeo.height)
679 gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_indeo.height, NULL);
680 if (format->u.video_indeo.fps_d || format->u.video_indeo.fps_n)
681 gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_indeo.fps_n, format->u.video_indeo.fps_d, NULL);
682 if (format->u.video_indeo.version)
683 gst_caps_set_simple(caps, "indeoversion", G_TYPE_INT, format->u.video_indeo.version, NULL);
685 return caps;
688 GstCaps *wg_format_to_caps(const struct wg_format *format)
690 switch (format->major_type)
692 case WG_MAJOR_TYPE_UNKNOWN:
693 return gst_caps_new_any();
694 case WG_MAJOR_TYPE_AUDIO:
695 return wg_format_to_caps_audio(format);
696 case WG_MAJOR_TYPE_AUDIO_MPEG1:
697 return wg_format_to_caps_audio_mpeg1(format);
698 case WG_MAJOR_TYPE_AUDIO_MPEG4:
699 return wg_format_to_caps_audio_mpeg4(format);
700 case WG_MAJOR_TYPE_AUDIO_WMA:
701 return wg_format_to_caps_audio_wma(format);
702 case WG_MAJOR_TYPE_VIDEO:
703 return wg_format_to_caps_video(format);
704 case WG_MAJOR_TYPE_VIDEO_CINEPAK:
705 return wg_format_to_caps_video_cinepak(format);
706 case WG_MAJOR_TYPE_VIDEO_H264:
707 return wg_format_to_caps_video_h264(format);
708 case WG_MAJOR_TYPE_VIDEO_WMV:
709 return wg_format_to_caps_video_wmv(format);
710 case WG_MAJOR_TYPE_VIDEO_INDEO:
711 return wg_format_to_caps_video_indeo(format);
713 assert(0);
714 return NULL;
717 bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
719 if (a->major_type != b->major_type)
720 return false;
722 switch (a->major_type)
724 case WG_MAJOR_TYPE_AUDIO_MPEG1:
725 case WG_MAJOR_TYPE_AUDIO_MPEG4:
726 case WG_MAJOR_TYPE_AUDIO_WMA:
727 case WG_MAJOR_TYPE_VIDEO_H264:
728 case WG_MAJOR_TYPE_VIDEO_WMV:
729 case WG_MAJOR_TYPE_VIDEO_INDEO:
730 GST_FIXME("Format %u not implemented!", a->major_type);
731 /* fallthrough */
732 case WG_MAJOR_TYPE_UNKNOWN:
733 return false;
735 case WG_MAJOR_TYPE_AUDIO:
736 return a->u.audio.format == b->u.audio.format
737 && a->u.audio.channels == b->u.audio.channels
738 && a->u.audio.rate == b->u.audio.rate;
740 case WG_MAJOR_TYPE_VIDEO:
741 /* Do not compare FPS. */
742 return a->u.video.format == b->u.video.format
743 && a->u.video.width == b->u.video.width
744 && abs(a->u.video.height) == abs(b->u.video.height)
745 && EqualRect( &a->u.video.padding, &b->u.video.padding );
747 case WG_MAJOR_TYPE_VIDEO_CINEPAK:
748 /* Do not compare FPS. */
749 return a->u.video_cinepak.width == b->u.video_cinepak.width
750 && a->u.video_cinepak.height == b->u.video_cinepak.height;
753 assert(0);
754 return false;