On 20.12.2011 12:43, Maarten Lankhorst wrote:
And add more sanity checks to stream. This shouldn't break things beyond those 
that aren't broken already.

Signed-off-by: Maarten Lankhorst<m.b.lankho...@gmail.com>

---
And yes Andy, I mean that I haven't found a good video yet to fix the playback 
parts that are still broken..
Why do you want to change that anyway?

The search for start codes was especially split out of the VLC stuff, because start codes start are byte aligned anyway and it doesn't make much sense to search for them using the slower peekbits & fillbits functions.

Se below for some further comments.
  src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c |   56 +++++++++++-------------
  src/gallium/auxiliary/vl/vl_vlc.h              |   33 +++++++++-----
  2 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c 
b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
index 936cf2c..62d08d7 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
@@ -787,7 +787,7 @@ entry:
  }

  static INLINE bool
-decode_slice(struct vl_mpg12_bs *bs)
+decode_slice(struct vl_mpg12_bs *bs, unsigned code)
  {
     struct pipe_mpeg12_macroblock mb;
     short dct_blocks[64*6];
@@ -796,24 +796,29 @@ decode_slice(struct vl_mpg12_bs *bs)

     memset(&mb, 0, sizeof(mb));
     mb.base.codec = PIPE_VIDEO_CODEC_MPEG12;
-   mb.y = vl_vlc_get_uimsbf(&bs->vlc, 8) - 1;
+   mb.y = code - 1;
     mb.blocks = dct_blocks;

     reset_predictor(bs);
+   vl_vlc_fillbits(&bs->vlc);
     dct_scale = quant_scale[bs->desc.q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 
5)];

-   if (vl_vlc_get_uimsbf(&bs->vlc, 1))
+   if (vl_vlc_get_uimsbf(&bs->vlc, 1)) {
+      vl_vlc_fillbits(&bs->vlc);
        while (vl_vlc_get_uimsbf(&bs->vlc, 9)&  1)
           vl_vlc_fillbits(&bs->vlc);
+   }

     vl_vlc_fillbits(&bs->vlc);
