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
34 #include <gst/video/video.h>
35 #include <gst/audio/audio.h>
41 #include "unix_private.h"
43 static enum wg_audio_format
wg_audio_format_from_gst(GstAudioFormat 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
;
60 return WG_AUDIO_FORMAT_UNKNOWN
;
64 static uint32_t wg_channel_position_from_gst(GstAudioChannelPosition position
)
66 static const uint32_t position_map
[] =
71 SPEAKER_LOW_FREQUENCY
,
74 SPEAKER_FRONT_LEFT_OF_CENTER
,
75 SPEAKER_FRONT_RIGHT_OF_CENTER
,
80 SPEAKER_TOP_FRONT_LEFT
,
81 SPEAKER_TOP_FRONT_RIGHT
,
82 SPEAKER_TOP_FRONT_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
];
99 static uint32_t wg_channel_mask_from_gst(const GstAudioInfo
*info
)
101 uint32_t mask
= 0, position
;
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
));
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.");
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
)
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
;
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.");
187 if (!gst_structure_get_int(structure
, "channels", &channels
))
189 GST_WARNING("Missing \"channels\" value.");
192 if (!gst_structure_get_int(structure
, "rate", &rate
))
194 GST_WARNING("Missing \"rate\" value.");
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.");
214 if (!gst_structure_get_int(structure
, "height", &height
))
216 GST_WARNING("Missing \"height\" value.");
219 if (!gst_structure_get_fraction(structure
, "framerate", &fps_n
, &fps_d
))
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.");
245 if (!gst_structure_get_int(structure
, "height", &height
))
247 GST_WARNING("Missing \"height\" value.");
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
;
269 wmv_format
= WG_WMV_VIDEO_FORMAT_UNKNOWN
;
271 if (!gst_structure_get_fraction(structure
, "framerate", &fps_n
, &fps_d
))
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"))
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"))
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
);
320 gchar
*str
= gst_caps_to_string(caps
);
322 GST_FIXME("Unhandled caps %s.", str
);
327 static GstAudioFormat
wg_audio_format_to_gst(enum wg_audio_format 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
;
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
];
377 GST_WARNING("Invalid channel mask %#x.", orig_mask
);
382 GST_WARNING("Incomplete channel mask %#x.", orig_mask
);
387 static GstCaps
*wg_format_to_caps_audio_mpeg1(const struct wg_format
*format
)
391 if (!(caps
= gst_caps_new_empty_simple("audio/mpeg")))
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
);
403 static GstCaps
*wg_format_to_caps_audio_mpeg4(const struct wg_format
*format
)
408 if (!(caps
= gst_caps_new_empty_simple("audio/mpeg")))
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
);
434 static GstCaps
*wg_format_to_caps_audio(const struct wg_format
*format
)
436 GstAudioChannelPosition positions
[32];
437 GstAudioFormat audio_format
;
440 if ((audio_format
= wg_audio_format_to_gst(format
->u
.audio
.format
)) == GST_AUDIO_FORMAT_UNKNOWN
)
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
)
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
;
475 if ((video_format
= wg_video_format_to_gst(format
->u
.video
.format
)) == GST_VIDEO_FORMAT_UNKNOWN
)
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 if (!format
->u
.video
.width
)
484 gst_structure_remove_fields(gst_caps_get_structure(caps
, i
), "width", NULL
);
485 if (!format
->u
.video
.height
)
486 gst_structure_remove_fields(gst_caps_get_structure(caps
, i
), "height", NULL
);
487 if (!format
->u
.video
.fps_d
&& !format
->u
.video
.fps_n
)
488 gst_structure_remove_fields(gst_caps_get_structure(caps
, i
), "framerate", NULL
);
494 static GstCaps
*wg_format_to_caps_video_cinepak(const struct wg_format
*format
)
498 if (!(caps
= gst_caps_new_empty_simple("video/x-cinepak")))
501 if (format
->u
.video_cinepak
.width
)
502 gst_caps_set_simple(caps
, "width", G_TYPE_INT
, format
->u
.video_cinepak
.width
, NULL
);
503 if (format
->u
.video_cinepak
.height
)
504 gst_caps_set_simple(caps
, "height", G_TYPE_INT
, format
->u
.video_cinepak
.height
, NULL
);
505 if (format
->u
.video_cinepak
.fps_d
|| format
->u
.video_cinepak
.fps_n
)
506 gst_caps_set_simple(caps
, "framerate", GST_TYPE_FRACTION
, format
->u
.video_cinepak
.fps_n
, format
->u
.video_cinepak
.fps_d
, NULL
);
511 static GstCaps
*wg_format_to_caps_audio_wma(const struct wg_format
*format
)
516 if (!(caps
= gst_caps_new_empty_simple("audio/x-wma")))
518 if (format
->u
.audio_wma
.version
)
519 gst_caps_set_simple(caps
, "wmaversion", G_TYPE_INT
, format
->u
.audio_wma
.version
, NULL
);
521 if (format
->u
.audio_wma
.bitrate
)
522 gst_caps_set_simple(caps
, "bitrate", G_TYPE_INT
, format
->u
.audio_wma
.bitrate
, NULL
);
523 if (format
->u
.audio_wma
.rate
)
524 gst_caps_set_simple(caps
, "rate", G_TYPE_INT
, format
->u
.audio_wma
.rate
, NULL
);
525 if (format
->u
.audio_wma
.depth
)
526 gst_caps_set_simple(caps
, "depth", G_TYPE_INT
, format
->u
.audio_wma
.depth
, NULL
);
527 if (format
->u
.audio_wma
.channels
)
528 gst_caps_set_simple(caps
, "channels", G_TYPE_INT
, format
->u
.audio_wma
.channels
, NULL
);
529 if (format
->u
.audio_wma
.block_align
)
530 gst_caps_set_simple(caps
, "block_align", G_TYPE_INT
, format
->u
.audio_wma
.block_align
, NULL
);
532 if (format
->u
.audio_wma
.codec_data_len
)
534 if (!(buffer
= gst_buffer_new_and_alloc(format
->u
.audio_wma
.codec_data_len
)))
536 gst_caps_unref(caps
);
540 gst_buffer_fill(buffer
, 0, format
->u
.audio_wma
.codec_data
, format
->u
.audio_wma
.codec_data_len
);
541 gst_caps_set_simple(caps
, "codec_data", GST_TYPE_BUFFER
, buffer
, NULL
);
542 gst_buffer_unref(buffer
);
548 static GstCaps
*wg_format_to_caps_video_h264(const struct wg_format
*format
)
550 const char *profile
, *level
;
553 if (!(caps
= gst_caps_new_empty_simple("video/x-h264")))
555 gst_caps_set_simple(caps
, "stream-format", G_TYPE_STRING
, "byte-stream", NULL
);
556 gst_caps_set_simple(caps
, "alignment", G_TYPE_STRING
, "au", NULL
);
558 if (format
->u
.video_h264
.width
)
559 gst_caps_set_simple(caps
, "width", G_TYPE_INT
, format
->u
.video_h264
.width
, NULL
);
560 if (format
->u
.video_h264
.height
)
561 gst_caps_set_simple(caps
, "height", G_TYPE_INT
, format
->u
.video_h264
.height
, NULL
);
562 if (format
->u
.video_h264
.fps_n
|| format
->u
.video_h264
.fps_d
)
563 gst_caps_set_simple(caps
, "framerate", GST_TYPE_FRACTION
, format
->u
.video_h264
.fps_n
, format
->u
.video_h264
.fps_d
, NULL
);
565 switch (format
->u
.video_h264
.profile
)
567 case eAVEncH264VProfile_Main
: profile
= "main"; break;
568 case eAVEncH264VProfile_High
: profile
= "high"; break;
569 case eAVEncH264VProfile_444
: profile
= "high-4:4:4"; break;
571 GST_FIXME("H264 profile attribute %u not implemented.", format
->u
.video_h264
.profile
);
573 case eAVEncH264VProfile_unknown
:
574 profile
= "baseline";
577 gst_caps_set_simple(caps
, "profile", G_TYPE_STRING
, profile
, NULL
);
579 switch (format
->u
.video_h264
.level
)
581 case eAVEncH264VLevel1
: level
= "1"; break;
582 case eAVEncH264VLevel1_1
: level
= "1.1"; break;
583 case eAVEncH264VLevel1_2
: level
= "1.2"; break;
584 case eAVEncH264VLevel1_3
: level
= "1.3"; break;
585 case eAVEncH264VLevel2
: level
= "2"; break;
586 case eAVEncH264VLevel2_1
: level
= "2.1"; break;
587 case eAVEncH264VLevel2_2
: level
= "2.2"; break;
588 case eAVEncH264VLevel3
: level
= "3"; break;
589 case eAVEncH264VLevel3_1
: level
= "3.1"; break;
590 case eAVEncH264VLevel3_2
: level
= "3.2"; break;
591 case eAVEncH264VLevel4
: level
= "4"; break;
592 case eAVEncH264VLevel4_1
: level
= "4.1"; break;
593 case eAVEncH264VLevel4_2
: level
= "4.2"; break;
594 case eAVEncH264VLevel5
: level
= "5"; break;
595 case eAVEncH264VLevel5_1
: level
= "5.1"; break;
596 case eAVEncH264VLevel5_2
: level
= "5.2"; break;
598 GST_FIXME("H264 level attribute %u not implemented.", format
->u
.video_h264
.level
);
605 gst_caps_set_simple(caps
, "level", G_TYPE_STRING
, level
, NULL
);
610 static GstCaps
*wg_format_to_caps_video_wmv(const struct wg_format
*format
)
612 unsigned int wmv_version
;
613 const char *wmv_format
;
616 if (!(caps
= gst_caps_new_empty_simple("video/x-wmv")))
619 switch (format
->u
.video_wmv
.format
)
621 case WG_WMV_VIDEO_FORMAT_WMV1
:
625 case WG_WMV_VIDEO_FORMAT_WMV2
:
629 case WG_WMV_VIDEO_FORMAT_WMV3
:
633 case WG_WMV_VIDEO_FORMAT_WMVA
:
637 case WG_WMV_VIDEO_FORMAT_WVC1
:
642 GST_WARNING("Unknown WMV format %u.", format
->u
.video_wmv
.format
);
644 case WG_WMV_VIDEO_FORMAT_UNKNOWN
:
651 gst_caps_set_simple(caps
, "format", G_TYPE_STRING
, wmv_format
, NULL
);
653 gst_caps_set_simple(caps
, "wmvversion", G_TYPE_INT
, wmv_version
, NULL
);
654 if (format
->u
.video_wmv
.width
)
655 gst_caps_set_simple(caps
, "width", G_TYPE_INT
, format
->u
.video_wmv
.width
, NULL
);
656 if (format
->u
.video_wmv
.height
)
657 gst_caps_set_simple(caps
, "height", G_TYPE_INT
, format
->u
.video_wmv
.height
, NULL
);
658 if (format
->u
.video_wmv
.fps_d
|| format
->u
.video_wmv
.fps_n
)
659 gst_caps_set_simple(caps
, "framerate", GST_TYPE_FRACTION
, format
->u
.video_wmv
.fps_n
, format
->u
.video_wmv
.fps_d
, NULL
);
664 static GstCaps
*wg_format_to_caps_video_indeo(const struct wg_format
*format
)
668 if (!(caps
= gst_caps_new_empty_simple("video/x-indeo")))
671 if (format
->u
.video_indeo
.width
)
672 gst_caps_set_simple(caps
, "width", G_TYPE_INT
, format
->u
.video_indeo
.width
, NULL
);
673 if (format
->u
.video_indeo
.height
)
674 gst_caps_set_simple(caps
, "height", G_TYPE_INT
, format
->u
.video_indeo
.height
, NULL
);
675 if (format
->u
.video_indeo
.fps_d
|| format
->u
.video_indeo
.fps_n
)
676 gst_caps_set_simple(caps
, "framerate", GST_TYPE_FRACTION
, format
->u
.video_indeo
.fps_n
, format
->u
.video_indeo
.fps_d
, NULL
);
677 if (format
->u
.video_indeo
.version
)
678 gst_caps_set_simple(caps
, "indeoversion", G_TYPE_INT
, format
->u
.video_indeo
.version
, NULL
);
683 GstCaps
*wg_format_to_caps(const struct wg_format
*format
)
685 switch (format
->major_type
)
687 case WG_MAJOR_TYPE_UNKNOWN
:
688 return gst_caps_new_any();
689 case WG_MAJOR_TYPE_AUDIO
:
690 return wg_format_to_caps_audio(format
);
691 case WG_MAJOR_TYPE_AUDIO_MPEG1
:
692 return wg_format_to_caps_audio_mpeg1(format
);
693 case WG_MAJOR_TYPE_AUDIO_MPEG4
:
694 return wg_format_to_caps_audio_mpeg4(format
);
695 case WG_MAJOR_TYPE_AUDIO_WMA
:
696 return wg_format_to_caps_audio_wma(format
);
697 case WG_MAJOR_TYPE_VIDEO
:
698 return wg_format_to_caps_video(format
);
699 case WG_MAJOR_TYPE_VIDEO_CINEPAK
:
700 return wg_format_to_caps_video_cinepak(format
);
701 case WG_MAJOR_TYPE_VIDEO_H264
:
702 return wg_format_to_caps_video_h264(format
);
703 case WG_MAJOR_TYPE_VIDEO_WMV
:
704 return wg_format_to_caps_video_wmv(format
);
705 case WG_MAJOR_TYPE_VIDEO_INDEO
:
706 return wg_format_to_caps_video_indeo(format
);
712 bool wg_format_compare(const struct wg_format
*a
, const struct wg_format
*b
)
714 if (a
->major_type
!= b
->major_type
)
717 switch (a
->major_type
)
719 case WG_MAJOR_TYPE_AUDIO_MPEG1
:
720 case WG_MAJOR_TYPE_AUDIO_MPEG4
:
721 case WG_MAJOR_TYPE_AUDIO_WMA
:
722 case WG_MAJOR_TYPE_VIDEO_H264
:
723 case WG_MAJOR_TYPE_VIDEO_WMV
:
724 case WG_MAJOR_TYPE_VIDEO_INDEO
:
725 GST_FIXME("Format %u not implemented!", a
->major_type
);
727 case WG_MAJOR_TYPE_UNKNOWN
:
730 case WG_MAJOR_TYPE_AUDIO
:
731 return a
->u
.audio
.format
== b
->u
.audio
.format
732 && a
->u
.audio
.channels
== b
->u
.audio
.channels
733 && a
->u
.audio
.rate
== b
->u
.audio
.rate
;
735 case WG_MAJOR_TYPE_VIDEO
:
736 /* Do not compare FPS. */
737 return a
->u
.video
.format
== b
->u
.video
.format
738 && a
->u
.video
.width
== b
->u
.video
.width
739 && abs(a
->u
.video
.height
) == abs(b
->u
.video
.height
)
740 && EqualRect( &a
->u
.video
.padding
, &b
->u
.video
.padding
);
742 case WG_MAJOR_TYPE_VIDEO_CINEPAK
:
743 /* Do not compare FPS. */
744 return a
->u
.video_cinepak
.width
== b
->u
.video_cinepak
.width
745 && a
->u
.video_cinepak
.height
== b
->u
.video_cinepak
.height
;