Since we are adding more and more media formats to wg_format, the current wg_format struct is getting ugly.
Everytime we add a video format, we need to duplicate width, height, fps. Everytime we add a audio format, we need to duplicate channels, rate. So it would be better if we could share width, height, fps fields between different video formats, also share channels and rate fields between different audio formats.
What makes me found the current wg_format is not in a good shape is when I was writting code for Proton, I found that I need to write some code like this if want to get width/height/fps from a wg_format:
```
static bool get_video_info_from_wg_format(struct wg_format *format, int32_t *width, int32_t *height, uint32_t *fps_n, uint32_t *fps_d) { switch (format->major_type) { case WG_MAJOR_TYPE_VIDEO: *width = format->u.video.width; *height = format->u.video.height; *fps_n = format->u.video.fps_n; *fps_d = format->u.video.fps_d; return true;
case WG_MAJOR_TYPE_VIDEO_CINEPAK: *width = format->u.video_cinepak.width; *height = format->u.video_cinepak.height; *fps_n = format->u.video_cinepak.fps_n; *fps_d = format->u.video_cinepak.fps_d; return true;
case WG_MAJOR_TYPE_VIDEO_H264: *width = format->u.video_h264.width; *height = format->u.video_h264.height; *fps_n = format->u.video_h264.fps_n; *fps_d = format->u.video_h264.fps_d; return true;
case WG_MAJOR_TYPE_VIDEO_WMV: *width = format->u.video_wmv.width; *height = format->u.video_wmv.height; *fps_n = format->u.video_wmv.fps_n; *fps_d = format->u.video_wmv.fps_d; return true;
case WG_MAJOR_TYPE_VIDEO_INDEO: *width = format->u.video_indeo.width; *height = format->u.video_indeo.height; *fps_n = format->u.video_indeo.fps_n; *fps_d = format->u.video_indeo.fps_d; return true;
case WG_MAJOR_TYPE_VIDEO_MPEG1: *width = format->u.video_mpeg1.width; *height = format->u.video_mpeg1.height; *fps_n = format->u.video_mpeg1.fps_n; *fps_d = format->u.video_mpeg1.fps_d; return true;
default: GST_ERROR("Type %d is not a video format.\n", format->major_type); return false; } }
```
Apparently, the code above is ugly. By refactoring wg_format, we can avoid code like this.
This patch is a draft now, it only contains unixlib.h code.
Zeb, I'd like to confirm that if this refactoring would be acceptable for you. If do, I'll continue finishing the remaining parts.
-- v6: winegstreamer: Refactor wg_format.
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/aac_decoder.c | 6 +- dlls/winegstreamer/gst_private.h | 4 +- dlls/winegstreamer/main.c | 58 +++- dlls/winegstreamer/mfplat.c | 104 +++--- dlls/winegstreamer/quartz_parser.c | 477 +++++++++++++------------- dlls/winegstreamer/quartz_transform.c | 14 +- dlls/winegstreamer/unix_private.h | 2 + dlls/winegstreamer/unixlib.h | 107 ++---- dlls/winegstreamer/video_decoder.c | 6 +- dlls/winegstreamer/wg_format.c | 388 ++++++++++++--------- dlls/winegstreamer/wg_parser.c | 13 +- dlls/winegstreamer/wg_transform.c | 110 +++--- dlls/winegstreamer/wm_reader.c | 122 ++++--- dlls/winegstreamer/wma_decoder.c | 26 +- dlls/winegstreamer/wmv_decoder.c | 14 +- 15 files changed, 782 insertions(+), 669 deletions(-)
diff --git a/dlls/winegstreamer/aac_decoder.c b/dlls/winegstreamer/aac_decoder.c index 5844de33ceb..df5ec68f3a1 100644 --- a/dlls/winegstreamer/aac_decoder.c +++ b/dlls/winegstreamer/aac_decoder.c @@ -596,7 +596,11 @@ HRESULT aac_decoder_create(REFIID riid, void **ret) .rate = 44100, }, }; - static const struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_AUDIO_MPEG4}; + static const struct wg_format input_format = + { + .major_type = WG_MAJOR_TYPE_AUDIO, + .u.audio.format = WG_AUDIO_FORMAT_MPEG4 + }; struct wg_transform_attrs attrs = {0}; wg_transform_t transform; struct aac_decoder *decoder; diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 2374fb6fddd..2291be8fd2a 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -146,8 +146,10 @@ HRESULT wg_transform_read_dmo(wg_transform_t transform, DMO_OUTPUT_DATA_BUFFER * HRESULT gstreamer_byte_stream_handler_create(REFIID riid, void **obj);
unsigned int wg_format_get_stride(const struct wg_format *format); - bool wg_video_format_is_rgb(enum wg_video_format format); +bool wg_format_is_uncompressed(const struct wg_format *format); +bool wg_format_is_compressed(const struct wg_format *format); +bool wg_format_is_wmv(const struct wg_format *format);
HRESULT aac_decoder_create(REFIID riid, void **ret); HRESULT h264_decoder_create(REFIID riid, void **ret); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index d4f5db04a15..87db14c2059 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -652,6 +652,37 @@ bool wg_video_format_is_rgb(enum wg_video_format format) case WG_VIDEO_FORMAT_RGB16: return true;
+ default: + return false; + } +} + +bool wg_format_is_uncompressed(const struct wg_format *format) +{ + switch (format->major_type) + { + case WG_MAJOR_TYPE_AUDIO: + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_U8: + case WG_AUDIO_FORMAT_S16LE: + case WG_AUDIO_FORMAT_S24LE: + case WG_AUDIO_FORMAT_S32LE: + case WG_AUDIO_FORMAT_F32LE: + case WG_AUDIO_FORMAT_F64LE: + return true; + default: + return false; + } + + case WG_MAJOR_TYPE_VIDEO: + switch (format->u.video.format) + { + case WG_VIDEO_FORMAT_BGRA: + case WG_VIDEO_FORMAT_BGRx: + case WG_VIDEO_FORMAT_BGR: + case WG_VIDEO_FORMAT_RGB15: + case WG_VIDEO_FORMAT_RGB16: case WG_VIDEO_FORMAT_AYUV: case WG_VIDEO_FORMAT_I420: case WG_VIDEO_FORMAT_NV12: @@ -659,11 +690,32 @@ bool wg_video_format_is_rgb(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: case WG_VIDEO_FORMAT_YV12: case WG_VIDEO_FORMAT_YVYU: - case WG_VIDEO_FORMAT_UNKNOWN: - break; + return true; + default: + return false; + } + + default: + return false; } +}
- return false; +bool wg_format_is_compressed(const struct wg_format *format) +{ + return format->major_type != WG_MAJOR_TYPE_UNKNOWN + && !wg_format_is_uncompressed(format) + && !(format->major_type == WG_MAJOR_TYPE_AUDIO && format->u.audio.format == WG_AUDIO_FORMAT_UNKNOWN) + && !(format->major_type == WG_MAJOR_TYPE_VIDEO && format->u.video.format == WG_VIDEO_FORMAT_UNKNOWN); +} + +bool wg_format_is_wmv(const struct wg_format *format) +{ + return format->major_type == WG_MAJOR_TYPE_VIDEO + && (format->u.video.format == WG_VIDEO_FORMAT_WMV1 + || format->u.video.format == WG_VIDEO_FORMAT_WMV2 + || format->u.video.format == WG_VIDEO_FORMAT_WMV3 + || format->u.video.format == WG_VIDEO_FORMAT_WMVA + || format->u.video.format == WG_VIDEO_FORMAT_WVC1); }
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index e6d9fb9fd2c..68098213ffc 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -559,24 +559,22 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) { switch (format->major_type) { - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - FIXME("Format %u not implemented!\n", format->major_type); - /* fallthrough */ - case WG_MAJOR_TYPE_UNKNOWN: - return NULL; - - case WG_MAJOR_TYPE_AUDIO: + case WG_MAJOR_TYPE_UNKNOWN: + return NULL; + + case WG_MAJOR_TYPE_AUDIO: + if (!wg_format_is_compressed(format)) return mf_media_type_from_wg_format_audio(format);
- case WG_MAJOR_TYPE_VIDEO: + FIXME("Audio format %u not implemented!\n", format->u.audio.format); + return NULL; + + case WG_MAJOR_TYPE_VIDEO: + if (!wg_format_is_compressed(format)) return mf_media_type_from_wg_format_video(format); + + FIXME("Video format %u not implemented!\n", format->u.video.format); + return NULL; }
assert(0); @@ -650,22 +648,23 @@ static void mf_media_type_to_wg_format_audio_mpeg4(IMFMediaType *type, const GUI raw_aac = IsEqualGUID(subtype, &MFAudioFormat_RAW_AAC); if (!raw_aac) codec_data_size -= min(codec_data_size, sizeof(HEAACWAVEINFO) - sizeof(WAVEFORMATEX)); - if (codec_data_size > sizeof(format->u.audio_mpeg4.codec_data)) + if (codec_data_size > sizeof(format->u.audio.codec_data)) { FIXME("Codec data needs %u bytes.\n", codec_data_size); return; } if (raw_aac) - memcpy(format->u.audio_mpeg4.codec_data, (BYTE *)(&wfx->wfInfo.wfx + 1), codec_data_size); + memcpy(format->u.audio.codec_data, (BYTE *)(&wfx->wfInfo.wfx + 1), codec_data_size); else - memcpy(format->u.audio_mpeg4.codec_data, wfx->pbAudioSpecificConfig, codec_data_size); + memcpy(format->u.audio.codec_data, wfx->pbAudioSpecificConfig, codec_data_size);
- format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG4; + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_MPEG4;
- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &format->u.audio_mpeg4.payload_type))) - format->u.audio_mpeg4.payload_type = 0; + if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &format->u.audio.payload_type))) + format->u.audio.payload_type = 0;
- format->u.audio_mpeg4.codec_data_len = codec_data_size; + format->u.audio.codec_data_len = codec_data_size; }
static enum wg_video_format mf_video_format_to_wg(const GUID *subtype) @@ -778,15 +777,16 @@ static void mf_media_type_to_wg_format_audio_wma(IMFMediaType *type, const GUID return; }
- format->major_type = WG_MAJOR_TYPE_AUDIO_WMA; - format->u.audio_wma.version = version; - format->u.audio_wma.bitrate = bytes_per_second * 8; - format->u.audio_wma.rate = rate; - format->u.audio_wma.depth = depth; - format->u.audio_wma.channels = channels; - format->u.audio_wma.block_align = block_align; - format->u.audio_wma.codec_data_len = codec_data_len; - memcpy(format->u.audio_wma.codec_data, codec_data, codec_data_len); + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_WMA; + format->u.audio.version = version; + format->u.audio.bitrate = bytes_per_second * 8; + format->u.audio.rate = rate; + format->u.audio.depth = depth; + format->u.audio.channels = channels; + format->u.audio.block_align = block_align; + format->u.audio.codec_data_len = codec_data_len; + memcpy(format->u.audio.codec_data, codec_data, codec_data_len); }
static void mf_media_type_to_wg_format_video_h264(IMFMediaType *type, struct wg_format *format) @@ -796,37 +796,38 @@ static void mf_media_type_to_wg_format_video_h264(IMFMediaType *type, struct wg_ BYTE *codec_data;
memset(format, 0, sizeof(*format)); - format->major_type = WG_MAJOR_TYPE_VIDEO_H264; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.format = WG_VIDEO_FORMAT_H264;
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) { - format->u.video_h264.width = frame_size >> 32; - format->u.video_h264.height = (UINT32)frame_size; + format->u.video.width = frame_size >> 32; + format->u.video.height = (UINT32)frame_size; }
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate) { - format->u.video_h264.fps_n = frame_rate >> 32; - format->u.video_h264.fps_d = (UINT32)frame_rate; + format->u.video.fps_n = frame_rate >> 32; + format->u.video.fps_d = (UINT32)frame_rate; } else { - format->u.video_h264.fps_n = 1; - format->u.video_h264.fps_d = 1; + format->u.video.fps_n = 1; + format->u.video.fps_d = 1; }
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile))) - format->u.video_h264.profile = profile; + format->u.video.profile = profile;
if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level))) - format->u.video_h264.level = level; + format->u.video.level = level;
if (SUCCEEDED(IMFMediaType_GetAllocatedBlob(type, &MF_MT_MPEG_SEQUENCE_HEADER, &codec_data, &codec_data_len))) { - if (codec_data_len <= sizeof(format->u.video_h264.codec_data)) + if (codec_data_len <= sizeof(format->u.video.codec_data)) { - format->u.video_h264.codec_data_len = codec_data_len; - memcpy(format->u.video_h264.codec_data, codec_data, codec_data_len); + format->u.video.codec_data_len = codec_data_len; + memcpy(format->u.video.codec_data, codec_data, codec_data_len); } else { @@ -841,26 +842,27 @@ static void mf_media_type_to_wg_format_video_indeo(IMFMediaType *type, uint32_t UINT64 frame_rate, frame_size;
memset(format, 0, sizeof(*format)); - format->major_type = WG_MAJOR_TYPE_VIDEO_INDEO; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.format = WG_VIDEO_FORMAT_INDEO;
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) { - format->u.video_indeo.width = frame_size >> 32; - format->u.video_indeo.height = (UINT32)frame_size; + format->u.video.width = frame_size >> 32; + format->u.video.height = (UINT32)frame_size; }
if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate) { - format->u.video_indeo.fps_n = frame_rate >> 32; - format->u.video_indeo.fps_d = (UINT32)frame_rate; + format->u.video.fps_n = frame_rate >> 32; + format->u.video.fps_d = (UINT32)frame_rate; } else { - format->u.video_indeo.fps_n = 1; - format->u.video_indeo.fps_d = 1; + format->u.video.fps_n = 1; + format->u.video.fps_d = 1; }
- format->u.video_indeo.version = version; + format->u.video.version = version; }
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 6c126fa13e2..f9e5ec47a91 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -119,17 +119,12 @@ static bool wg_audio_format_is_float(enum wg_audio_format format) { switch (format) { - case WG_AUDIO_FORMAT_UNKNOWN: return false; - case WG_AUDIO_FORMAT_U8: return false; - case WG_AUDIO_FORMAT_S16LE: return false; - case WG_AUDIO_FORMAT_S24LE: return false; - case WG_AUDIO_FORMAT_S32LE: return false; - case WG_AUDIO_FORMAT_F32LE: return true; - case WG_AUDIO_FORMAT_F64LE: return true; + case WG_AUDIO_FORMAT_F32LE: + case WG_AUDIO_FORMAT_F64LE: + return true; + default: + return false; } - - assert(0); - return false; }
static WORD wg_audio_format_get_depth(enum wg_audio_format format) @@ -143,6 +138,7 @@ static WORD wg_audio_format_get_depth(enum wg_audio_format format) case WG_AUDIO_FORMAT_S32LE: return 32; case WG_AUDIO_FORMAT_F32LE: return 32; case WG_AUDIO_FORMAT_F64LE: return 64; + default: break; }
assert(0); @@ -154,17 +150,11 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format * mt->majortype = MEDIATYPE_Audio; mt->formattype = FORMAT_WaveFormatEx;
- switch (format->u.audio.format) + if (format->u.audio.format == WG_AUDIO_FORMAT_UNKNOWN) { - case WG_AUDIO_FORMAT_UNKNOWN: return false; - - case WG_AUDIO_FORMAT_U8: - case WG_AUDIO_FORMAT_S16LE: - case WG_AUDIO_FORMAT_S24LE: - case WG_AUDIO_FORMAT_S32LE: - case WG_AUDIO_FORMAT_F32LE: - case WG_AUDIO_FORMAT_F64LE: + } + else if (wg_format_is_uncompressed(format)) { bool is_float = wg_audio_format_is_float(format->u.audio.format); WORD depth = wg_audio_format_get_depth(format->u.audio.format); @@ -216,7 +206,6 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format * } return true; } - }
assert(0); return false; @@ -227,7 +216,7 @@ static bool amt_from_wg_format_audio_mpeg1(AM_MEDIA_TYPE *mt, const struct wg_fo mt->majortype = MEDIATYPE_Audio; mt->formattype = FORMAT_WaveFormatEx;
- switch (format->u.audio_mpeg1.layer) + switch (format->u.audio.layer) { case 1: case 2: @@ -242,10 +231,10 @@ static bool amt_from_wg_format_audio_mpeg1(AM_MEDIA_TYPE *mt, const struct wg_fo mt->cbFormat = sizeof(*wave_format); mt->pbFormat = (BYTE *)wave_format; wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEG; - wave_format->wfx.nChannels = format->u.audio_mpeg1.channels; - wave_format->wfx.nSamplesPerSec = format->u.audio_mpeg1.rate; + wave_format->wfx.nChannels = format->u.audio.channels; + wave_format->wfx.nSamplesPerSec = format->u.audio.rate; wave_format->wfx.cbSize = sizeof(*wave_format) - sizeof(WAVEFORMATEX); - wave_format->fwHeadLayer = format->u.audio_mpeg1.layer; + wave_format->fwHeadLayer = format->u.audio.layer; return true; }
@@ -261,8 +250,8 @@ static bool amt_from_wg_format_audio_mpeg1(AM_MEDIA_TYPE *mt, const struct wg_fo mt->cbFormat = sizeof(*wave_format); mt->pbFormat = (BYTE *)wave_format; wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; - wave_format->wfx.nChannels = format->u.audio_mpeg1.channels; - wave_format->wfx.nSamplesPerSec = format->u.audio_mpeg1.rate; + wave_format->wfx.nChannels = format->u.audio.channels; + wave_format->wfx.nSamplesPerSec = format->u.audio.rate; wave_format->wfx.cbSize = sizeof(*wave_format) - sizeof(WAVEFORMATEX); /* FIXME: We can't get most of the MPEG data from the caps. We may have * to manually parse the header. */ @@ -288,7 +277,7 @@ static bool amt_from_wg_format_audio_wma(AM_MEDIA_TYPE *mt, const struct wg_form mt->majortype = MEDIATYPE_Audio; mt->formattype = FORMAT_WaveFormatEx;
- switch (format->u.audio_wma.version) + switch (format->u.audio.version) { case 1: subtype = &MEDIASUBTYPE_MSAUDIO1; @@ -322,149 +311,155 @@ static bool amt_from_wg_format_audio_wma(AM_MEDIA_TYPE *mt, const struct wg_form
mt->subtype = *subtype; mt->bFixedSizeSamples = TRUE; - mt->lSampleSize = format->u.audio_wma.block_align; + mt->lSampleSize = format->u.audio.block_align; mt->cbFormat = size; mt->pbFormat = (BYTE *)wave_format; wave_format->wFormatTag = fmt_tag; - wave_format->nChannels = format->u.audio_wma.channels; - wave_format->nSamplesPerSec = format->u.audio_wma.rate; - wave_format->nAvgBytesPerSec = format->u.audio_wma.bitrate / 8; - wave_format->nBlockAlign = format->u.audio_wma.block_align; - wave_format->wBitsPerSample = format->u.audio_wma.depth; + wave_format->nChannels = format->u.audio.channels; + wave_format->nSamplesPerSec = format->u.audio.rate; + wave_format->nAvgBytesPerSec = format->u.audio.bitrate / 8; + wave_format->nBlockAlign = format->u.audio.block_align; + wave_format->wBitsPerSample = format->u.audio.depth; wave_format->cbSize = codec_data_len;
- if (format->u.audio_wma.codec_data_len == codec_data_len) - memcpy(wave_format+1, format->u.audio_wma.codec_data, format->u.audio_wma.codec_data_len); + if (format->u.audio.codec_data_len == codec_data_len) + memcpy(wave_format+1, format->u.audio.codec_data, format->u.audio.codec_data_len); else - FIXME("Unexpected codec_data length; got %u, expected %lu\n", format->u.audio_wma.codec_data_len, codec_data_len); + FIXME("Unexpected codec_data length; got %u, expected %lu\n", format->u.audio.codec_data_len, codec_data_len); return true; }
#define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
-static unsigned int wg_format_get_max_size_video_raw(enum wg_video_format format, unsigned int width, unsigned int height) +static unsigned int wg_audio_format_get_max_size(const struct wg_format *format) { - switch (format) + uint32_t rate = format->u.audio.rate, channels = format->u.audio.channels; + + /* Actually we don't know how large of a sample GStreamer will give us. + * Hopefully 1 second is enough... */ + switch (format->u.audio.format) { - case WG_VIDEO_FORMAT_BGRA: - case WG_VIDEO_FORMAT_BGRx: - case WG_VIDEO_FORMAT_AYUV: - return width * height * 4; + case WG_AUDIO_FORMAT_U8: + return rate * channels;
- case WG_VIDEO_FORMAT_BGR: - return ALIGN(width * 3, 4) * height; + case WG_AUDIO_FORMAT_S16LE: + return rate * channels * 2;
- case WG_VIDEO_FORMAT_RGB15: - case WG_VIDEO_FORMAT_RGB16: - case WG_VIDEO_FORMAT_UYVY: - case WG_VIDEO_FORMAT_YUY2: - case WG_VIDEO_FORMAT_YVYU: - return ALIGN(width * 2, 4) * height; + case WG_AUDIO_FORMAT_S24LE: + return rate * channels * 3;
- case WG_VIDEO_FORMAT_I420: - case WG_VIDEO_FORMAT_YV12: - return ALIGN(width, 4) * ALIGN(height, 2) /* Y plane */ - + 2 * ALIGN((width + 1) / 2, 4) * ((height + 1) / 2); /* U and V planes */ + case WG_AUDIO_FORMAT_S32LE: + case WG_AUDIO_FORMAT_F32LE: + return rate * channels * 4;
- case WG_VIDEO_FORMAT_NV12: - return ALIGN(width, 4) * ALIGN(height, 2) /* Y plane */ - + ALIGN(width, 4) * ((height + 1) / 2); /* U/V plane */ + case WG_AUDIO_FORMAT_F64LE: + return rate * channels * 8;
- case WG_VIDEO_FORMAT_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown video format.\n"); + case WG_AUDIO_FORMAT_MPEG1: + switch (format->u.audio.layer) + { + case 1: + return 56000; + case 2: + return 48000; + case 3: + return 40000; + default: + ERR("Unknown layer %u for mpeg1 audio.\n", format->u.audio.layer); return 0; - } + }
- assert(0); - return 0; + case WG_AUDIO_FORMAT_WMA: + /* Estimated max size of a compressed audio frame. + * There's no way to no way to know the real upper bound, + * so let's just use one second of decompressed size and hope it works. */ + return format->u.audio.rate * format->u.audio.channels * format->u.audio.depth / 8; + + case WG_MAJOR_TYPE_UNKNOWN: + FIXME("Cannot guess maximum sample size for unknown audio format.\n"); + return 0; + + default: + FIXME("Audio format %u not implemented!\n", format->u.audio.format); + return 0; + } }
-unsigned int wg_format_get_max_size(const struct wg_format *format) +static unsigned int wg_video_format_get_max_size(const struct wg_format *format) { - switch (format->major_type) + int32_t width = format->u.video.width, height = abs(format->u.video.height); + struct wg_format yv12_format = { - case WG_MAJOR_TYPE_VIDEO: - return wg_format_get_max_size_video_raw(format->u.video.format, - format->u.video.width, abs(format->u.video.height)); - - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - /* Both ffmpeg's encoder and a Cinepak file seen in the wild report - * 24 bpp. ffmpeg sets biSizeImage as below; others may be smaller, - * but as long as every sample fits into our allocator, we're fine. */ - return format->u.video_cinepak.width * format->u.video_cinepak.height * 3; - - case WG_MAJOR_TYPE_VIDEO_MPEG1: - /* Estimated max size of a compressed video frame. - * There's no way to no way to know the real upper bound, - * so let's just use the decompressed size and hope it works. */ - return wg_format_get_max_size_video_raw(WG_VIDEO_FORMAT_YV12, - format->u.video_mpeg1.width, format->u.video_mpeg1.height); - - case WG_MAJOR_TYPE_VIDEO_WMV: - return wg_format_get_max_size_video_raw(WG_VIDEO_FORMAT_YV12, - format->u.video_wmv.width, format->u.video_wmv.height); - - case WG_MAJOR_TYPE_AUDIO: - { - unsigned int rate = format->u.audio.rate, channels = format->u.audio.channels; - - /* Actually we don't know how large of a sample GStreamer will give - * us. Hopefully 1 second is enough... */ - - switch (format->u.audio.format) - { - case WG_AUDIO_FORMAT_U8: - return rate * channels; - - case WG_AUDIO_FORMAT_S16LE: - return rate * channels * 2; - - case WG_AUDIO_FORMAT_S24LE: - return rate * channels * 3; - - case WG_AUDIO_FORMAT_S32LE: - case WG_AUDIO_FORMAT_F32LE: - return rate * channels * 4; - - case WG_AUDIO_FORMAT_F64LE: - return rate * channels * 8; - - case WG_AUDIO_FORMAT_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown audio format.\n"); - return 0; - } - break; - } - - case WG_MAJOR_TYPE_AUDIO_MPEG1: - switch (format->u.audio_mpeg1.layer) - { - case 1: - return 56000; + .major_type = WG_MAJOR_TYPE_VIDEO, + .u.video.format = WG_VIDEO_FORMAT_YV12, + .u.video.width = width, + .u.video.height = height, + };
- case 2: - return 48000; + if (wg_format_is_wmv(format)) + return wg_video_format_get_max_size(&yv12_format); + + switch (format->u.video.format) + { + case WG_VIDEO_FORMAT_BGRA: + case WG_VIDEO_FORMAT_BGRx: + case WG_VIDEO_FORMAT_AYUV: + return width * height * 4; + + case WG_VIDEO_FORMAT_BGR: + return ALIGN(width * 3, 4) * height; + + case WG_VIDEO_FORMAT_RGB15: + case WG_VIDEO_FORMAT_RGB16: + case WG_VIDEO_FORMAT_UYVY: + case WG_VIDEO_FORMAT_YUY2: + case WG_VIDEO_FORMAT_YVYU: + return ALIGN(width * 2, 4) * height; + + case WG_VIDEO_FORMAT_I420: + case WG_VIDEO_FORMAT_YV12: + return ALIGN(width, 4) * ALIGN(height, 2) /* Y plane */ + + 2 * ALIGN((width + 1) / 2, 4) * ((height + 1) / 2); /* U and V planes */ + + case WG_VIDEO_FORMAT_NV12: + return ALIGN(width, 4) * ALIGN(height, 2) /* Y plane */ + + ALIGN(width, 4) * ((height + 1) / 2); /* U/V plane */ + + case WG_VIDEO_FORMAT_CINEPAK: + /* Both ffmpeg's encoder and a Cinepak file seen in the wild report + * 24 bpp. ffmpeg sets biSizeImage as below; others may be smaller, + * but as long as every sample fits into our allocator, we're fine. */ + return width * height * 3; + + case WG_VIDEO_FORMAT_MPEG1: + /* Estimated max size of a compressed video frame. + * There's no way to know the real upper bound, + * so let's just use the decompressed size and hope it works. */ + return wg_video_format_get_max_size(&yv12_format); + + case WG_VIDEO_FORMAT_UNKNOWN: + FIXME("Cannot guess maximum sample size for unknown video format.\n"); + return 0;
- case 3: - return 40000; - } - break; + default: + FIXME("Video format %u not implemented!\n", format->u.audio.format); + return 0; + } +}
- case WG_MAJOR_TYPE_AUDIO_WMA: - /* Estimated max size of a compressed audio frame. - * There's no way to no way to know the real upper bound, - * so let's just use one second of decompressed size and hope it works. */ - return format->u.audio_wma.rate * format->u.audio_wma.channels * format->u.audio_wma.depth / 8; +unsigned int wg_format_get_max_size(const struct wg_format *format) +{ + switch (format->major_type) + { + case WG_MAJOR_TYPE_AUDIO: + return wg_audio_format_get_max_size(format);
- case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_INDEO: - FIXME("Format %u not implemented!\n", format->major_type); - return 0; + case WG_MAJOR_TYPE_VIDEO: + return wg_video_format_get_max_size(format);
- case WG_MAJOR_TYPE_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown format.\n"); - return 0; + case WG_MAJOR_TYPE_UNKNOWN: + FIXME("Cannot guess maximum sample size for unknown major type.\n"); + return 0; }
assert(0); @@ -488,6 +483,7 @@ static const GUID *wg_video_format_get_mediasubtype(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return &MEDIASUBTYPE_YUY2; case WG_VIDEO_FORMAT_YV12: return &MEDIASUBTYPE_YV12; case WG_VIDEO_FORMAT_YVYU: return &MEDIASUBTYPE_YVYU; + default: break; }
assert(0); @@ -511,6 +507,7 @@ static DWORD wg_video_format_get_compression(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return mmioFOURCC('Y','U','Y','2'); case WG_VIDEO_FORMAT_YV12: return mmioFOURCC('Y','V','1','2'); case WG_VIDEO_FORMAT_YVYU: return mmioFOURCC('Y','V','Y','U'); + default: break; }
assert(0); @@ -534,6 +531,7 @@ static WORD wg_video_format_get_depth(enum wg_video_format format) case WG_VIDEO_FORMAT_YUY2: return 16; case WG_VIDEO_FORMAT_YV12: return 12; case WG_VIDEO_FORMAT_YVYU: return 16; + default: break; }
assert(0); @@ -609,11 +607,11 @@ static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_ mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); - if ((frame_time = MulDiv(10000000, format->u.video_cinepak.fps_d, format->u.video_cinepak.fps_n)) != -1) + if ((frame_time = MulDiv(10000000, format->u.video.fps_d, format->u.video.fps_n)) != -1) video_format->AvgTimePerFrame = frame_time; video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - video_format->bmiHeader.biWidth = format->u.video_cinepak.width; - video_format->bmiHeader.biHeight = format->u.video_cinepak.height; + video_format->bmiHeader.biWidth = format->u.video.width; + video_format->bmiHeader.biHeight = format->u.video.height; video_format->bmiHeader.biPlanes = 1; video_format->bmiHeader.biBitCount = 24; video_format->bmiHeader.biCompression = mt->subtype.Data1; @@ -628,29 +626,29 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form uint32_t frame_time; const GUID *subtype;
- switch (format->u.video_wmv.format) + switch (format->u.video.format) { - case WG_WMV_VIDEO_FORMAT_WMV1: + case WG_VIDEO_FORMAT_WMV1: subtype = &MEDIASUBTYPE_WMV1; break; - case WG_WMV_VIDEO_FORMAT_WMV2: + case WG_VIDEO_FORMAT_WMV2: subtype = &MEDIASUBTYPE_WMV2; break; - case WG_WMV_VIDEO_FORMAT_WMV3: + case WG_VIDEO_FORMAT_WMV3: subtype = &MEDIASUBTYPE_WMV3; break; - case WG_WMV_VIDEO_FORMAT_WMVA: + case WG_VIDEO_FORMAT_WMVA: subtype = &MEDIASUBTYPE_WMVA; break; - case WG_WMV_VIDEO_FORMAT_WVC1: + case WG_VIDEO_FORMAT_WVC1: subtype = &MEDIASUBTYPE_WVC1; break; default: - WARN("Invalid WMV format %u.\n", format->u.video_wmv.format); + WARN("Invalid WMV format %u.\n", format->u.video.format); return false; }
- if (!(video_format = CoTaskMemAlloc(sizeof(*video_format) + format->u.video_wmv.codec_data_len))) + if (!(video_format = CoTaskMemAlloc(sizeof(*video_format) + format->u.video.codec_data_len))) return false;
mt->majortype = MEDIATYPE_Video; @@ -659,22 +657,22 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form mt->bTemporalCompression = TRUE; mt->lSampleSize = 0; mt->formattype = FORMAT_VideoInfo; - mt->cbFormat = sizeof(*video_format) + format->u.video_wmv.codec_data_len; + mt->cbFormat = sizeof(*video_format) + format->u.video.codec_data_len; mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); - SetRect(&video_format->rcSource, 0, 0, format->u.video_wmv.width, format->u.video_wmv.height); + SetRect(&video_format->rcSource, 0, 0, format->u.video.width, format->u.video.height); video_format->rcTarget = video_format->rcSource; - if ((frame_time = MulDiv(10000000, format->u.video_wmv.fps_d, format->u.video_wmv.fps_n)) != -1) + if ((frame_time = MulDiv(10000000, format->u.video.fps_d, format->u.video.fps_n)) != -1) video_format->AvgTimePerFrame = frame_time; - video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + format->u.video_wmv.codec_data_len; - video_format->bmiHeader.biWidth = format->u.video_wmv.width; - video_format->bmiHeader.biHeight = format->u.video_wmv.height; + video_format->bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + format->u.video.codec_data_len; + video_format->bmiHeader.biWidth = format->u.video.width; + video_format->bmiHeader.biHeight = format->u.video.height; video_format->bmiHeader.biPlanes = 1; video_format->bmiHeader.biCompression = mt->subtype.Data1; video_format->bmiHeader.biBitCount = 24; video_format->dwBitRate = 0; - memcpy(video_format+1, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len); + memcpy(video_format+1, format->u.video.codec_data, format->u.video.codec_data_len);
return true; } @@ -696,11 +694,11 @@ static bool amt_from_wg_format_video_mpeg1(AM_MEDIA_TYPE *mt, const struct wg_fo mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); - if ((frame_time = MulDiv(10000000, format->u.video_mpeg1.fps_d, format->u.video_mpeg1.fps_n)) != -1) + if ((frame_time = MulDiv(10000000, format->u.video.fps_d, format->u.video.fps_n)) != -1) video_format->hdr.AvgTimePerFrame = frame_time; video_format->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - video_format->hdr.bmiHeader.biWidth = format->u.video_mpeg1.width; - video_format->hdr.bmiHeader.biHeight = format->u.video_mpeg1.height; + video_format->hdr.bmiHeader.biWidth = format->u.video.width; + video_format->hdr.bmiHeader.biHeight = format->u.video.height; video_format->hdr.bmiHeader.biPlanes = 1; video_format->hdr.bmiHeader.biBitCount = 12; video_format->hdr.bmiHeader.biCompression = mt->subtype.Data1; @@ -715,34 +713,45 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
switch (format->major_type) { - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_INDEO: - FIXME("Format %u not implemented!\n", format->major_type); - /* fallthrough */ case WG_MAJOR_TYPE_UNKNOWN: return false;
case WG_MAJOR_TYPE_AUDIO: - return amt_from_wg_format_audio(mt, format); + if (wg_format_is_uncompressed(format)) + return amt_from_wg_format_audio(mt, format);
- case WG_MAJOR_TYPE_AUDIO_MPEG1: - return amt_from_wg_format_audio_mpeg1(mt, format); + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_MPEG1: + return amt_from_wg_format_audio_mpeg1(mt, format);
- case WG_MAJOR_TYPE_AUDIO_WMA: - return amt_from_wg_format_audio_wma(mt, format); + case WG_AUDIO_FORMAT_WMA: + return amt_from_wg_format_audio_wma(mt, format); + + default: + FIXME("Audio format %u not implemented.\n", format->u.audio.format); + return false; + }
case WG_MAJOR_TYPE_VIDEO: - return amt_from_wg_format_video(mt, format, wm); + if (wg_format_is_uncompressed(format)) + return amt_from_wg_format_video(mt, format, wm); + + if (wg_format_is_wmv(format)) + return amt_from_wg_format_video_wmv(mt, format);
- case WG_MAJOR_TYPE_VIDEO_CINEPAK: - return amt_from_wg_format_video_cinepak(mt, format); + switch (format->u.video.format) + { + case WG_VIDEO_FORMAT_CINEPAK: + return amt_from_wg_format_video_cinepak(mt, format);
- case WG_MAJOR_TYPE_VIDEO_WMV: - return amt_from_wg_format_video_wmv(mt, format); + case WG_VIDEO_FORMAT_MPEG1: + return amt_from_wg_format_video_mpeg1(mt, format);
- case WG_MAJOR_TYPE_VIDEO_MPEG1: - return amt_from_wg_format_video_mpeg1(mt, format); + default: + FIXME("Video format %u not implemented.\n", format->u.audio.format); + return false; + } }
assert(0); @@ -833,10 +842,11 @@ static bool amt_to_wg_format_audio_mpeg1(const AM_MEDIA_TYPE *mt, struct wg_form return false; }
- format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG1; - format->u.audio_mpeg1.channels = audio_format->wfx.nChannels; - format->u.audio_mpeg1.rate = audio_format->wfx.nSamplesPerSec; - format->u.audio_mpeg1.layer = audio_format->fwHeadLayer; + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1; + format->u.audio.channels = audio_format->wfx.nChannels; + format->u.audio.rate = audio_format->wfx.nSamplesPerSec; + format->u.audio.layer = audio_format->fwHeadLayer; return true; }
@@ -855,10 +865,11 @@ static bool amt_to_wg_format_audio_mpeg1_layer3(const AM_MEDIA_TYPE *mt, struct return false; }
- format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG1; - format->u.audio_mpeg1.channels = audio_format->wfx.nChannels; - format->u.audio_mpeg1.rate = audio_format->wfx.nSamplesPerSec; - format->u.audio_mpeg1.layer = 3; + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1; + format->u.audio.channels = audio_format->wfx.nChannels; + format->u.audio.rate = audio_format->wfx.nSamplesPerSec; + format->u.audio.layer = 3; return true; }
@@ -878,33 +889,34 @@ static bool amt_to_wg_format_audio_wma(const AM_MEDIA_TYPE *mt, struct wg_format }
if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MSAUDIO1)) - format->u.audio_wma.version = 1; + format->u.audio.version = 1; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO2)) - format->u.audio_wma.version = 2; + format->u.audio.version = 2; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO3)) - format->u.audio_wma.version = 3; + format->u.audio.version = 3; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO_LOSSLESS)) - format->u.audio_wma.version = 4; + format->u.audio.version = 4; else assert(false); - format->major_type = WG_MAJOR_TYPE_AUDIO_WMA; - format->u.audio_wma.bitrate = audio_format->nAvgBytesPerSec * 8; - format->u.audio_wma.rate = audio_format->nSamplesPerSec; - format->u.audio_wma.depth = audio_format->wBitsPerSample; - format->u.audio_wma.channels = audio_format->nChannels; - format->u.audio_wma.block_align = audio_format->nBlockAlign; - - format->u.audio_wma.codec_data_len = 0; - if (format->u.audio_wma.version == 1) - format->u.audio_wma.codec_data_len = 4; - if (format->u.audio_wma.version == 2) - format->u.audio_wma.codec_data_len = 10; - if (format->u.audio_wma.version == 3) - format->u.audio_wma.codec_data_len = 18; - if (format->u.audio_wma.version == 4) - format->u.audio_wma.codec_data_len = 18; - if (mt->cbFormat >= sizeof(WAVEFORMATEX) + format->u.audio_wma.codec_data_len) - memcpy(format->u.audio_wma.codec_data, audio_format+1, format->u.audio_wma.codec_data_len); + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_WMA; + format->u.audio.bitrate = audio_format->nAvgBytesPerSec * 8; + format->u.audio.rate = audio_format->nSamplesPerSec; + format->u.audio.depth = audio_format->wBitsPerSample; + format->u.audio.channels = audio_format->nChannels; + format->u.audio.block_align = audio_format->nBlockAlign; + + format->u.audio.codec_data_len = 0; + if (format->u.audio.version == 1) + format->u.audio.codec_data_len = 4; + if (format->u.audio.version == 2) + format->u.audio.codec_data_len = 10; + if (format->u.audio.version == 3) + format->u.audio.codec_data_len = 18; + if (format->u.audio.version == 4) + format->u.audio.codec_data_len = 18; + if (mt->cbFormat >= sizeof(WAVEFORMATEX) + format->u.audio.codec_data_len) + memcpy(format->u.audio.codec_data, audio_format+1, format->u.audio.codec_data_len); else FIXME("Too small format block, can't copy codec data\n");
@@ -984,32 +996,32 @@ static bool amt_to_wg_format_video_wmv(const AM_MEDIA_TYPE *mt, struct wg_format return false; }
- format->major_type = WG_MAJOR_TYPE_VIDEO_WMV; - format->u.video_wmv.width = video_format->bmiHeader.biWidth; - format->u.video_wmv.height = video_format->bmiHeader.biHeight; - format->u.video_wmv.fps_n = 10000000; - format->u.video_wmv.fps_d = video_format->AvgTimePerFrame; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.width = video_format->bmiHeader.biWidth; + format->u.video.height = video_format->bmiHeader.biHeight; + format->u.video.fps_n = 10000000; + format->u.video.fps_d = video_format->AvgTimePerFrame;
if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV1)) - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WMV1; + format->u.video.format = WG_VIDEO_FORMAT_WMV1; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV2)) - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WMV2; + format->u.video.format = WG_VIDEO_FORMAT_WMV2; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMV3)) - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WMV3; + format->u.video.format = WG_VIDEO_FORMAT_WMV3; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMVA)) - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WMVA; + format->u.video.format = WG_VIDEO_FORMAT_WMVA; else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WVC1)) - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WVC1; + format->u.video.format = WG_VIDEO_FORMAT_WVC1; else - format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_UNKNOWN; + format->u.video.format = WG_VIDEO_FORMAT_UNKNOWN;
- format->u.video_wmv.codec_data_len = mt->cbFormat - sizeof(VIDEOINFOHEADER); - if (format->u.video_wmv.codec_data_len > sizeof(format->u.video_wmv.codec_data)) + format->u.video.codec_data_len = mt->cbFormat - sizeof(VIDEOINFOHEADER); + if (format->u.video.codec_data_len > sizeof(format->u.video.codec_data)) { - ERR("Too big codec_data value (%u).\n", format->u.video_wmv.codec_data_len); - format->u.video_wmv.codec_data_len = 0; + ERR("Too big codec_data value (%u).\n", format->u.video.codec_data_len); + format->u.video.codec_data_len = 0; } - memcpy(format->u.video_wmv.codec_data, video_format+1, format->u.video_wmv.codec_data_len); + memcpy(format->u.video.codec_data, video_format+1, format->u.video.codec_data_len); return true; }
@@ -1028,11 +1040,12 @@ static bool amt_to_wg_format_video_mpeg1(const AM_MEDIA_TYPE *mt, struct wg_form return false; }
- format->major_type = WG_MAJOR_TYPE_VIDEO_MPEG1; - format->u.video_mpeg1.width = video_format->hdr.bmiHeader.biWidth; - format->u.video_mpeg1.height = video_format->hdr.bmiHeader.biHeight; - format->u.video_mpeg1.fps_n = 10000000; - format->u.video_mpeg1.fps_d = video_format->hdr.AvgTimePerFrame; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.format = WG_VIDEO_FORMAT_MPEG1; + format->u.video.width = video_format->hdr.bmiHeader.biWidth; + format->u.video.height = video_format->hdr.bmiHeader.biHeight; + format->u.video.fps_n = 10000000; + format->u.video.fps_d = video_format->hdr.AvgTimePerFrame;
return true; } @@ -2375,12 +2388,12 @@ static BOOL mpeg_splitter_filter_init_gst(struct parser *filter) { stream = wg_parser_get_stream(parser, i); wg_parser_stream_get_preferred_format(stream, &fmt); - if (fmt.major_type == WG_MAJOR_TYPE_VIDEO_MPEG1) + if (fmt.major_type == WG_MAJOR_TYPE_VIDEO && fmt.u.video.format == WG_VIDEO_FORMAT_MPEG1) { if (!create_pin(filter, wg_parser_get_stream(parser, i), L"Video")) return FALSE; } - else if (fmt.major_type == WG_MAJOR_TYPE_AUDIO_MPEG1) + else if (fmt.major_type == WG_MAJOR_TYPE_AUDIO && fmt.u.audio.format == WG_AUDIO_FORMAT_MPEG1) { if (!create_pin(filter, wg_parser_get_stream(parser, i), L"Audio")) return FALSE; diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index 5189c0b22d3..f1dbcca00af 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -757,9 +757,10 @@ HRESULT mpeg_audio_codec_create(IUnknown *outer, IUnknown **out) }; static const struct wg_format input_format = { - .major_type = WG_MAJOR_TYPE_AUDIO_MPEG1, - .u.audio_mpeg1 = + .major_type = WG_MAJOR_TYPE_AUDIO, + .u.audio = { + .format = WG_AUDIO_FORMAT_MPEG1, .layer = 2, .channels = 1, .rate = 44100, @@ -906,8 +907,8 @@ HRESULT mpeg_video_codec_create(IUnknown *outer, IUnknown **out) }; static const struct wg_format input_format = { - .major_type = WG_MAJOR_TYPE_VIDEO_MPEG1, - .u.video_mpeg1 = {}, + .major_type = WG_MAJOR_TYPE_VIDEO, + .u.video = {.format = WG_VIDEO_FORMAT_MPEG1}, }; struct wg_transform_attrs attrs = {0}; wg_transform_t transform; @@ -1035,9 +1036,10 @@ HRESULT mpeg_layer3_decoder_create(IUnknown *outer, IUnknown **out) }; static const struct wg_format input_format = { - .major_type = WG_MAJOR_TYPE_AUDIO_MPEG1, - .u.audio_mpeg1 = + .major_type = WG_MAJOR_TYPE_AUDIO, + .u.audio = { + .format = WG_AUDIO_FORMAT_MPEG1, .layer = 3, .channels = 1, .rate = 44100, diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index bb2cb864735..a7c84a4b642 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -48,6 +48,8 @@ extern bool push_event(GstPad *pad, GstEvent *event);
/* wg_format.c */
+extern bool wg_format_is_uncompressed(const struct wg_format *format); +extern bool wg_format_is_compressed(const struct wg_format *format); extern void wg_format_from_caps(struct wg_format *format, const GstCaps *caps); extern bool wg_format_compare(const struct wg_format *a, const struct wg_format *b); extern GstCaps *wg_format_to_caps(const struct wg_format *format); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 5b1b6ffa7ba..aac4dab9eae 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -34,21 +34,13 @@ enum wg_major_type { WG_MAJOR_TYPE_UNKNOWN = 0, WG_MAJOR_TYPE_AUDIO, - WG_MAJOR_TYPE_AUDIO_MPEG1, - WG_MAJOR_TYPE_AUDIO_MPEG4, - WG_MAJOR_TYPE_AUDIO_WMA, WG_MAJOR_TYPE_VIDEO, - WG_MAJOR_TYPE_VIDEO_CINEPAK, - WG_MAJOR_TYPE_VIDEO_H264, - WG_MAJOR_TYPE_VIDEO_WMV, - WG_MAJOR_TYPE_VIDEO_INDEO, - WG_MAJOR_TYPE_VIDEO_MPEG1, };
typedef UINT32 wg_audio_format; enum wg_audio_format { - WG_AUDIO_FORMAT_UNKNOWN, + WG_AUDIO_FORMAT_UNKNOWN = 0,
WG_AUDIO_FORMAT_U8, WG_AUDIO_FORMAT_S16LE, @@ -56,12 +48,16 @@ enum wg_audio_format WG_AUDIO_FORMAT_S32LE, WG_AUDIO_FORMAT_F32LE, WG_AUDIO_FORMAT_F64LE, + + WG_AUDIO_FORMAT_MPEG1, + WG_AUDIO_FORMAT_MPEG4, + WG_AUDIO_FORMAT_WMA, };
typedef UINT32 wg_video_format; enum wg_video_format { - WG_VIDEO_FORMAT_UNKNOWN, + WG_VIDEO_FORMAT_UNKNOWN = 0,
WG_VIDEO_FORMAT_BGRA, WG_VIDEO_FORMAT_BGRx, @@ -76,17 +72,17 @@ enum wg_video_format WG_VIDEO_FORMAT_YUY2, WG_VIDEO_FORMAT_YV12, WG_VIDEO_FORMAT_YVYU, -};
-typedef UINT32 wg_wmv_video_format; -enum wg_wmv_video_format -{ - WG_WMV_VIDEO_FORMAT_UNKNOWN, - WG_WMV_VIDEO_FORMAT_WMV1, - WG_WMV_VIDEO_FORMAT_WMV2, - WG_WMV_VIDEO_FORMAT_WMV3, - WG_WMV_VIDEO_FORMAT_WMVA, - WG_WMV_VIDEO_FORMAT_WVC1, + WG_VIDEO_FORMAT_CINEPAK, + WG_VIDEO_FORMAT_H264, + WG_VIDEO_FORMAT_INDEO, + WG_VIDEO_FORMAT_MPEG1, + + WG_VIDEO_FORMAT_WMV1, + WG_VIDEO_FORMAT_WMV2, + WG_VIDEO_FORMAT_WMV3, + WG_VIDEO_FORMAT_WMVA, + WG_VIDEO_FORMAT_WVC1, };
struct wg_format @@ -95,38 +91,37 @@ struct wg_format
union { + /* Valid members for different audio formats: + * + * Uncompressed(PCM): channels, channel_mask, rate. + * MPEG1: channels, rate, layer. + * MPEG4: payload_type, codec_data_len, codec_data. + * WMA: channels, rate, version, bitrate, depth, block_align, layer, + * payload_type, codec_data_len, codec_data. */ struct { wg_audio_format format; - uint32_t channels; uint32_t channel_mask; /* In WinMM format. */ uint32_t rate; - } audio; - struct - { - uint32_t layer; - uint32_t rate; - uint32_t channels; - } audio_mpeg1; - struct - { - uint32_t payload_type; - uint32_t codec_data_len; - unsigned char codec_data[64]; - } audio_mpeg4; - struct - { uint32_t version; uint32_t bitrate; - uint32_t rate; uint32_t depth; - uint32_t channels; uint32_t block_align; + uint32_t layer; + uint32_t payload_type; uint32_t codec_data_len; unsigned char codec_data[64]; - } audio_wma; + } audio;
+ /* Valid members for different video formats: + * + * Uncompressed(RGB and YUV): width, height, fps_n, fps_d. + * CINEPAK: width, height, fps_n, fps_d. + * H264: width, height, fps_n, fps_d, profile, level, codec_data_len, codec_data. + * INDEO: width, height, fps_n, fps_d, version. + * MPEG1: width, height, fps_n, fps_d. + * WMV: width, height, fps_n, fps_d, version, codec_data_len, codec_data. */ struct { wg_video_format format; @@ -135,42 +130,12 @@ struct wg_format int32_t width, height; uint32_t fps_n, fps_d; RECT padding; - } video; - struct - { - uint32_t width; - uint32_t height; - uint32_t fps_n; - uint32_t fps_d; - } video_cinepak; - struct - { - int32_t width, height; - uint32_t fps_n, fps_d; uint32_t profile; uint32_t level; + uint32_t version; uint32_t codec_data_len; unsigned char codec_data[64]; - } video_h264; - struct - { - wg_wmv_video_format format; - int32_t width, height; - uint32_t fps_n, fps_d; - uint32_t codec_data_len; - unsigned char codec_data[64]; - } video_wmv; - struct - { - int32_t width, height; - uint32_t fps_n, fps_d; - uint32_t version; - } video_indeo; - struct - { - int32_t width, height; - uint32_t fps_n, fps_d; - } video_mpeg1; + } video; } u; };
diff --git a/dlls/winegstreamer/video_decoder.c b/dlls/winegstreamer/video_decoder.c index 0837217e3a6..516aa933bba 100644 --- a/dlls/winegstreamer/video_decoder.c +++ b/dlls/winegstreamer/video_decoder.c @@ -879,7 +879,11 @@ HRESULT h264_decoder_create(REFIID riid, void **out) .height = 1080, }, }; - static const struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_VIDEO_H264}; + static const struct wg_format input_format = + { + .major_type = WG_MAJOR_TYPE_VIDEO, + .u.video.format = WG_VIDEO_FORMAT_H264, + }; struct wg_transform_attrs attrs = {0}; wg_transform_t transform; IMFTransform *iface; diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 6da97685736..a86be2ad149 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -40,6 +40,67 @@
#include "unix_private.h"
+bool wg_format_is_uncompressed(const struct wg_format *format) +{ + switch (format->major_type) + { + case WG_MAJOR_TYPE_AUDIO: + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_U8: + case WG_AUDIO_FORMAT_S16LE: + case WG_AUDIO_FORMAT_S24LE: + case WG_AUDIO_FORMAT_S32LE: + case WG_AUDIO_FORMAT_F32LE: + case WG_AUDIO_FORMAT_F64LE: + return true; + default: + return false; + } + + case WG_MAJOR_TYPE_VIDEO: + switch (format->u.video.format) + { + case WG_VIDEO_FORMAT_BGRA: + case WG_VIDEO_FORMAT_BGRx: + case WG_VIDEO_FORMAT_BGR: + case WG_VIDEO_FORMAT_RGB15: + case WG_VIDEO_FORMAT_RGB16: + case WG_VIDEO_FORMAT_AYUV: + case WG_VIDEO_FORMAT_I420: + case WG_VIDEO_FORMAT_NV12: + case WG_VIDEO_FORMAT_UYVY: + case WG_VIDEO_FORMAT_YUY2: + case WG_VIDEO_FORMAT_YV12: + case WG_VIDEO_FORMAT_YVYU: + return true; + default: + return false; + } + + default: + return false; + } +} + +bool wg_format_is_compressed(const struct wg_format *format) +{ + return format->major_type != WG_MAJOR_TYPE_UNKNOWN + && !wg_format_is_uncompressed(format) + && !(format->major_type == WG_MAJOR_TYPE_AUDIO && format->u.audio.format == WG_AUDIO_FORMAT_UNKNOWN) + && !(format->major_type == WG_MAJOR_TYPE_VIDEO && format->u.video.format == WG_VIDEO_FORMAT_UNKNOWN); +} + +static bool wg_format_is_wmv(const struct wg_format *format) +{ + return format->major_type == WG_MAJOR_TYPE_VIDEO + && (format->u.video.format == WG_VIDEO_FORMAT_WMV1 + || format->u.video.format == WG_VIDEO_FORMAT_WMV2 + || format->u.video.format == WG_VIDEO_FORMAT_WMV3 + || format->u.video.format == WG_VIDEO_FORMAT_WMVA + || format->u.video.format == WG_VIDEO_FORMAT_WVC1); +} + static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format) { switch (format) @@ -195,10 +256,11 @@ static void wg_format_from_caps_audio_mpeg1(struct wg_format *format, const GstC return; }
- format->major_type = WG_MAJOR_TYPE_AUDIO_MPEG1; - format->u.audio_mpeg1.layer = layer; - format->u.audio_mpeg1.channels = channels; - format->u.audio_mpeg1.rate = rate; + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1; + format->u.audio.layer = layer; + format->u.audio.channels = channels; + format->u.audio.rate = rate; }
static void wg_format_from_caps_audio_wma(struct wg_format *format, const GstCaps *caps) @@ -246,19 +308,20 @@ static void wg_format_from_caps_audio_wma(struct wg_format *format, const GstCap return; }
- format->major_type = WG_MAJOR_TYPE_AUDIO_WMA; - format->u.audio_wma.version = version; - format->u.audio_wma.bitrate = bitrate; - format->u.audio_wma.rate = rate; - format->u.audio_wma.depth = depth; - format->u.audio_wma.channels = channels; - format->u.audio_wma.block_align = block_align; + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.format = WG_AUDIO_FORMAT_WMA; + format->u.audio.version = version; + format->u.audio.bitrate = bitrate; + format->u.audio.rate = rate; + format->u.audio.depth = depth; + format->u.audio.channels = channels; + format->u.audio.block_align = block_align;
gst_buffer_map(codec_data, &map, GST_MAP_READ); - if (map.size <= sizeof(format->u.audio_wma.codec_data)) + if (map.size <= sizeof(format->u.audio.codec_data)) { - format->u.audio_wma.codec_data_len = map.size; - memcpy(format->u.audio_wma.codec_data, map.data, map.size); + format->u.audio.codec_data_len = map.size; + memcpy(format->u.audio.codec_data, map.data, map.size); } else GST_WARNING("Too big codec_data value (%u) in %" GST_PTR_FORMAT ".", (UINT)map.size, caps); @@ -286,11 +349,12 @@ static void wg_format_from_caps_video_cinepak(struct wg_format *format, const Gs fps_d = 1; }
- format->major_type = WG_MAJOR_TYPE_VIDEO_CINEPAK; - format->u.video_cinepak.width = width; - format->u.video_cinepak.height = height; - format->u.video_cinepak.fps_n = fps_n; - format->u.video_cinepak.fps_d = fps_d; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.audio.format = WG_VIDEO_FORMAT_CINEPAK; + format->u.video.width = width; + format->u.video.height = height; + format->u.video.fps_n = fps_n; + format->u.video.fps_d = fps_d; }
static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCaps *caps) @@ -298,9 +362,9 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap const GstStructure *structure = gst_caps_get_structure(caps, 0); gint width, height, fps_n, fps_d, wmv_version = 0; gchar format_buffer[5] = {'W','M','V','0',0}; - enum wg_wmv_video_format wmv_format; const gchar *wmv_format_str = NULL; const GValue *codec_data_value; + wg_video_format wmv_format; GstBuffer *codec_data; GstMapInfo map;
@@ -323,17 +387,17 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap wmv_format_str = format_buffer; } if (!strcmp(wmv_format_str, "WMV1")) - wmv_format = WG_WMV_VIDEO_FORMAT_WMV1; + wmv_format = WG_VIDEO_FORMAT_WMV1; else if (!strcmp(wmv_format_str, "WMV2")) - wmv_format = WG_WMV_VIDEO_FORMAT_WMV2; + wmv_format = WG_VIDEO_FORMAT_WMV2; else if (!strcmp(wmv_format_str, "WMV3")) - wmv_format = WG_WMV_VIDEO_FORMAT_WMV3; + wmv_format = WG_VIDEO_FORMAT_WMV3; else if (!strcmp(wmv_format_str, "WMVA")) - wmv_format = WG_WMV_VIDEO_FORMAT_WMVA; + wmv_format = WG_VIDEO_FORMAT_WMVA; else if (!strcmp(wmv_format_str, "WVC1")) - wmv_format = WG_WMV_VIDEO_FORMAT_WVC1; + wmv_format = WG_VIDEO_FORMAT_WVC1; else - wmv_format = WG_WMV_VIDEO_FORMAT_UNKNOWN; + wmv_format = WG_VIDEO_FORMAT_UNKNOWN;
if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d)) { @@ -341,20 +405,21 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap fps_d = 1; }
- format->major_type = WG_MAJOR_TYPE_VIDEO_WMV; - format->u.video_wmv.width = width; - format->u.video_wmv.height = height; - format->u.video_wmv.format = wmv_format; - format->u.video_wmv.fps_n = fps_n; - format->u.video_wmv.fps_d = fps_d; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.format = wmv_format; + format->u.video.width = width; + format->u.video.height = height; + format->u.video.format = wmv_format; + format->u.video.fps_n = fps_n; + format->u.video.fps_d = fps_d;
if ((codec_data_value = gst_structure_get_value(structure, "codec_data")) && (codec_data = gst_value_get_buffer(codec_data_value))) { gst_buffer_map(codec_data, &map, GST_MAP_READ); - if (map.size <= sizeof(format->u.video_wmv.codec_data)) + if (map.size <= sizeof(format->u.video.codec_data)) { - format->u.video_wmv.codec_data_len = map.size; - memcpy(format->u.video_wmv.codec_data, map.data, map.size); + format->u.video.codec_data_len = map.size; + memcpy(format->u.video.codec_data, map.data, map.size); } else GST_WARNING("Too big codec_data value (%u) in %" GST_PTR_FORMAT ".", (UINT)map.size, caps); @@ -383,11 +448,12 @@ static void wg_format_from_caps_video_mpeg1(struct wg_format *format, const GstC fps_d = 1; }
- format->major_type = WG_MAJOR_TYPE_VIDEO_MPEG1; - format->u.video_mpeg1.width = width; - format->u.video_mpeg1.height = height; - format->u.video_mpeg1.fps_n = fps_n; - format->u.video_mpeg1.fps_d = fps_d; + format->major_type = WG_MAJOR_TYPE_VIDEO; + format->u.video.format = WG_VIDEO_FORMAT_MPEG1; + format->u.video.width = width; + format->u.video.height = height; + format->u.video.fps_n = fps_n; + format->u.video.fps_d = fps_d; }
void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) @@ -506,9 +572,9 @@ static GstCaps *wg_format_to_caps_audio_mpeg1(const struct wg_format *format) return NULL;
gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, 1, NULL); - gst_caps_set_simple(caps, "layer", G_TYPE_INT, format->u.audio_mpeg1.layer, NULL); - gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio_mpeg1.rate, NULL); - gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio_mpeg1.channels, NULL); + gst_caps_set_simple(caps, "layer", G_TYPE_INT, format->u.audio.layer, NULL); + gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio.rate, NULL); + gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio.channels, NULL); gst_caps_set_simple(caps, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
return caps; @@ -524,7 +590,7 @@ static GstCaps *wg_format_to_caps_audio_mpeg4(const struct wg_format *format)
gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, 4, NULL);
- switch (format->u.audio_mpeg4.payload_type) + switch (format->u.audio.payload_type) { case 0: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "raw", NULL); break; case 1: gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "adts", NULL); break; @@ -534,10 +600,10 @@ static GstCaps *wg_format_to_caps_audio_mpeg4(const struct wg_format *format)
/* FIXME: Use gst_codec_utils_aac_caps_set_level_and_profile from GStreamer pbutils library */
- if (format->u.audio_mpeg4.codec_data_len) + if (format->u.audio.codec_data_len) { - buffer = gst_buffer_new_and_alloc(format->u.audio_mpeg4.codec_data_len); - gst_buffer_fill(buffer, 0, format->u.audio_mpeg4.codec_data, format->u.audio_mpeg4.codec_data_len); + buffer = gst_buffer_new_and_alloc(format->u.audio.codec_data_len); + gst_buffer_fill(buffer, 0, format->u.audio.codec_data, format->u.audio.codec_data_len); gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); gst_buffer_unref(buffer); } @@ -579,6 +645,16 @@ static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format) } }
+static void wg_format_to_caps_width_height_framerate(const struct wg_format *format, GstCaps *caps) +{ + if (format->u.video.width) + gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video.width, NULL); + if (format->u.video.height) + gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video.height, NULL); + if (format->u.video.fps_d || format->u.video.fps_n) + gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video.fps_n, format->u.video.fps_d, NULL); +} + static GstCaps *wg_format_to_caps_video(const struct wg_format *format) { GstVideoFormat video_format; @@ -621,13 +697,7 @@ static GstCaps *wg_format_to_caps_video_cinepak(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("video/x-cinepak"))) return NULL; - - if (format->u.video_cinepak.width) - gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_cinepak.width, NULL); - if (format->u.video_cinepak.height) - gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_cinepak.height, NULL); - if (format->u.video_cinepak.fps_d || format->u.video_cinepak.fps_n) - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_cinepak.fps_n, format->u.video_cinepak.fps_d, NULL); + wg_format_to_caps_width_height_framerate(format, caps);
return caps; } @@ -639,29 +709,29 @@ static GstCaps *wg_format_to_caps_audio_wma(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("audio/x-wma"))) return NULL; - if (format->u.audio_wma.version) - gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.audio_wma.version, NULL); - - if (format->u.audio_wma.bitrate) - gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.audio_wma.bitrate, NULL); - if (format->u.audio_wma.rate) - gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio_wma.rate, NULL); - if (format->u.audio_wma.depth) - gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.audio_wma.depth, NULL); - if (format->u.audio_wma.channels) - gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio_wma.channels, NULL); - if (format->u.audio_wma.block_align) - gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.audio_wma.block_align, NULL); - - if (format->u.audio_wma.codec_data_len) - { - if (!(buffer = gst_buffer_new_and_alloc(format->u.audio_wma.codec_data_len))) + if (format->u.audio.version) + gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.audio.version, NULL); + + if (format->u.audio.bitrate) + gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.audio.bitrate, NULL); + if (format->u.audio.rate) + gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.audio.rate, NULL); + if (format->u.audio.depth) + gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.audio.depth, NULL); + if (format->u.audio.channels) + gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.audio.channels, NULL); + if (format->u.audio.block_align) + gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.audio.block_align, NULL); + + if (format->u.audio.codec_data_len) + { + if (!(buffer = gst_buffer_new_and_alloc(format->u.audio.codec_data_len))) { gst_caps_unref(caps); return NULL; }
- gst_buffer_fill(buffer, 0, format->u.audio_wma.codec_data, format->u.audio_wma.codec_data_len); + gst_buffer_fill(buffer, 0, format->u.audio.codec_data, format->u.audio.codec_data_len); gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); gst_buffer_unref(buffer); } @@ -677,23 +747,17 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("video/x-h264"))) return NULL; + wg_format_to_caps_width_height_framerate(format, caps); gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL);
- if (format->u.video_h264.width) - gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_h264.width, NULL); - if (format->u.video_h264.height) - gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_h264.height, NULL); - if (format->u.video_h264.fps_n || format->u.video_h264.fps_d) - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_h264.fps_n, format->u.video_h264.fps_d, NULL); - - switch (format->u.video_h264.profile) + switch (format->u.video.profile) { case eAVEncH264VProfile_Main: profile = "main"; break; case eAVEncH264VProfile_High: profile = "high"; break; case eAVEncH264VProfile_444: profile = "high-4:4:4"; break; default: - GST_FIXME("H264 profile attribute %u not implemented.", format->u.video_h264.profile); + GST_FIXME("H264 profile attribute %u not implemented.", format->u.video.profile); /* fallthrough */ case eAVEncH264VProfile_unknown: profile = "baseline"; @@ -701,7 +765,7 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format) } gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL);
- switch (format->u.video_h264.level) + switch (format->u.video.level) { case eAVEncH264VLevel1: level = "1"; break; case eAVEncH264VLevel1_1: level = "1.1"; break; @@ -720,7 +784,7 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format) case eAVEncH264VLevel5_1: level = "5.1"; break; case eAVEncH264VLevel5_2: level = "5.2"; break; default: - GST_FIXME("H264 level attribute %u not implemented.", format->u.video_h264.level); + GST_FIXME("H264 level attribute %u not implemented.", format->u.video.level); /* fallthrough */ case 0: level = NULL; @@ -729,9 +793,9 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format) if (level) gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL);
- if (format->u.video_h264.codec_data_len) + if (format->u.video.codec_data_len) { - if (!(buffer = gst_buffer_new_and_alloc(format->u.video_h264.codec_data_len))) + if (!(buffer = gst_buffer_new_and_alloc(format->u.video.codec_data_len))) { gst_caps_unref(caps); return NULL; @@ -739,7 +803,7 @@ static GstCaps *wg_format_to_caps_video_h264(const struct wg_format *format)
GST_BUFFER_PTS(buffer) = 0; GST_BUFFER_DTS(buffer) = 0; - gst_buffer_fill(buffer, 0, format->u.video_h264.codec_data, format->u.video_h264.codec_data_len); + gst_buffer_fill(buffer, 0, format->u.video.codec_data, format->u.video.codec_data_len); gst_caps_set_simple(caps, "streamheader", GST_TYPE_BUFFER, buffer, NULL); gst_buffer_unref(buffer); } @@ -756,33 +820,34 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("video/x-wmv"))) return NULL; + wg_format_to_caps_width_height_framerate(format, caps);
- switch (format->u.video_wmv.format) + switch (format->u.video.format) { - case WG_WMV_VIDEO_FORMAT_WMV1: + case WG_VIDEO_FORMAT_WMV1: wmv_format = "WMV1"; wmv_version = 1; break; - case WG_WMV_VIDEO_FORMAT_WMV2: + case WG_VIDEO_FORMAT_WMV2: wmv_format = "WMV2"; wmv_version = 2; break; - case WG_WMV_VIDEO_FORMAT_WMV3: + case WG_VIDEO_FORMAT_WMV3: wmv_format = "WMV3"; wmv_version = 3; break; - case WG_WMV_VIDEO_FORMAT_WMVA: + case WG_VIDEO_FORMAT_WMVA: wmv_format = "WMVA"; wmv_version = 3; break; - case WG_WMV_VIDEO_FORMAT_WVC1: + case WG_VIDEO_FORMAT_WVC1: wmv_format = "WVC1"; wmv_version = 3; break; default: - GST_WARNING("Unknown WMV format %u.", format->u.video_wmv.format); + GST_WARNING("Unknown WMV format %u.", format->u.video.format); /* fallthrough */ - case WG_WMV_VIDEO_FORMAT_UNKNOWN: + case WG_VIDEO_FORMAT_UNKNOWN: wmv_format = NULL; wmv_version = 0; break; @@ -792,22 +857,16 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) gst_caps_set_simple(caps, "format", G_TYPE_STRING, wmv_format, NULL); if (wmv_version) gst_caps_set_simple(caps, "wmvversion", G_TYPE_INT, wmv_version, NULL); - if (format->u.video_wmv.width) - gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_wmv.width, NULL); - if (format->u.video_wmv.height) - gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_wmv.height, NULL); - if (format->u.video_wmv.fps_d || format->u.video_wmv.fps_n) - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_wmv.fps_n, format->u.video_wmv.fps_d, NULL);
- if (format->u.video_wmv.codec_data_len) + if (format->u.video.codec_data_len) { - if (!(buffer = gst_buffer_new_and_alloc(format->u.video_wmv.codec_data_len))) + if (!(buffer = gst_buffer_new_and_alloc(format->u.video.codec_data_len))) { gst_caps_unref(caps); return NULL; }
- gst_buffer_fill(buffer, 0, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len); + gst_buffer_fill(buffer, 0, format->u.video.codec_data, format->u.video.codec_data_len); gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); gst_buffer_unref(buffer); } @@ -821,15 +880,10 @@ static GstCaps *wg_format_to_caps_video_indeo(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("video/x-indeo"))) return NULL; + wg_format_to_caps_width_height_framerate(format, caps);
- if (format->u.video_indeo.width) - gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_indeo.width, NULL); - if (format->u.video_indeo.height) - gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_indeo.height, NULL); - if (format->u.video_indeo.fps_d || format->u.video_indeo.fps_n) - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_indeo.fps_n, format->u.video_indeo.fps_d, NULL); - if (format->u.video_indeo.version) - gst_caps_set_simple(caps, "indeoversion", G_TYPE_INT, format->u.video_indeo.version, NULL); + if (format->u.video.version) + gst_caps_set_simple(caps, "indeoversion", G_TYPE_INT, format->u.video.version, NULL);
return caps; } @@ -840,16 +894,11 @@ static GstCaps *wg_format_to_caps_video_mpeg1(const struct wg_format *format)
if (!(caps = gst_caps_new_empty_simple("video/mpeg"))) return NULL; + wg_format_to_caps_width_height_framerate(format, caps);
gst_caps_set_simple(caps, "mpegversion", G_TYPE_INT, 1, NULL); gst_caps_set_simple(caps, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); gst_caps_set_simple(caps, "parsed", G_TYPE_BOOLEAN, TRUE, NULL); - if (format->u.video_mpeg1.width) - gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video_mpeg1.width, NULL); - if (format->u.video_mpeg1.height) - gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video_mpeg1.height, NULL); - if (format->u.video_mpeg1.fps_d || format->u.video_cinepak.fps_n) - gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_mpeg1.fps_n, format->u.video_mpeg1.fps_d, NULL); return caps; }
@@ -857,29 +906,56 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) { switch (format->major_type) { - case WG_MAJOR_TYPE_UNKNOWN: - return gst_caps_new_any(); - case WG_MAJOR_TYPE_AUDIO: + case WG_MAJOR_TYPE_UNKNOWN: + return gst_caps_new_any(); + + case WG_MAJOR_TYPE_AUDIO: + if (wg_format_is_uncompressed(format) || format->u.audio.format == WG_AUDIO_FORMAT_UNKNOWN) return wg_format_to_caps_audio(format); - case WG_MAJOR_TYPE_AUDIO_MPEG1: + + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_MPEG1: return wg_format_to_caps_audio_mpeg1(format); - case WG_MAJOR_TYPE_AUDIO_MPEG4: + + case WG_AUDIO_FORMAT_MPEG4: return wg_format_to_caps_audio_mpeg4(format); - case WG_MAJOR_TYPE_AUDIO_WMA: + + case WG_AUDIO_FORMAT_WMA: return wg_format_to_caps_audio_wma(format); - case WG_MAJOR_TYPE_VIDEO: + + default: + GST_FIXME("Audio format %u not implemented!", format->major_type); + return NULL; + } + + case WG_MAJOR_TYPE_VIDEO: + if (wg_format_is_uncompressed(format) || format->u.video.format == WG_AUDIO_FORMAT_UNKNOWN) return wg_format_to_caps_video(format); - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - return wg_format_to_caps_video_cinepak(format); - case WG_MAJOR_TYPE_VIDEO_H264: - return wg_format_to_caps_video_h264(format); - case WG_MAJOR_TYPE_VIDEO_WMV: + + if (wg_format_is_wmv(format)) return wg_format_to_caps_video_wmv(format); - case WG_MAJOR_TYPE_VIDEO_INDEO: - return wg_format_to_caps_video_indeo(format); - case WG_MAJOR_TYPE_VIDEO_MPEG1: - return wg_format_to_caps_video_mpeg1(format); + + switch (format->u.audio.format) + { + case WG_VIDEO_FORMAT_CINEPAK: + return wg_format_to_caps_video_cinepak(format); + + case WG_VIDEO_FORMAT_H264: + return wg_format_to_caps_video_h264(format); + + case WG_VIDEO_FORMAT_INDEO: + return wg_format_to_caps_video_indeo(format); + + case WG_VIDEO_FORMAT_MPEG1: + return wg_format_to_caps_video_mpeg1(format); + + default: + GST_FIXME("Video format %u not implemented!", format->major_type); + return NULL; + } } + assert(0); return NULL; } @@ -891,39 +967,39 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
switch (a->major_type) { - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - GST_FIXME("Format %u not implemented!", a->major_type); - /* fallthrough */ - case WG_MAJOR_TYPE_UNKNOWN: - return false; - - case WG_MAJOR_TYPE_AUDIO: + case WG_MAJOR_TYPE_AUDIO: + if (wg_format_is_uncompressed(a)) + { return a->u.audio.format == b->u.audio.format - && a->u.audio.channels == b->u.audio.channels - && a->u.audio.rate == b->u.audio.rate; + && a->u.audio.channels == b->u.audio.channels + && a->u.audio.rate == b->u.audio.rate; + } + + GST_FIXME("Audio format %u not implemented!", a->major_type); + return false;
- case WG_MAJOR_TYPE_VIDEO: + case WG_MAJOR_TYPE_VIDEO: + if (wg_format_is_uncompressed(a)) + { /* Do not compare FPS. */ return a->u.video.format == b->u.video.format && a->u.video.width == b->u.video.width && abs(a->u.video.height) == abs(b->u.video.height) && EqualRect( &a->u.video.padding, &b->u.video.padding ); + }
- case WG_MAJOR_TYPE_VIDEO_CINEPAK: + if (wg_format_is_wmv(a) || a->u.video.format == WG_VIDEO_FORMAT_CINEPAK) + { /* Do not compare FPS. */ - return a->u.video_cinepak.width == b->u.video_cinepak.width - && a->u.video_cinepak.height == b->u.video_cinepak.height; + return a->u.video.width == b->u.video.width + && a->u.video.height == b->u.video.height; + }
- case WG_MAJOR_TYPE_VIDEO_WMV: - /* Do not compare FPS. */ - return a->u.video_wmv.format == b->u.video_wmv.format - && a->u.video_wmv.width == b->u.video_wmv.width - && a->u.video_wmv.height == b->u.video_wmv.height; + GST_FIXME("Video format %u not implemented!", a->major_type); + return false; + + case WG_MAJOR_TYPE_UNKNOWN: + return false; }
assert(0); diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index b0a344d5186..b77d690f99c 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -130,13 +130,6 @@ static struct wg_parser_stream *get_stream(wg_parser_stream_t stream) return (struct wg_parser_stream *)(ULONG_PTR)stream; }
-static bool format_is_compressed(struct wg_format *format) -{ - return format->major_type != WG_MAJOR_TYPE_UNKNOWN - && format->major_type != WG_MAJOR_TYPE_VIDEO - && format->major_type != WG_MAJOR_TYPE_AUDIO; -} - static NTSTATUS wg_parser_get_stream_count(void *args) { struct wg_parser_get_stream_count_params *params = args; @@ -232,7 +225,7 @@ static NTSTATUS wg_parser_stream_get_codec_format(void *args) struct wg_parser_stream_get_codec_format_params *params = args; struct wg_parser_stream *stream = get_stream(params->stream);
- *params->format = format_is_compressed(&stream->codec_format) ? + *params->format = wg_format_is_compressed(&stream->codec_format) ? stream->codec_format : stream->preferred_format; return S_OK; @@ -509,7 +502,7 @@ static gboolean autoplug_continue_cb(GstElement * decodebin, GstPad *pad, GstCap
wg_format_from_caps(&format, caps);
- return !format_is_compressed(&format); + return !wg_format_is_compressed(&format); }
static GstAutoplugSelectResult autoplug_select_cb(GstElement *bin, GstPad *pad, @@ -981,7 +974,7 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user) gst_caps_unref(caps);
/* For compressed stream, create an extra decodebin to decode it. */ - if (!parser->output_compressed && format_is_compressed(&stream->codec_format)) + if (!parser->output_compressed && wg_format_is_compressed(&stream->codec_format)) { if (!stream_decodebin_create(stream)) { diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index aabe618972d..f19a9c75569 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -341,45 +341,44 @@ static GstCaps *transform_get_parsed_caps(struct wg_format *format, const char *
switch (format->major_type) { - case WG_MAJOR_TYPE_AUDIO_MPEG1: + case WG_MAJOR_TYPE_AUDIO: + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_MPEG1: gst_caps_set_simple(parsed_caps, "parsed", G_TYPE_BOOLEAN, true, "mpegversion", G_TYPE_INT, 1, - "layer", G_TYPE_INT, format->u.audio_mpeg1.layer, NULL); + "layer", G_TYPE_INT, format->u.audio.layer, NULL); break; - case WG_MAJOR_TYPE_AUDIO_MPEG4: + case WG_AUDIO_FORMAT_MPEG4: gst_caps_set_simple(parsed_caps, "framed", G_TYPE_BOOLEAN, true, "mpegversion", G_TYPE_INT, 4, NULL); break; - case WG_MAJOR_TYPE_AUDIO_WMA: - gst_caps_set_simple(parsed_caps, "wmaversion", G_TYPE_INT, format->u.audio_wma.version, NULL); + case WG_AUDIO_FORMAT_WMA: + gst_caps_set_simple(parsed_caps, "wmaversion", G_TYPE_INT, format->u.audio.version, NULL); break; - case WG_MAJOR_TYPE_VIDEO_H264: + } + break; + + case WG_MAJOR_TYPE_VIDEO: + switch (format->u.video.format) + { + case WG_VIDEO_FORMAT_H264: gst_caps_set_simple(parsed_caps, "parsed", G_TYPE_BOOLEAN, true, NULL); break; - case WG_MAJOR_TYPE_VIDEO_MPEG1: + case WG_VIDEO_FORMAT_MPEG1: gst_caps_set_simple(parsed_caps, "parsed", G_TYPE_BOOLEAN, true, "mpegversion", G_TYPE_INT, 1, NULL); break; - case WG_MAJOR_TYPE_VIDEO_WMV: - switch (format->u.video_wmv.format) - { - case WG_WMV_VIDEO_FORMAT_WMV1: - gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 1, NULL); - break; - case WG_WMV_VIDEO_FORMAT_WMV2: - gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 2, NULL); - break; - case WG_WMV_VIDEO_FORMAT_WMV3: - case WG_WMV_VIDEO_FORMAT_WMVA: - case WG_WMV_VIDEO_FORMAT_WVC1: - gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 3, NULL); - break; - default: - GST_WARNING("Unknown WMV format %u.", format->u.video_wmv.format); - break; - } + case WG_VIDEO_FORMAT_WMV1: + gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 1, NULL); break; - case WG_MAJOR_TYPE_AUDIO: - case WG_MAJOR_TYPE_VIDEO: - case WG_MAJOR_TYPE_UNKNOWN: + case WG_VIDEO_FORMAT_WMV2: + gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 2, NULL); + break; + case WG_VIDEO_FORMAT_WMV3: + case WG_VIDEO_FORMAT_WMVA: + case WG_VIDEO_FORMAT_WVC1: + gst_caps_set_simple(parsed_caps, "wmvversion", G_TYPE_INT, 3, NULL); break; + } + break; }
return parsed_caps; @@ -455,40 +454,26 @@ NTSTATUS wg_transform_create(void *args) if (!(sink_caps = gst_caps_new_empty_simple(media_type))) goto out;
- switch (input_format.major_type) + if (wg_format_is_compressed(&input_format)) { - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_WMV: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - if ((element = find_element(GST_ELEMENT_FACTORY_TYPE_PARSER, src_caps, parsed_caps)) - && !append_element(transform->container, element, &first, &last)) - goto out; - else if (!element) - { - gst_caps_unref(parsed_caps); - parsed_caps = gst_caps_ref(src_caps); - } - - if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, parsed_caps, sink_caps)) - || !append_element(transform->container, element, &first, &last)) - goto out; - break; + if ((element = find_element(GST_ELEMENT_FACTORY_TYPE_PARSER, src_caps, parsed_caps)) + && !append_element(transform->container, element, &first, &last)) + goto out; + else if (!element) + { + gst_caps_unref(parsed_caps); + parsed_caps = gst_caps_ref(src_caps); + }
- case WG_MAJOR_TYPE_AUDIO: - case WG_MAJOR_TYPE_VIDEO: - break; - case WG_MAJOR_TYPE_UNKNOWN: - GST_FIXME("Format %u not implemented!", input_format.major_type); + if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, parsed_caps, sink_caps)) + || !append_element(transform->container, element, &first, &last)) goto out; }
- switch (output_format.major_type) + if (wg_format_is_uncompressed(&output_format)) { + switch (output_format.major_type) + { case WG_MAJOR_TYPE_AUDIO: /* The MF audio decoder transforms allow decoding to various formats * as well as resampling the audio at the same time, whereas @@ -523,18 +508,7 @@ NTSTATUS wg_transform_create(void *args) /* Let GStreamer choose a default number of threads. */ gst_util_set_object_arg(G_OBJECT(element), "n-threads", "0"); break; - - case WG_MAJOR_TYPE_UNKNOWN: - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_WMV: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - GST_FIXME("Format %u not implemented!", output_format.major_type); - goto out; + } }
if (!link_src_to_element(transform->my_src, first)) diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 18910f87d40..9e42ef530d4 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1635,33 +1635,76 @@ static const enum wg_video_format video_formats[] = WG_VIDEO_FORMAT_RGB15, };
-static const char *get_major_type_string(enum wg_major_type type) +static const char *get_format_string(const struct wg_format *format) { - switch (type) + switch (format->major_type) { - case WG_MAJOR_TYPE_AUDIO: + case WG_MAJOR_TYPE_UNKNOWN: + return "unknown"; + + case WG_MAJOR_TYPE_AUDIO: + switch (format->u.audio.format) + { + case WG_AUDIO_FORMAT_UNKNOWN: return "audio"; - case WG_MAJOR_TYPE_AUDIO_MPEG1: + case WG_AUDIO_FORMAT_U8: + return "pcm_u8"; + case WG_AUDIO_FORMAT_S16LE: + return "pcm_s16le"; + case WG_AUDIO_FORMAT_S24LE: + return "pcm_s24le"; + case WG_AUDIO_FORMAT_S32LE: + return "pcm_s32le"; + case WG_AUDIO_FORMAT_F32LE: + return "pcm_f32le"; + case WG_AUDIO_FORMAT_F64LE: + return "pcm_f64le"; + case WG_AUDIO_FORMAT_MPEG1: return "mpeg1-audio"; - case WG_MAJOR_TYPE_AUDIO_MPEG4: + case WG_AUDIO_FORMAT_MPEG4: return "mpeg4-audio"; - case WG_MAJOR_TYPE_AUDIO_WMA: + case WG_AUDIO_FORMAT_WMA: return "wma"; - case WG_MAJOR_TYPE_VIDEO: + } + + case WG_MAJOR_TYPE_VIDEO: + switch (format->u.video.format) + { + case WG_AUDIO_FORMAT_UNKNOWN: + case WG_VIDEO_FORMAT_BGRA: + case WG_VIDEO_FORMAT_BGRx: + case WG_VIDEO_FORMAT_BGR: + case WG_VIDEO_FORMAT_RGB15: + case WG_VIDEO_FORMAT_RGB16: + case WG_VIDEO_FORMAT_AYUV: + case WG_VIDEO_FORMAT_I420: + case WG_VIDEO_FORMAT_NV12: + case WG_VIDEO_FORMAT_UYVY: + case WG_VIDEO_FORMAT_YUY2: + case WG_VIDEO_FORMAT_YV12: + case WG_VIDEO_FORMAT_YVYU: return "video"; - case WG_MAJOR_TYPE_VIDEO_CINEPAK: + case WG_VIDEO_FORMAT_CINEPAK: return "cinepak"; - case WG_MAJOR_TYPE_VIDEO_H264: + case WG_VIDEO_FORMAT_H264: return "h264"; - case WG_MAJOR_TYPE_VIDEO_WMV: - return "wmv"; - case WG_MAJOR_TYPE_VIDEO_INDEO: + case WG_VIDEO_FORMAT_INDEO: return "indeo"; - case WG_MAJOR_TYPE_VIDEO_MPEG1: + case WG_VIDEO_FORMAT_MPEG1: return "mpeg1-video"; - case WG_MAJOR_TYPE_UNKNOWN: - return "unknown"; + case WG_VIDEO_FORMAT_WMV1: + return "wmv1"; + case WG_VIDEO_FORMAT_WMV2: + return "wmv2"; + case WG_VIDEO_FORMAT_WMV3: + return "wmv3"; + case WG_VIDEO_FORMAT_WMVA: + return "wmva"; + case WG_VIDEO_FORMAT_WVC1: + return "wvc1"; + } } + assert(0); return NULL; } @@ -1701,7 +1744,7 @@ static HRESULT wm_reader_read_stream_sample(struct wm_reader *reader, struct wg_ if (!(stream = wm_reader_get_stream_by_stream_number(reader, buffer->stream + 1))) return E_INVALIDARG;
- TRACE("Got buffer for '%s' stream %p.\n", get_major_type_string(stream->format.major_type), stream); + TRACE("Got buffer for '%s' stream %p.\n", get_format_string(&stream->format), stream);
if (FAILED(hr = wm_stream_allocate_sample(stream, buffer->size, sample))) { @@ -1999,8 +2042,10 @@ static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface,
wg_parser_stream_get_preferred_format(stream->wg_stream, &format);
- switch (format.major_type) + if (wg_format_is_uncompressed(&format)) { + switch (format.major_type) + { case WG_MAJOR_TYPE_VIDEO: if (index >= ARRAY_SIZE(video_formats)) { @@ -2021,19 +2066,11 @@ static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface, } format.u.audio.format = WG_AUDIO_FORMAT_S16LE; break; - - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - FIXME("Format %u not implemented!\n", format.major_type); - break; - case WG_MAJOR_TYPE_UNKNOWN: - break; + } + } + else + { + FIXME("Format %u not implemented!\n", format.major_type); }
LeaveCriticalSection(&reader->cs); @@ -2059,27 +2096,10 @@ static HRESULT WINAPI reader_GetOutputFormatCount(IWMSyncReader2 *iface, DWORD o }
wg_parser_stream_get_preferred_format(stream->wg_stream, &format); - switch (format.major_type) - { - case WG_MAJOR_TYPE_VIDEO: - *count = ARRAY_SIZE(video_formats); - break; - - case WG_MAJOR_TYPE_AUDIO_MPEG1: - case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: - case WG_MAJOR_TYPE_VIDEO_CINEPAK: - case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: - case WG_MAJOR_TYPE_VIDEO_INDEO: - case WG_MAJOR_TYPE_VIDEO_MPEG1: - FIXME("Format %u not implemented!\n", format.major_type); - /* fallthrough */ - case WG_MAJOR_TYPE_AUDIO: - case WG_MAJOR_TYPE_UNKNOWN: - *count = 1; - break; - } + if (format.major_type == WG_MAJOR_TYPE_VIDEO && !wg_format_is_compressed(&format)) + *count = ARRAY_SIZE(video_formats); + else + *count = 1;
LeaveCriticalSection(&reader->cs); return S_OK; diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 62279e4d108..43017ed01b7 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -317,19 +317,19 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR goto done;
if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, - decoder->input_format.u.audio_wma.channels))) + decoder->input_format.u.audio.channels))) goto done;
if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, - decoder->input_format.u.audio_wma.rate))) + decoder->input_format.u.audio.rate))) goto done;
- block_alignment = sample_size * decoder->input_format.u.audio_wma.channels / 8; + block_alignment = sample_size * decoder->input_format.u.audio.channels / 8; if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, block_alignment))) goto done; if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, - decoder->input_format.u.audio_wma.rate * block_alignment))) + decoder->input_format.u.audio.rate * block_alignment))) goto done;
if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1))) @@ -446,7 +446,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK;
- decoder->input_format.u.audio_wma.depth = sample_size; + decoder->input_format.u.audio.depth = sample_size;
mf_media_type_to_wg_format(type, &decoder->output_format); decoder->output_buf_size = 1024 * block_alignment * channel_count; @@ -682,13 +682,13 @@ static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD inde memset(type->pbFormat, 0, type->cbFormat);
wfx = (WAVEFORMATEX *)type->pbFormat; - if (decoder->input_format.u.audio_wma.depth == 32) + if (decoder->input_format.u.audio.depth == 32) wfx->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; else wfx->wFormatTag = WAVE_FORMAT_PCM; - wfx->nChannels = decoder->input_format.u.audio_wma.channels; - wfx->nSamplesPerSec = decoder->input_format.u.audio_wma.rate; - wfx->wBitsPerSample = decoder->input_format.u.audio_wma.depth; + wfx->nChannels = decoder->input_format.u.audio.channels; + wfx->nSamplesPerSec = decoder->input_format.u.audio.rate; + wfx->wBitsPerSample = decoder->input_format.u.audio.depth; wfx->nAvgBytesPerSec = wfx->nChannels * wfx->nSamplesPerSec * wfx->wBitsPerSample / 8; wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8;
@@ -735,7 +735,7 @@ static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index
if (!amt_to_wg_format((const AM_MEDIA_TYPE *)type, &wg_format)) return DMO_E_TYPE_NOT_ACCEPTED; - assert(wg_format.major_type == WG_MAJOR_TYPE_AUDIO_WMA); + assert(wg_format.major_type == WG_MAJOR_TYPE_AUDIO && wg_format.u.audio.format == WG_AUDIO_FORMAT_WMA);
if (flags & DMO_SET_TYPEF_TEST_ONLY) return S_OK; @@ -1037,7 +1037,11 @@ HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out) .rate = 44100, }, }; - static const struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_AUDIO_WMA}; + static const struct wg_format input_format = + { + .major_type = WG_MAJOR_TYPE_AUDIO, + .u.audio.format = WG_AUDIO_FORMAT_WMA, + }; struct wg_transform_attrs attrs = {0}; wg_transform_t transform; struct wma_decoder *decoder; diff --git a/dlls/winegstreamer/wmv_decoder.c b/dlls/winegstreamer/wmv_decoder.c index ee77309aae4..75ba5ac3af1 100644 --- a/dlls/winegstreamer/wmv_decoder.c +++ b/dlls/winegstreamer/wmv_decoder.c @@ -445,8 +445,8 @@ static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD inde if (!wg_format_is_set(&decoder->input_format)) return DMO_E_TYPE_NOT_SET;
- width = decoder->input_format.u.video_wmv.width; - height = abs(decoder->input_format.u.video_wmv.height); + width = decoder->input_format.u.video.width; + height = abs(decoder->input_format.u.video.height); subtype = wmv_decoder_output_types[type_index].subtype; if (FAILED(hr = MFCalculateImageSize(subtype, width, height, &image_size))) { @@ -470,8 +470,8 @@ static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD inde info->rcSource.bottom = height; info->rcTarget.right = width; info->rcTarget.bottom = height; - info->AvgTimePerFrame = MulDiv(10000000, decoder->input_format.u.video_wmv.fps_d, - decoder->input_format.u.video_wmv.fps_n); + info->AvgTimePerFrame = MulDiv(10000000, decoder->input_format.u.video.fps_d, + decoder->input_format.u.video.fps_n); info->bmiHeader.biSize = sizeof(info->bmiHeader); info->bmiHeader.biWidth = width; info->bmiHeader.biHeight = height; @@ -521,7 +521,7 @@ static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index
if (!amt_to_wg_format((const AM_MEDIA_TYPE *)type, &wg_format)) return DMO_E_TYPE_NOT_ACCEPTED; - assert(wg_format.major_type == WG_MAJOR_TYPE_VIDEO_WMV); + assert(wg_format_is_wmv(&wg_format));
if (flags & DMO_SET_TYPEF_TEST_ONLY) return S_OK; @@ -880,8 +880,8 @@ HRESULT wmv_decoder_create(IUnknown *outer, IUnknown **out) { static const struct wg_format input_format = { - .major_type = WG_MAJOR_TYPE_VIDEO_WMV, - .u.video_wmv.format = WG_WMV_VIDEO_FORMAT_WMV3, + .major_type = WG_MAJOR_TYPE_VIDEO, + .u.video.format = WG_VIDEO_FORMAT_WMV3, }; static const struct wg_format output_format = {
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144528
Your paranoid android.
=== debian11b (64 bit WoW report) ===
Report validation errors: mf:transform has no test summary line (early exit of the main process?) mf:transform has unaccounted for todo messages mf:transform has unaccounted for skip messages mf:transform returned a non-zero exit code despite reporting no failures
rebase to resolve merge conflicts
I hate to say it, but I don't think I find this patch particularly convincing. The diffstat isn't favorable, for one, and it's hard to immediately tell why, but I think e.g. wg_format_is_uncompressed() and wg_format_is_wmv() are one reason, and their existence is a little disturbing since it doesn't particularly feel like an improvement over the separate major types.
I also don't like that wg_format_is_uncompressed() exists alongside wg_format_is_compressed() but isn't its inverse [though I can also kind of see why].
I also note that we're not really doing anything to actually factor *out* any logic, which is particularly evident when looking at e.g. amt_to_wg_format_video_*(). Not sure if that was intended to be left to later patches, but well, that was the main point of this series.
What I would recommend doing—and I know this is going to require more work—is to start with the probably more clearly desirable transformation, i.e. merging the structure fields together. That could even be done one patch at a time, i.e. merge u.audio_mpeg1 into u.audio, then u.audio_mpeg4 into u.audio, etc. Then, after that, we can consider turning major types into minor types.
What I would recommend doing—and I know this is going to require more work—is to start with the probably more clearly desirable transformation, i.e. merging the structure fields together. That could even be done one patch at a time, i.e. merge u.audio_mpeg1 into u.audio, then u.audio_mpeg4 into u.audio, etc. Then, after that, we can consider turning major types into minor types.
I'm agree with that, it's a good suggestion. I'm also struggled by splitting this patch.
I'll open a new MR which merge audio_mpeg1 into u.audio to see if that's acceptable.
This merge request was closed by Ziqing Hui.