winegstreamer: Convert MPEG-1 audio to a major type.

Signed-off-by: Anton Baskanov <baskanov@gmail.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Anton Baskanov 2022-05-05 17:24:30 -05:00 committed by Alexandre Julliard
parent 915d88e5e6
commit 0d956959fa
6 changed files with 104 additions and 85 deletions

View File

@ -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:

View File

@ -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,20 @@ 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;
}
break;
case WG_MAJOR_TYPE_H264:
case WG_MAJOR_TYPE_WMA:
FIXME("Format %u not implemented!\n", format->major_type);
@ -431,6 +448,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 +546,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 +568,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;
}

View File

@ -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;

View File

@ -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);

View File

@ -236,6 +236,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:
@ -269,6 +270,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:

View File

@ -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: