[PATCH 1/7] winegstreamer: Convert MPEG-1 audio to a major type.

Anton Baskanov baskanov at gmail.com
Tue May 3 13:27:59 CDT 2022


Signed-off-by: Anton Baskanov <baskanov at gmail.com>
---
 dlls/winegstreamer/mfplat.c        |   1 +
 dlls/winegstreamer/quartz_parser.c | 151 ++++++++++++++++-------------
 dlls/winegstreamer/unixlib.h       |  11 ++-
 dlls/winegstreamer/wg_format.c     |  22 ++---
 dlls/winegstreamer/wg_transform.c  |   2 +
 dlls/winegstreamer/wm_reader.c     |   4 +
 6 files changed, 106 insertions(+), 85 deletions(-)

diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 97e27bb7301..4d8476d7b49 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -661,6 +661,7 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
     {
         case WG_MAJOR_TYPE_H264:
         case WG_MAJOR_TYPE_WMA:
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
             FIXME("Format %u not implemented!\n", format->major_type);
             /* fallthrough */
         case WG_MAJOR_TYPE_UNKNOWN:
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 7b82f3efbc9..3e00813ae75 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -111,50 +111,6 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format *
     case WG_AUDIO_FORMAT_UNKNOWN:
         return false;
 
-    case WG_AUDIO_FORMAT_MPEG1_LAYER1:
-    case WG_AUDIO_FORMAT_MPEG1_LAYER2:
-    {
-        MPEG1WAVEFORMAT *wave_format;
-
-        if (!(wave_format = CoTaskMemAlloc(sizeof(*wave_format))))
-            return false;
-        memset(wave_format, 0, sizeof(*wave_format));
-
-        mt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
-        mt->cbFormat = sizeof(*wave_format);
-        mt->pbFormat = (BYTE *)wave_format;
-        wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEG;
-        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.format == WG_AUDIO_FORMAT_MPEG1_LAYER1 ? 1 : 2);
-        return true;
-    }
-
-    case WG_AUDIO_FORMAT_MPEG1_LAYER3:
-    {
-        MPEGLAYER3WAVEFORMAT *wave_format;
-
-        if (!(wave_format = CoTaskMemAlloc(sizeof(*wave_format))))
-            return false;
-        memset(wave_format, 0, sizeof(*wave_format));
-
-        mt->subtype = MEDIASUBTYPE_MP3;
-        mt->cbFormat = sizeof(*wave_format);
-        mt->pbFormat = (BYTE *)wave_format;
-        wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
-        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. */
-        wave_format->wID = MPEGLAYER3_ID_MPEG;
-        wave_format->fdwFlags = MPEGLAYER3_FLAG_PADDING_ON;
-        wave_format->nFramesPerBlock = 1;
-        wave_format->nCodecDelay = 1393;
-        return true;
-    }
-
     case WG_AUDIO_FORMAT_U8:
     case WG_AUDIO_FORMAT_S16LE:
     case WG_AUDIO_FORMAT_S24LE:
@@ -238,6 +194,62 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format *
     return false;
 }
 
+static bool amt_from_wg_format_mpeg1_audio(AM_MEDIA_TYPE *mt, const struct wg_format *format)
+{
+    mt->majortype = MEDIATYPE_Audio;
+    mt->formattype = FORMAT_WaveFormatEx;
+
+    switch (format->u.mpeg1_audio.layer)
+    {
+    case 1:
+    case 2:
+    {
+        MPEG1WAVEFORMAT *wave_format;
+
+        if (!(wave_format = CoTaskMemAlloc(sizeof(*wave_format))))
+            return false;
+        memset(wave_format, 0, sizeof(*wave_format));
+
+        mt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
+        mt->cbFormat = sizeof(*wave_format);
+        mt->pbFormat = (BYTE *)wave_format;
+        wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEG;
+        wave_format->wfx.nChannels = format->u.mpeg1_audio.channels;
+        wave_format->wfx.nSamplesPerSec = format->u.mpeg1_audio.rate;
+        wave_format->wfx.cbSize = sizeof(*wave_format) - sizeof(WAVEFORMATEX);
+        wave_format->fwHeadLayer = format->u.mpeg1_audio.layer;
+        return true;
+    }
+
+    case 3:
+    {
+        MPEGLAYER3WAVEFORMAT *wave_format;
+
+        if (!(wave_format = CoTaskMemAlloc(sizeof(*wave_format))))
+            return false;
+        memset(wave_format, 0, sizeof(*wave_format));
+
+        mt->subtype = MEDIASUBTYPE_MP3;
+        mt->cbFormat = sizeof(*wave_format);
+        mt->pbFormat = (BYTE *)wave_format;
+        wave_format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
+        wave_format->wfx.nChannels = format->u.mpeg1_audio.channels;
+        wave_format->wfx.nSamplesPerSec = format->u.mpeg1_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. */
+        wave_format->wID = MPEGLAYER3_ID_MPEG;
+        wave_format->fdwFlags = MPEGLAYER3_FLAG_PADDING_ON;
+        wave_format->nFramesPerBlock = 1;
+        wave_format->nCodecDelay = 1393;
+        return true;
+    }
+    }
+
+    assert(0);
+    return false;
+}
+
 #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
 
 unsigned int wg_format_get_max_size(const struct wg_format *format)
