<br><div class="gmail_quote">2012/3/15 Christian König <span dir="ltr">&lt;<a href="mailto:deathsimple@vodafone.de">deathsimple@vodafone.de</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Signed-off-by: Christian König &lt;<a href="mailto:deathsimple@vodafone.de">deathsimple@vodafone.de</a>&gt;<br>
---<br>
 src/gallium/state_trackers/vdpau/decode.c |   48 ++++++++++++++++++++++++----<br>
 1 files changed, 41 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c<br>
index 56a171f..154ebd0 100644<br>
--- a/src/gallium/state_trackers/vdpau/decode.c<br>
+++ b/src/gallium/state_trackers/vdpau/decode.c<br>
@@ -30,6 +30,8 @@<br>
 #include &quot;util/u_debug.h&quot;<br>
 #include &quot;util/u_video.h&quot;<br>
<br>
+#include &quot;vl/vl_vlc.h&quot;<br>
+<br>
 #include &quot;vdpau_private.h&quot;<br>
<br>
 /**<br>
@@ -378,6 +380,36 @@ vlVdpDecoderRenderH264(struct pipe_h264_picture_desc *picture,<br>
    return VDP_STATUS_OK;<br>
 }<br>
<br>
+static void<br>
+vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])<br>
+{<br>
+   static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };<br>
+   struct vl_vlc vlc;<br>
+   unsigned i;<br>
+<br>
+   /* search the first 64 bytes for a startcode */<br>
+   vl_vlc_init(&amp;vlc, *num_buffers, buffers, sizes);<br>
+   for (i = 0; i &lt; 64 &amp;&amp; vl_vlc_bits_left(&amp;vlc) &gt;= 32; ++i) {<br>
+      uint32_t value = vl_vlc_peekbits(&amp;vlc, 32);<br>
+      if (value == 0x0000010D ||<br>
+          value == 0x0000010C ||<br>
+          value == 0x0000010B)<br>
+         return;<br>
+      vl_vlc_eatbits(&amp;vlc, 8);<br>
+      vl_vlc_fillbits(&amp;vlc);<br>
+   }<br>
+<br>
+   /* none found, ok add one manually */<br>
+   VDPAU_MSG(VDPAU_TRACE, &quot;[VDPAU] Manually adding VC-1 startcode\n&quot;);<br>
+   for (i = *num_buffers; i &gt; 0; --i) {<br>
+      buffers[i] = buffers[i - 1];<br>
+      sizes[i] = sizes[i - 1];<br>
+   }<br>
+   ++(*num_buffers);<br>
+   buffers[0] = vc1_startcode;<br>
+   sizes[0] = 4;<br>
+}<br>
+<br>
 /**<br>
  * Decode a compressed field/frame and render the result into a VdpVideoSurface.<br>
  */<br>
@@ -388,8 +420,8 @@ vlVdpDecoderRender(VdpDecoder decoder,<br>
                    uint32_t bitstream_buffer_count,<br>
                    VdpBitstreamBuffer const *bitstream_buffers)<br>
 {<br>
-   const void * buffers[bitstream_buffer_count];<br>
-   unsigned sizes[bitstream_buffer_count];<br>
+   const void * buffers[bitstream_buffer_count + 1];<br>
+   unsigned sizes[bitstream_buffer_count + 1];<br>
    vlVdpDecoder *vldecoder;<br>
    vlVdpSurface *vlsurf;<br>
    VdpStatus ret;<br>
@@ -454,6 +486,11 @@ vlVdpDecoderRender(VdpDecoder decoder,<br>
       }<br>
    }<br>
