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 | 54 +-- dlls/winegstreamer/wm_reader.c | 122 ++++--- dlls/winegstreamer/wma_decoder.c | 26 +- dlls/winegstreamer/wmv_decoder.c | 14 +- 15 files changed, 755 insertions(+), 640 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 74a6eee5b1d..22b57751d14 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -650,6 +650,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: @@ -657,11 +688,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 4ec9fce515e..fed555f617b 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 71ea8cd263c..3882f64a9d7 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -402,40 +402,27 @@ 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 - { - 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 + { + 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 @@ -470,18 +457,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 = {