@@ -312,15 +324,6 @@ unsigned int wg_format_get_max_size(const struct wg_format *format)
                 case WG_AUDIO_FORMAT_F64LE:
                     return rate * channels * 8;
 
-                case WG_AUDIO_FORMAT_MPEG1_LAYER1:
-                    return 56000;
-
-                case WG_AUDIO_FORMAT_MPEG1_LAYER2:
-                    return 48000;
-
-                case WG_AUDIO_FORMAT_MPEG1_LAYER3:
-                    return 40000;
-
                 case WG_AUDIO_FORMAT_UNKNOWN:
                     FIXME("Cannot guess maximum sample size for unknown audio format.\n");
                     return 0;
@@ -328,6 +331,22 @@ unsigned int wg_format_get_max_size(const struct wg_format *format)
             break;
         }
 
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
+            switch (format->u.mpeg1_audio.layer)
+            {
+            case 1:
+                return 56000;
+
+            case 2:
+                return 48000;
+
+            case 3:
+                return 40000;
+            }
+            assert(0);
+            return 0;
+
+
         case WG_MAJOR_TYPE_H264:
         case WG_MAJOR_TYPE_WMA:
             FIXME("Format %u not implemented!\n", format->major_type);
@@ -431,6 +450,9 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
     case WG_MAJOR_TYPE_UNKNOWN:
         return false;
 
+    case WG_MAJOR_TYPE_MPEG1_AUDIO:
+        return amt_from_wg_format_mpeg1_audio(mt, format);
+
     case WG_MAJOR_TYPE_AUDIO:
         return amt_from_wg_format_audio(mt, format);
 
@@ -526,17 +548,10 @@ 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;
-    format->u.audio.channels = audio_format->wfx.nChannels;
-    format->u.audio.rate = audio_format->wfx.nSamplesPerSec;
-    if (audio_format->fwHeadLayer == 1)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1;
-    else if (audio_format->fwHeadLayer == 2)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2;
-    else if (audio_format->fwHeadLayer == 3)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3;
-    else
-        return false;
+    format->major_type = WG_MAJOR_TYPE_MPEG1_AUDIO;
+    format->u.mpeg1_audio.channels = audio_format->wfx.nChannels;
+    format->u.mpeg1_audio.rate = audio_format->wfx.nSamplesPerSec;
+    format->u.mpeg1_audio.layer = audio_format->fwHeadLayer;
     return true;
 }
 
@@ -555,10 +570,10 @@ static bool amt_to_wg_format_audio_mpeg1_layer3(const AM_MEDIA_TYPE *mt, struct
         return false;
     }
 
-    format->major_type = WG_MAJOR_TYPE_AUDIO;
-    format->u.audio.channels = audio_format->wfx.nChannels;
-    format->u.audio.rate = audio_format->wfx.nSamplesPerSec;
-    format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3;
+    format->major_type = WG_MAJOR_TYPE_MPEG1_AUDIO;
+    format->u.mpeg1_audio.channels = audio_format->wfx.nChannels;
+    format->u.mpeg1_audio.rate = audio_format->wfx.nSamplesPerSec;
+    format->u.mpeg1_audio.layer = 3;
     return true;
 }
 
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index f4e2ea4966b..881eb720b6c 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -37,6 +37,7 @@ struct wg_format
         WG_MAJOR_TYPE_UNKNOWN,
         WG_MAJOR_TYPE_VIDEO,
         WG_MAJOR_TYPE_AUDIO,
+        WG_MAJOR_TYPE_MPEG1_AUDIO,
         WG_MAJOR_TYPE_WMA,
         WG_MAJOR_TYPE_H264,
     } major_type;
@@ -80,10 +81,6 @@ struct wg_format
                 WG_AUDIO_FORMAT_S32LE,
                 WG_AUDIO_FORMAT_F32LE,
                 WG_AUDIO_FORMAT_F64LE,
-
-                WG_AUDIO_FORMAT_MPEG1_LAYER1,
-                WG_AUDIO_FORMAT_MPEG1_LAYER2,
-                WG_AUDIO_FORMAT_MPEG1_LAYER3,
             } format;
 
             uint32_t channels;
