[PATCH v2 0/1] MR6533: Draft: winegstreamer: Tweak h264 caps conversion.
-- v2: winegstreamer: Pass H264 codec data as streamheader if it's not parsed yet. https://gitlab.winehq.org/wine/wine/-/merge_requests/6533
From: Rémi Bernon <rbernon(a)codeweavers.com> And set stream-format to avc if it is, as h264parse doesn't expect a codec_data otherwise. Native demuxers and decoders expect the H264 codec data to be appended SPS/PPS NALs, but Wine sometimes only gets it in parsed format if it's stored like that in an avcC MP4 atom. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57204 --- dlls/winegstreamer/wg_media_type.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/wg_media_type.c b/dlls/winegstreamer/wg_media_type.c index 300dace5c52..5de8386522d 100644 --- a/dlls/winegstreamer/wg_media_type.c +++ b/dlls/winegstreamer/wg_media_type.c @@ -288,14 +288,34 @@ static void init_caps_from_video_cinepak(GstCaps *caps, const MFVIDEOFORMAT *for gst_structure_set_name(gst_caps_get_structure(caps, 0), "video/x-cinepak"); } +static int is_h264_start_code(UINT32 value) +{ + return value == 0x10000000 || (value << 8) == 0x10000000; +} + static void init_caps_from_video_h264(GstCaps *caps, const MFVIDEOFORMAT *format, UINT format_size) { - init_caps_codec_data(caps, format + 1, format_size - sizeof(*format)); + GstBuffer *buffer; gst_structure_remove_field(gst_caps_get_structure(caps, 0), "format"); gst_structure_set_name(gst_caps_get_structure(caps, 0), "video/x-h264"); - 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_size <= sizeof(*format) || !(buffer = gst_buffer_new_and_alloc(format_size - sizeof(*format)))) + gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); + else if (format_size - sizeof(*format) >= 4 && is_h264_start_code( *(UINT32 *)(format + 1) )) + { + gst_buffer_fill(buffer, 0, format + 1, format_size - sizeof(*format)); + gst_caps_set_simple(caps, "streamheader", GST_TYPE_BUFFER, buffer, NULL); + gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); + gst_buffer_unref(buffer); + } + else + { + gst_buffer_fill(buffer, 0, format + 1, format_size - sizeof(*format)); + gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); + gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "avc", NULL); + gst_buffer_unref(buffer); + } } static void init_caps_from_video_wmv(GstCaps *caps, const MFVIDEOFORMAT *format, UINT format_size, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6533
v2: Drop the 'au' alignment removal for now as it breaks some tests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6533#note_82734
That doesn't look right. The documentation for both the Media Foundation H.264 decoder and for the MPEG-4 file sink states that the stream must be in Annex B format, which is equivalent to stream-format=byte-stream. Probably what's needed instead is a repeat of !4600. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6533#note_83103
If it really is possible to pass AVC data to these elements, it needs tests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6533#note_83105
participants (2)
-
Elizabeth Figura (@zfigura) -
Rémi Bernon