From: Rémi Bernon rbernon@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 f2d6e273df2..581e09bbfa0 100644 --- a/dlls/winegstreamer/wg_media_type.c +++ b/dlls/winegstreamer/wg_media_type.c @@ -288,13 +288,33 @@ 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); + 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,