mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
vc1parser: take care of endianness when parsing sequence-layer
sequence-layer is serialized in little-endian byte order except for STRUCT_C which is serialized in big-endian byte order. But since STRUCT_A and STRUCT_B fields are defined as unsigned int msb first, we have to pass them as big-endian to their parsing function. So we basically use temporary buffers to convert them in big-endian. See SMPTE 421M Annex J and L. https://bugzilla.gnome.org/show_bug.cgi?id=736871
This commit is contained in:
parent
61c40523df
commit
c9a196d54d
1 changed files with 53 additions and 6 deletions
|
@ -35,6 +35,7 @@
|
||||||
#include "gstvc1parser.h"
|
#include "gstvc1parser.h"
|
||||||
#include "parserutils.h"
|
#include "parserutils.h"
|
||||||
#include <gst/base/gstbytereader.h>
|
#include <gst/base/gstbytereader.h>
|
||||||
|
#include <gst/base/gstbytewriter.h>
|
||||||
#include <gst/base/gstbitreader.h>
|
#include <gst/base/gstbitreader.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -1728,32 +1729,78 @@ gst_vc1_parse_sequence_layer (const guint8 * data, gsize size,
|
||||||
GstVC1SeqLayer * seqlayer)
|
GstVC1SeqLayer * seqlayer)
|
||||||
{
|
{
|
||||||
guint32 tmp;
|
guint32 tmp;
|
||||||
GstBitReader br = GST_BIT_READER_INIT (data, size);
|
guint8 tmp8;
|
||||||
|
guint8 structA[8] = { 0, };
|
||||||
|
guint8 structB[12] = { 0, };
|
||||||
|
GstBitReader br;
|
||||||
|
GstByteReader byter = GST_BYTE_READER_INIT (data, size);
|
||||||
|
GstByteWriter bytew;
|
||||||
|
|
||||||
g_return_val_if_fail (seqlayer != NULL, GST_VC1_PARSER_ERROR);
|
g_return_val_if_fail (seqlayer != NULL, GST_VC1_PARSER_ERROR);
|
||||||
|
|
||||||
READ_UINT32 (&br, tmp, 8);
|
/* Thanks to the specification, structA and structB fields are defined
|
||||||
if (tmp != 0xC5)
|
* as unisgned integer msb first.
|
||||||
|
* But in sequence-layer there are serialized in little-endian byte order,
|
||||||
|
* so we must take care of their endianness before using bit reader */
|
||||||
|
|
||||||
|
if (!gst_byte_reader_get_uint24_le (&byter, &seqlayer->numframes))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
READ_UINT32 (&br, seqlayer->numframes, 24);
|
if (!gst_byte_reader_get_uint8 (&byter, &tmp8))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (tmp8 != 0xC5)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* 0x00000004 */
|
||||||
|
if (!gst_byte_reader_get_uint32_le (&byter, &tmp))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
READ_UINT32 (&br, tmp, 32);
|
|
||||||
if (tmp != 0x04)
|
if (tmp != 0x04)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
/* As an exception, structC is serialized in big-endian byte order so
|
||||||
|
* no endianness issue here but we should at least have 4 bytes */
|
||||||
|
if (gst_byte_reader_get_remaining (&byter) < 4)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
gst_bit_reader_init (&br, data + gst_byte_reader_get_pos (&byter), 4);
|
||||||
if (parse_sequence_header_struct_c (&br, &seqlayer->struct_c) ==
|
if (parse_sequence_header_struct_c (&br, &seqlayer->struct_c) ==
|
||||||
GST_VC1_PARSER_ERROR)
|
GST_VC1_PARSER_ERROR)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
gst_byte_reader_skip (&byter, 4);
|
||||||
|
|
||||||
|
/* structA */
|
||||||
|
gst_byte_writer_init_with_data (&bytew, structA, 8, TRUE);
|
||||||
|
gst_byte_reader_get_uint32_le (&byter, &tmp);
|
||||||
|
gst_byte_writer_put_uint32_be (&bytew, tmp);
|
||||||
|
gst_byte_reader_get_uint32_le (&byter, &tmp);
|
||||||
|
gst_byte_writer_put_uint32_be (&bytew, tmp);
|
||||||
|
|
||||||
|
gst_bit_reader_init (&br, structA, 8);
|
||||||
if (parse_sequence_header_struct_a (&br, &seqlayer->struct_a) ==
|
if (parse_sequence_header_struct_a (&br, &seqlayer->struct_a) ==
|
||||||
GST_VC1_PARSER_ERROR)
|
GST_VC1_PARSER_ERROR)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
READ_UINT32 (&br, tmp, 32);
|
/* 0x0000000C */
|
||||||
|
if (!gst_byte_reader_get_uint32_le (&byter, &tmp))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
if (tmp != 0x0C)
|
if (tmp != 0x0C)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
/* structB */
|
||||||
|
gst_byte_writer_reset (&bytew);
|
||||||
|
gst_byte_writer_init_with_data (&bytew, structB, 12, TRUE);
|
||||||
|
gst_byte_reader_get_uint32_le (&byter, &tmp);
|
||||||
|
gst_byte_writer_put_uint32_be (&bytew, tmp);
|
||||||
|
gst_byte_reader_get_uint32_le (&byter, &tmp);
|
||||||
|
gst_byte_writer_put_uint32_be (&bytew, tmp);
|
||||||
|
gst_byte_reader_get_uint32_le (&byter, &tmp);
|
||||||
|
gst_byte_writer_put_uint32_be (&bytew, tmp);
|
||||||
|
|
||||||
|
gst_bit_reader_init (&br, structB, 12);
|
||||||
if (parse_sequence_header_struct_b (&br, &seqlayer->struct_b) ==
|
if (parse_sequence_header_struct_b (&br, &seqlayer->struct_b) ==
|
||||||
GST_VC1_PARSER_ERROR)
|
GST_VC1_PARSER_ERROR)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
Loading…
Reference in a new issue