+   assert(vl_vlc_bits_left(&bs->vlc)>  23&&  vl_vlc_peekbits(&bs->vlc, 23));
     do {
        int inc = 0;

-      while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
-         vl_vlc_eatbits(&bs->vlc, 11);
-         vl_vlc_fillbits(&bs->vlc);
-      }
+      if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1)
+         while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
+            vl_vlc_eatbits(&bs->vlc, 11);
+            vl_vlc_fillbits(&bs->vlc);
+         }

        while (vl_vlc_peekbits(&bs->vlc, 11) == 8) {
           vl_vlc_eatbits(&bs->vlc, 11);
@@ -959,32 +964,23 @@ void
  vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t 
*buffer)
  {
     assert(bs);
-   assert(buffer&&  num_bytes);
-
-   while(num_bytes>  2) {
-      if (buffer[0] == 0x00&&  buffer[1] == 0x00&&  buffer[2] == 0x01&&
-       buffer[3]>= 0x01&&  buffer[3]<  0xAF) {
-         unsigned consumed;

-         buffer += 3;
-         num_bytes -= 3;
+   vl_vlc_init(&bs->vlc, 1, num_bytes, (void const * const 
*)&buffer,&num_bytes);

-         vl_vlc_init(&bs->vlc, buffer, num_bytes);
-
-         if (!decode_slice(bs))
+   while (vl_vlc_bits_left(&bs->vlc)>= 32) {
+      vl_vlc_fillbits(&bs->vlc);
+      if (vl_vlc_peekbits(&bs->vlc, 24) == 0x000001) {
+         unsigned code;
+         vl_vlc_eatbits(&bs->vlc, 24);
+         code = vl_vlc_get_uimsbf(&bs->vlc, 8);
+         if (!code || code>  0xaf)
+            continue;
+         if (!decode_slice(bs, code))
              return;
-
-         consumed = num_bytes - vl_vlc_bits_left(&bs->vlc) / 8;
-
-         /* crap, this is a bug we have consumed more bytes than left in the 
buffer */
-         assert(consumed<= num_bytes);
-
-         num_bytes -= consumed;
-         buffer += consumed;
-
+         vl_vlc_bitalign(&bs->vlc);
        } else {
-         ++buffer;
-         --num_bytes;
+         vl_vlc_eatbits(&bs->vlc, 8);
+         continue;
        }
     }
  }
diff --git a/src/gallium/auxiliary/vl/vl_vlc.h 
b/src/gallium/auxiliary/vl/vl_vlc.h
index dc4faed..a4ded70 100644
--- a/src/gallium/auxiliary/vl/vl_vlc.h
+++ b/src/gallium/auxiliary/vl/vl_vlc.h
@@ -38,7 +38,7 @@
  struct vl_vlc
  {
     uint64_t buffer;
-   unsigned valid_bits;
+   uint32_t valid_bits;
     uint32_t *data;
     uint32_t *end;
  };
@@ -74,11 +74,9 @@ vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned 
dst_size, const struct vl_v
  static INLINE void
  vl_vlc_fillbits(struct vl_vlc *vlc)
  {
-   if (vlc->valid_bits<  32) {
+   if (vlc->valid_bits<  32&&  vlc->data<  vlc->end) {
        uint32_t value = *vlc->data;
The correct sollution would be to let fillbits return a boolean signaling that the buffer(s) are depleted.


-      //assert(vlc->data<= vlc->end);
-
  #ifndef PIPE_ARCH_BIG_ENDIAN
        value = util_bswap32(value);
  #endif
@@ -90,10 +88,14 @@ vl_vlc_fillbits(struct vl_vlc *vlc)
  }

  static INLINE void
-vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len)
+vl_vlc_init(struct vl_vlc *vlc,
+            const unsigned array_size, unsigned total_len,
+            const const void *const *datas, const unsigned *lens)
  {
+   const uint8_t *data = datas[0];
     assert(vlc);
-   assert(data&&  len);
+   assert(array_size == 1); // TODO
+   assert(datas[0]&&  lens[0]);
Adding an interface definition without an implementation usually only makes sense when we could have more than one different implementation.


     vlc->buffer = 0;
     vlc->valid_bits = 0;
@@ -102,11 +104,11 @@ vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, 
unsigned len)
     while (pointer_to_uintptr(data)&  3) {
        vlc->buffer |= (uint64_t)*data<<  (56 - vlc->valid_bits);
        ++data;
-      --len;
+      --total_len;
        vlc->valid_bits += 8;
     }
     vlc->data = (uint32_t*)data;
-   vlc->end = (uint32_t*)(data + len);
+   vlc->end = (uint32_t*)(data + total_len);

     vl_vlc_fillbits(vlc);
     vl_vlc_fillbits(vlc);
@@ -122,7 +124,7 @@ vl_vlc_bits_left(struct vl_vlc *vlc)
  static INLINE unsigned
  struct vl_vlc *vlc, unsigned num_bits)
  {
-   //assert(vlc->valid_bits>= num_bits);
+   assert(vlc->valid_bits>= num_bits || vl_vlc_bits_left(vlc)<  num_bits);
Hui? bits_left is calculation the total number of bits left in the buffer, while valid_bits is the number of currently loaded bits, so that check is erroneous.


     return vlc->buffer>>  (64 - num_bits);
  }
@@ -130,7 +132,7 @@ vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
  static INLINE void
  vl_vlc_eatbits(struct vl_vlc *vlc, unsigned num_bits)
  {
-   //assert(vlc->valid_bits>  num_bits);
+   assert(vlc->valid_bits>= num_bits);
Just commenting in all checks isn't such a good idea, since that affect performance very badly, a define which enables all assertions at once at the beginning of the file seems the better idea.


     vlc->buffer<<= num_bits;
     vlc->valid_bits -= num_bits;
@@ -141,7 +143,7 @@ vl_vlc_get_uimsbf(struct vl_vlc *vlc, unsigned num_bits)
  {
     unsigned value;

-   //assert(vlc->valid_bits>= num_bits);
+   assert(vlc->valid_bits>= num_bits);

     value = vlc->buffer>>  (64 - num_bits);
     vl_vlc_eatbits(vlc, num_bits);
@@ -154,7 +156,7 @@ vl_vlc_get_simsbf(struct vl_vlc *vlc, unsigned num_bits)
  {
     signed value;

-   //assert(vlc->valid_bits>= num_bits);
+   assert(vlc->valid_bits>= num_bits);

     value = ((int64_t)vlc->buffer)>>  (64 - num_bits);
     vl_vlc_eatbits(vlc, num_bits);
@@ -167,7 +169,14 @@ vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct 
vl_vlc_entry *tbl, unsigned n
  {
     tbl += vl_vlc_peekbits(vlc, num_bits);
     vl_vlc_eatbits(vlc, tbl->length);
+   assert(tbl->length);
     return tbl->value;
  }

+static INLINE void
+vl_vlc_bitalign(struct vl_vlc *vlc)
+{
+   vl_vlc_eatbits(vlc, vlc->valid_bits&  7);
+}
+
  #endif /* vl_vlc_h */


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Christian.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to