summaryrefslogtreecommitdiff
path: root/gst/videoparsers/gstvc1parse.c
diff options
context:
space:
mode:
authorAurélien Zanelli <aurelien.zanelli@parrot.com>2014-09-19 11:37:56 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-10-20 13:17:57 +0200
commit4cc6c7fe3b15a14f62cc3fb69f8afdd3fbe625b7 (patch)
tree9546eaad2da81b15a1600bc5a974d600b462e8b0 /gst/videoparsers/gstvc1parse.c
parenteee5110fb4eb39d101c125c39a588754e8acb7ac (diff)
downloadgstreamer-plugins-bad-4cc6c7fe3b15a14f62cc3fb69f8afdd3fbe625b7.tar.gz
vc1parse: introduce a helper to make sequence-layer
It will be useful to implement stream-format conversion. https://bugzilla.gnome.org/show_bug.cgi?id=738526
Diffstat (limited to 'gst/videoparsers/gstvc1parse.c')
-rw-r--r--gst/videoparsers/gstvc1parse.c179
1 files changed, 95 insertions, 84 deletions
diff --git a/gst/videoparsers/gstvc1parse.c b/gst/videoparsers/gstvc1parse.c
index a93e2d611..51b93ebb7 100644
--- a/gst/videoparsers/gstvc1parse.c
+++ b/gst/videoparsers/gstvc1parse.c
@@ -606,6 +606,99 @@ gst_vc1_parse_get_max_framerate (GstVC1Parse * vc1parse)
}
}
+static GstBuffer *
+gst_vc1_parse_make_sequence_layer (GstVC1Parse * vc1parse)
+{
+ GstBuffer *seq_layer_buffer;
+ guint8 *data;
+ guint32 structC = 0;
+ GstMapInfo minfo;
+
+ seq_layer_buffer = gst_buffer_new_and_alloc (36);
+ gst_buffer_map (seq_layer_buffer, &minfo, GST_MAP_WRITE);
+
+ data = minfo.data;
+ /* According to SMPTE 421M Annex L, the sequence layer shall be
+ * represented as a sequence of 32 bit unsigned integers and each
+ * integers should be serialized in little-endian byte-order except for
+ * STRUCT_C which should be serialized in big-endian byte-order. */
+
+ /* Unknown number of frames and start code */
+ data[0] = 0xff;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xc5;
+
+ /* 0x00000004 */
+ GST_WRITE_UINT32_LE (data + 4, 4);
+
+ /* structC */
+ structC |= (vc1parse->profile << 30);
+ if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
+ /* Build simple/main structC from sequence header */
+ structC |= (vc1parse->seq_hdr.struct_c.wmvp << 28);
+ structC |= (vc1parse->seq_hdr.struct_c.frmrtq_postproc << 25);
+ structC |= (vc1parse->seq_hdr.struct_c.bitrtq_postproc << 20);
+ structC |= (vc1parse->seq_hdr.struct_c.loop_filter << 19);
+ /* Reserved3 shall be set to zero */
+ structC |= (vc1parse->seq_hdr.struct_c.multires << 17);
+ /* Reserved4 shall be set to one */
+ structC |= (1 << 16);
+ structC |= (vc1parse->seq_hdr.struct_c.fastuvmc << 15);
+ structC |= (vc1parse->seq_hdr.struct_c.extended_mv << 14);
+ structC |= (vc1parse->seq_hdr.struct_c.dquant << 12);
+ structC |= (vc1parse->seq_hdr.struct_c.vstransform << 11);
+ /* Reserved5 shall be set to zero */
+ structC |= (vc1parse->seq_hdr.struct_c.overlap << 9);
+ structC |= (vc1parse->seq_hdr.struct_c.syncmarker << 8);
+ structC |= (vc1parse->seq_hdr.struct_c.rangered << 7);
+ structC |= (vc1parse->seq_hdr.struct_c.maxbframes << 4);
+ structC |= (vc1parse->seq_hdr.struct_c.quantizer << 2);
+ structC |= (vc1parse->seq_hdr.struct_c.finterpflag << 1);
+ /* Reserved6 shall be set to one */
+ structC |= 1;
+ }
+ GST_WRITE_UINT32_BE (data + 8, structC);
+
+ /* structA */
+ if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
+ GST_WRITE_UINT32_LE (data + 12, vc1parse->height);
+ GST_WRITE_UINT32_LE (data + 16, vc1parse->width);
+ } else {
+ GST_WRITE_UINT32_LE (data + 12, 0);
+ GST_WRITE_UINT32_LE (data + 16, 0);
+ }
+
+ /* 0x0000000c */
+ GST_WRITE_UINT32_LE (data + 20, 0x0000000c);
+
+ /* structB */
+ /* Unknown HRD_BUFFER */
+ GST_WRITE_UINT24_LE (data + 24, 0);
+ if ((gint) vc1parse->level != -1)
+ data[27] = (vc1parse->level << 5);
+ else
+ data[27] = (0x4 << 5); /* Use HIGH level */
+ /* Unknown HRD_RATE */
+ GST_WRITE_UINT32_LE (data + 28, 0);
+ /* Framerate */
+ if (vc1parse->fps_d == 0) {
+ /* If not known, it seems we need to put in the maximum framerate
+ possible for the profile/level used (this is for RTP
+ (https://tools.ietf.org/html/draft-ietf-avt-rtp-vc1-06#section-6.1),
+ so likely elsewhere too */
+ GST_WRITE_UINT32_LE (data + 32, gst_vc1_parse_get_max_framerate (vc1parse));
+ } else {
+ GST_WRITE_UINT32_LE (data + 32,
+ ((guint32) (((gdouble) vc1parse->fps_n) /
+ ((gdouble) vc1parse->fps_d) + 0.5)));
+ }
+
+ gst_buffer_unmap (seq_layer_buffer, &minfo);
+
+ return seq_layer_buffer;
+}
+
static gboolean
gst_vc1_parse_update_caps (GstVC1Parse * vc1parse)
{
@@ -795,91 +888,9 @@ gst_vc1_parse_update_caps (GstVC1Parse * vc1parse)
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
vc1parse->seq_layer_buffer, NULL);
} else {
- GstBuffer *codec_data = gst_buffer_new_and_alloc (36);
- guint8 *data;
- guint32 structC = 0;
- GstMapInfo minfo;
-
- gst_buffer_map (codec_data, &minfo, GST_MAP_WRITE);
-
- data = minfo.data;
- /* According to SMPTE 421M Annex L, the sequence layer shall be
- * represented as a sequence of 32 bit unsigned integers and each
- * integers should be serialized in little-endian byte-order except for
- * STRUCT_C which should be serialized in big-endian byte-order. */
-
- /* Unknown number of frames and start code */
- data[0] = 0xff;
- data[1] = 0xff;
- data[2] = 0xff;
- data[3] = 0xc5;
-
- /* 0x00000004 */
- GST_WRITE_UINT32_LE (data + 4, 4);
-
- /* structC */
- structC |= (vc1parse->profile << 30);
- if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
- /* Build simple/main structC from sequence header */
- structC |= (vc1parse->seq_hdr.struct_c.wmvp << 28);
- structC |= (vc1parse->seq_hdr.struct_c.frmrtq_postproc << 25);
- structC |= (vc1parse->seq_hdr.struct_c.bitrtq_postproc << 20);
- structC |= (vc1parse->seq_hdr.struct_c.loop_filter << 19);
- /* Reserved3 shall be set to zero */
- structC |= (vc1parse->seq_hdr.struct_c.multires << 17);
- /* Reserved4 shall be set to one */
- structC |= (1 << 16);
- structC |= (vc1parse->seq_hdr.struct_c.fastuvmc << 15);
- structC |= (vc1parse->seq_hdr.struct_c.extended_mv << 14);
- structC |= (vc1parse->seq_hdr.struct_c.dquant << 12);
- structC |= (vc1parse->seq_hdr.struct_c.vstransform << 11);
- /* Reserved5 shall be set to zero */
- structC |= (vc1parse->seq_hdr.struct_c.overlap << 9);
- structC |= (vc1parse->seq_hdr.struct_c.syncmarker << 8);
- structC |= (vc1parse->seq_hdr.struct_c.rangered << 7);
- structC |= (vc1parse->seq_hdr.struct_c.maxbframes << 4);
- structC |= (vc1parse->seq_hdr.struct_c.quantizer << 2);
- structC |= (vc1parse->seq_hdr.struct_c.finterpflag << 1);
- /* Reserved6 shall be set to one */
- structC |= 1;
- }
- GST_WRITE_UINT32_BE (data + 8, structC);
-
- /* structA */
- if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
- GST_WRITE_UINT32_LE (data + 12, vc1parse->height);
- GST_WRITE_UINT32_LE (data + 16, vc1parse->width);
- } else {
- GST_WRITE_UINT32_LE (data + 12, 0);
- GST_WRITE_UINT32_LE (data + 16, 0);
- }
-
- /* 0x0000000c */
- GST_WRITE_UINT32_LE (data + 20, 0x0000000c);
+ GstBuffer *codec_data;
- /* structB */
- /* Unknown HRD_BUFFER */
- GST_WRITE_UINT24_LE (data + 24, 0);
- if ((gint) vc1parse->level != -1)
- data[27] = (vc1parse->level << 5);
- else
- data[27] = (0x4 << 5); /* Use HIGH level */
- /* Unknown HRD_RATE */
- GST_WRITE_UINT32_LE (data + 28, 0);
- /* Framerate */
- if (vc1parse->fps_d == 0) {
- /* If not known, it seems we need to put in the maximum framerate
- possible for the profile/level used (this is for RTP
- (https://tools.ietf.org/html/draft-ietf-avt-rtp-vc1-06#section-6.1),
- so likely elsewhere too */
- GST_WRITE_UINT32_LE (data + 32,
- gst_vc1_parse_get_max_framerate (vc1parse));
- } else {
- GST_WRITE_UINT32_LE (data + 32,
- ((guint32) (((gdouble) vc1parse->fps_n) /
- ((gdouble) vc1parse->fps_d) + 0.5)));
- }
- gst_buffer_unmap (codec_data, &minfo);
+ codec_data = gst_vc1_parse_make_sequence_layer (vc1parse);
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data,
NULL);