aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly/0002-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch
blob: 2c81e1bdd21361609ed431c87e969f182d2f3944 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
From 389480c0a11c134b963fe4d249d49549db519dec Mon Sep 17 00:00:00 2001
From: Kazunori Kobayashi <kkobayas@igel.co.jp>
Date: Tue, 18 Jun 2013 12:28:32 +0900
Subject: [PATCH 2/2] asfdemux/asfpacket: set frame start code to VC-1 advanced
 profile stream

VC-1 advanced profile constrains the bitstream format to pair
the frame data with the frame start code.
---
 gst/asfdemux/asfpacket.c | 73 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 67 insertions(+), 6 deletions(-)

diff --git a/gst/asfdemux/asfpacket.c b/gst/asfdemux/asfpacket.c
index 12eede8..7b72aa0 100644
--- a/gst/asfdemux/asfpacket.c
+++ b/gst/asfdemux/asfpacket.c
@@ -72,7 +72,7 @@ asf_packet_read_varlen_int (guint lentype_flags, guint lentype_bit_offset,
 
 static GstBuffer *
 asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
-    guint * p_size, guint payload_len)
+    guint * p_size, guint payload_len, gboolean need_st_code)
 {
   guint off;
 
@@ -84,6 +84,39 @@ asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
   *p_data += payload_len;
   *p_size -= payload_len;
 
+  /* set start code for VC-1 advanced profile */
+  if (need_st_code && off >= 4) {
+    const guint8 *pos;
+
+    pos = packet->bdata + off;
+    /* check if this packet has a start code */
+    if (pos[0] != 0x00 || pos[1] != 0x00 || pos[2] != 0x01 || pos[3] != 0x0d) {
+      GstBuffer *subbuf;
+      GstMapInfo map;
+
+      subbuf = gst_buffer_copy_region (packet->buf, GST_BUFFER_COPY_ALL,
+          off - 4, payload_len + 4);
+      if (subbuf == NULL) {
+        GST_ERROR ("Failed to create a sub-buffer");
+        return NULL;
+      }
+
+      if (!gst_buffer_map (subbuf, &map, GST_MAP_WRITE)) {
+        GST_ERROR ("Failed to create a gstbuffer mapping");
+        return NULL;
+      }
+
+      map.data[0] = 0x00;
+      map.data[1] = 0x00;
+      map.data[2] = 0x01;
+      map.data[3] = 0x0d;
+
+      gst_buffer_unmap (subbuf, &map);
+
+      return subbuf;
+    }
+  }
+
   return gst_buffer_copy_region (packet->buf, GST_BUFFER_COPY_ALL, off,
       payload_len);
 }
@@ -284,6 +317,9 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
   gboolean is_compressed;
   guint payload_len;
   guint stream_num;
+  GstStructure *structure;
+  const gchar *fourcc;
+  gboolean need_st_code = FALSE;
 
   if (G_UNLIKELY (*p_size < 1)) {
     GST_WARNING_OBJECT (demux, "Short packet!");
@@ -363,6 +399,18 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
     return TRUE;
   }
 
+  structure = gst_caps_get_structure (stream->caps, 0);
+  fourcc = gst_structure_get_string (structure, "format");
+  if (fourcc) {
+    /*
+     * set start code for VC-1 advanced profile if fourcc is 'WVC1' and this
+     * packet is at the head of a payload.
+     */
+    if (strncmp (fourcc, "WVC1", strlen ("WVC1")) == 0
+        && payload.mo_offset == 0)
+      need_st_code = TRUE;
+  }
+
   if (G_UNLIKELY (!is_compressed)) {
     GST_LOG_OBJECT (demux, "replicated data length: %u", payload.rep_data_len);
 
@@ -397,7 +445,7 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
       /* if the media object is not fragmented, just create a sub-buffer */
       GST_LOG_OBJECT (demux, "unfragmented media object size %u", payload_len);
       payload.buf = asf_packet_create_payload_buffer (packet, p_data, p_size,
-          payload_len);
+          payload_len, need_st_code);
       payload.buf_filled = payload_len;
       gst_asf_payload_queue_for_stream (demux, &payload, stream);
     } else {
@@ -437,11 +485,24 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
               "any previous fragment, ignoring payload");
         }
       } else {
+        const guint8 st_code[] = { 0x00, 0x00, 0x01, 0x0d };
+
         GST_LOG_OBJECT (demux, "allocating buffer of size %u for fragmented "
             "media object", payload.mo_size);
-        payload.buf = gst_buffer_new_allocate (NULL, payload.mo_size, NULL);
-        gst_buffer_fill (payload.buf, 0, payload_data, payload_len);
-        payload.buf_filled = payload_len;
+        if ((payload_data[0] != 0x00 || payload_data[1] != 0x00 ||
+                payload_data[2] != 0x01 || payload_data[3] != 0x0d) &&
+            need_st_code) {
+          /* set start code for VC-1 advanced profile */
+          payload.buf =
+              gst_buffer_new_allocate (NULL, payload.mo_size + 4, NULL);
+          gst_buffer_fill (payload.buf, 0, st_code, sizeof (st_code));
+          gst_buffer_fill (payload.buf, 4, payload_data, payload_len);
+          payload.buf_filled = payload_len + sizeof (st_code);
+        } else {
+          payload.buf = gst_buffer_new_allocate (NULL, payload.mo_size, NULL);
+          gst_buffer_fill (payload.buf, 0, payload_data, payload_len);
+          payload.buf_filled = payload_len;
+        }
 
         gst_asf_payload_queue_for_stream (demux, &payload, stream);
       }
@@ -483,7 +544,7 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
 
       if (G_LIKELY (sub_payload_len > 0)) {
         payload.buf = asf_packet_create_payload_buffer (packet,
-            &payload_data, &payload_len, sub_payload_len);
+            &payload_data, &payload_len, sub_payload_len, need_st_code);
         payload.buf_filled = sub_payload_len;
 
         payload.ts = ts;
-- 
1.8.1.2