@@ -91,6 +88,12 @@ struct wg_format
             uint32_t rate;
         } audio;
         struct
+        {
+            uint32_t layer;
+            uint32_t rate;
+            uint32_t channels;
+        } mpeg1_audio;
+        struct
         {
             uint32_t version;
             uint32_t bitrate;
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c
index ff9238a6a69..608070b78e8 100644
--- a/dlls/winegstreamer/wg_format.c
+++ b/dlls/winegstreamer/wg_format.c
@@ -177,7 +177,7 @@ static void wg_format_from_video_info(struct wg_format *format, const GstVideoIn
     format->u.video.fps_d = GST_VIDEO_INFO_FPS_D(info);
 }
 
-static void wg_format_from_caps_audio_mpeg(struct wg_format *format, const GstCaps *caps)
+static void wg_format_from_caps_audio_mpeg1(struct wg_format *format, const GstCaps *caps)
 {
     const GstStructure *structure = gst_caps_get_structure(caps, 0);
     gint layer, channels, rate;
@@ -198,17 +198,10 @@ static void wg_format_from_caps_audio_mpeg(struct wg_format *format, const GstCa
         return;
     }
 
-    format->major_type = WG_MAJOR_TYPE_AUDIO;
-
-    if (layer == 1)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1;
-    else if (layer == 2)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2;
-    else if (layer == 3)
-        format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3;
-
-    format->u.audio.channels = channels;
-    format->u.audio.rate = rate;
+    format->major_type = WG_MAJOR_TYPE_MPEG1_AUDIO;
+    format->u.mpeg1_audio.layer = layer;
+    format->u.mpeg1_audio.channels = channels;
+    format->u.mpeg1_audio.rate = rate;
 }
 
 static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps)
@@ -263,7 +256,7 @@ void wg_format_from_caps(struct wg_format *format, const GstCaps *caps)
     }
     else if (!strcmp(name, "audio/mpeg"))
     {
-        wg_format_from_caps_audio_mpeg(format, caps);
+        wg_format_from_caps_audio_mpeg1(format, caps);
     }
     else if (!strcmp(name, "video/x-cinepak"))
     {
@@ -501,6 +494,8 @@ GstCaps *wg_format_to_caps(const struct wg_format *format)
     {
         case WG_MAJOR_TYPE_UNKNOWN:
             return gst_caps_new_any();
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
+            return NULL;
         case WG_MAJOR_TYPE_WMA:
             return wg_format_to_caps_wma(format);
         case WG_MAJOR_TYPE_H264:
@@ -521,6 +516,7 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
 
     switch (a->major_type)
     {
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
         case WG_MAJOR_TYPE_WMA:
         case WG_MAJOR_TYPE_H264:
             GST_FIXME("Format %u not implemented!", a->major_type);
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 49c7bfaa927..dca85e7366e 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -233,6 +233,7 @@ NTSTATUS wg_transform_create(void *args)
             }
             break;
 
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
         case WG_MAJOR_TYPE_AUDIO:
         case WG_MAJOR_TYPE_VIDEO:
         case WG_MAJOR_TYPE_UNKNOWN:
@@ -266,6 +267,7 @@ NTSTATUS wg_transform_create(void *args)
         case WG_MAJOR_TYPE_VIDEO:
             break;
 
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
         case WG_MAJOR_TYPE_H264:
         case WG_MAJOR_TYPE_WMA:
         case WG_MAJOR_TYPE_UNKNOWN:
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 57ba8633a84..03adea8a318 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1686,6 +1686,7 @@ HRESULT wm_reader_get_output_format_count(struct wm_reader *reader, DWORD output
             *count = ARRAY_SIZE(video_formats);
             break;
 
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
         case WG_MAJOR_TYPE_WMA:
         case WG_MAJOR_TYPE_H264:
             FIXME("Format %u not implemented!\n", format.major_type);
@@ -1736,6 +1737,7 @@ HRESULT wm_reader_get_output_format(struct wm_reader *reader, DWORD output,
             format.u.audio.format = WG_AUDIO_FORMAT_S16LE;
             break;
 
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
         case WG_MAJOR_TYPE_WMA:
         case WG_MAJOR_TYPE_H264:
             FIXME("Format %u not implemented!\n", format.major_type);
@@ -1815,6 +1817,8 @@ static const char *get_major_type_string(enum wg_major_type type)
             return "video";
         case WG_MAJOR_TYPE_UNKNOWN:
             return "unknown";
+        case WG_MAJOR_TYPE_MPEG1_AUDIO:
+            return "mpeg1-audio";
         case WG_MAJOR_TYPE_WMA:
             return "wma";
         case WG_MAJOR_TYPE_H264:
-- 
2.34.1




More information about the wine-devel mailing list