<br>
+   for (i = 0; i &lt; bitstream_buffer_count; ++i) {<br>
+      buffers[i] = bitstream_buffers[i].bitstream;<br>
+      sizes[i] = bitstream_buffers[i].bitstream_bytes;<br>
+   }<br>
+<br>
    memset(&amp;desc, 0, sizeof(desc));<br>
    desc.base.profile = dec-&gt;profile;<br>
    switch (u_reduce_video_profile(dec-&gt;profile)) {<br>
@@ -464,6 +501,7 @@ vlVdpDecoderRender(VdpDecoder decoder,<br>
       ret = vlVdpDecoderRenderMpeg4(&amp;desc.mpeg4, (VdpPictureInfoMPEG4Part2 *)picture_info);<br>
       break;<br>
    case PIPE_VIDEO_CODEC_VC1:<br>
+      vlVdpDecoderFixVC1Startcode(&amp;bitstream_buffer_count, buffers, sizes);<br>
       ret = vlVdpDecoderRenderVC1(&amp;desc.vc1, (VdpPictureInfoVC1 *)picture_info);<br>
       break;<br>
    case PIPE_VIDEO_CODEC_MPEG4_AVC:<br>
@@ -473,16 +511,12 @@ vlVdpDecoderRender(VdpDecoder decoder,<br>
       pipe_mutex_unlock(vlsurf-&gt;device-&gt;mutex);<br>
       return VDP_STATUS_INVALID_DECODER_PROFILE;<br>
    }<br>
+<br>
    if (ret != VDP_STATUS_OK) {<br>
       pipe_mutex_unlock(vlsurf-&gt;device-&gt;mutex);<br>
       return ret;<br>
    }<br>
<br>
-   for (i = 0; i &lt; bitstream_buffer_count; ++i) {<br>
-      buffers[i] = bitstream_buffers[i].bitstream;<br>
-      sizes[i] = bitstream_buffers[i].bitstream_bytes;<br>
-   }<br>
-<br>
    dec-&gt;begin_frame(dec, vlsurf-&gt;video_buffer, &amp;desc.base);<br>
    dec-&gt;decode_bitstream(dec, vlsurf-&gt;video_buffer, &amp;desc.base, bitstream_buffer_count, buffers, sizes);<br>
    dec-&gt;end_frame(dec, vlsurf-&gt;video_buffer, &amp;desc.base);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.5.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br><div>I actually made some code that does exactly the opposite, for H.264 and VP8, removing the start code from the first buffer containing it (so the first buffer alltoghether or just the 3 first bytes of the first buffer). I think the start codes, at least for H.264 are just here so the decoding application (in this case the state tracker) can make sure the buffers are valid video buffers, and are not used in the decoding process.</div>

<div><br></div><div>In my VP8 implementation I require a 0x9D012A start code, similar to H.264 that requires a 0x000001. I asked on the VDPAU mailing list if it was a good idea, and what was the purpose of these start code in the first place but I did not get an answer.</div>

<div><br></div><div>However I have no idea if a VC1 decoder requires the presence of start codes, and your implementation is fine by me, I can still hook a vlVdpDecoderRemoveVP8Startcode() function similar to vlVdpDecoderFixVC1Startcode().</div>

<div><br></div><div>Emeric</div><div><br></div><div><div>diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c</div><div>index f093194..b8ef5f2 100644</div><div>--- a/src/gallium/state_trackers/vdpau/decode.c</div>

<div>+++ b/src/gallium/state_trackers/vdpau/decode.c</div></div><div><div>@@ -516,9 +516,41 @@ vlVdpDecoderRender(VdpDecoder decoder,</div><div>       return ret;</div><div>    }</div><div> </div><div>-   for (i = 0; i &lt; bitstream_buffer_count; ++i) {</div>

<div>-      buffers[i] = bitstream_buffers[i].bitstream;</div><div>-      sizes[i] = bitstream_buffers[i].bitstream_bytes;</div><div>+   // Cleanup start_code (mandatory for some codec) from bitstream buffers</div><div>+   if (u_reduce_video_profile(dec-&gt;profile) == PIPE_VIDEO_CODEC_MPEG4_AVC ||</div>

<div>+       u_reduce_video_profile(dec-&gt;profile) == PIPE_VIDEO_CODEC_VP8) {</div><div>+      int start_code_found = 0;</div><div>+</div><div>+      for (i = 0, j = 0; i &lt; bitstream_buffer_count; ++i) {</div><div>+         if (!start_code_found) {</div>

<div>+            const uint8_t *datab = (const uint8_t *)bitstream_buffers[i].bitstream;</div><div>+</div><div>+            if ((datab[0] == 0x9D &amp;&amp; datab[1] == 0x01 &amp;&amp; datab[2] == 0x2A) ||</div><div>+                (datab[0] == 0x00 &amp;&amp; datab[1] == 0x00 &amp;&amp; datab[2] == 0x01)) {</div>

<div>+               start_code_found = 1;</div><div>+</div><div>+               if (bitstream_buffers[i].bitstream_bytes != 3) {</div><div>+                  buffers[j] = bitstream_buffers[i].bitstream + 3;</div><div>+                  sizes[j] = bitstream_buffers[i].bitstream_bytes - 3;</div>

<div>+                  j++;</div><div>+               }</div><div>+            } else {</div><div>+               VDPAU_MSG(VDPAU_TRACE, &quot;[VDPAU] Error : the first data buffer does not contain the mandatory start_code [0x9D012A]\n&quot;);</div>

<div>+               return VDP_STATUS_ERROR;</div><div>+            }</div><div>+         } else {</div><div>+            buffers[j] = bitstream_buffers[i].bitstream;</div><div>+            sizes[j] = bitstream_buffers[i].bitstream_bytes;</div>

<div>+            j++;</div><div>+         }</div><div>+      }</div><div>+</div><div>+      bitstream_buffer_count = j;</div><div>+   } else {</div><div>+      for (i = 0; i &lt; bitstream_buffer_count; ++i) {</div><div>

+         buffers[i] = bitstream_buffers[i].bitstream;</div><div>+         sizes[i] = bitstream_buffers[i].bitstream_bytes;</div><div>+      }</div><div>    }</div><div> </div><div>    dec-&gt;begin_frame(dec, vlsurf-&gt;video_buffer, &amp;desc.base);</div>

<div>-- </div></div>