Write LEB128 OBU size fields.

Removes padding bytes.

BUG=aomedia:1125

Change-Id: Ib9bce81a86aa218abeeba8e027387634aaa89b92
diff --git a/aom/src/aom_integer.c b/aom/src/aom_integer.c
index 1fd9a84..23a0a8c 100644
--- a/aom/src/aom_integer.c
+++ b/aom/src/aom_integer.c
@@ -28,6 +28,7 @@
     for (size_t i = 0; i < kMaximumLeb128Size && i < available; ++i) {
       const uint8_t decoded_byte = *(buffer + i) & kLeb128ByteMask;
       *value |= decoded_byte << (i * 7);
+      if ((*(buffer + i) >> 7) == 0) break;
     }
   }
 }
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 3304634..10939f9 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -1267,10 +1267,6 @@
   return flags;
 }
 
-#if CONFIG_OBU
-static uint32_t write_temporal_delimiter_obu() { return 0; }
-#endif
-
 static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
                                       const aom_image_t *img,
                                       aom_codec_pts_t pts,
@@ -1436,15 +1432,19 @@
         // move data PRE_OBU_SIZE_BYTES + 1 bytes and insert OBU_TD preceded by
         // optional 4 byte size
         uint32_t obu_size = 1;
+#if CONFIG_OBU_SIZING
+        const size_t length_field_size = aom_uleb_size_in_bytes(obu_size);
+#else
+        const size_t length_field_size = PRE_OBU_SIZE_BYTES;
+#endif
         if (ctx->pending_cx_data) {
-          const size_t index_sz = PRE_OBU_SIZE_BYTES + 1;
-          memmove(ctx->pending_cx_data + index_sz, ctx->pending_cx_data,
+          const size_t obu_header_size = length_field_size + 1;
+          memmove(ctx->pending_cx_data + obu_header_size, ctx->pending_cx_data,
                   ctx->pending_cx_data_sz);
         }
         obu_size = write_obu_header(
             OBU_TEMPORAL_DELIMITER, 0,
-            (uint8_t *)(ctx->pending_cx_data + PRE_OBU_SIZE_BYTES));
-        obu_size += write_temporal_delimiter_obu();
+            (uint8_t *)(ctx->pending_cx_data + length_field_size));
 #if CONFIG_OBU_SIZING
         // OBUs are preceded by an unsigned leb128 coded unsigned integer padded
         // to PRE_OBU_SIZE_BYTES bytes.
@@ -1453,7 +1453,7 @@
 #else
         mem_put_le32(ctx->pending_cx_data, obu_size);
 #endif  // CONFIG_OBU_SIZING
-        pkt.data.frame.sz += (obu_size + PRE_OBU_SIZE_BYTES);
+        pkt.data.frame.sz += obu_size + length_field_size;
       }
 #endif  // CONFIG_OBU
 
diff --git a/av1/common/common.h b/av1/common/common.h
index 286c1f1..b051921 100644
--- a/av1/common/common.h
+++ b/av1/common/common.h
@@ -54,8 +54,13 @@
 
 #define AOM_FRAME_MARKER 0x2
 
-// Size of OBU length field.
+#if CONFIG_OBU_SIZING
+// Variable size LEB128 unsigned integer length field.
+#define PRE_OBU_SIZE_BYTES 0
+#else
+// Fixed size OBU length field.
 #define PRE_OBU_SIZE_BYTES 4
+#endif
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index e1ed8eb..e49faae 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -148,7 +148,6 @@
 
   // TODO(shan):  For now, assume all tile groups received in order
   *is_last_tg = endTile == cm->tile_rows * cm->tile_cols - 1;
-
   return header_size + tg_payload_size;
 }
 
@@ -273,21 +272,29 @@
   while (!frame_decoding_finished && !cm->error.error_code) {
     struct aom_read_bit_buffer rb;
     size_t obu_header_size, obu_payload_size = 0;
-    av1_init_read_bit_buffer(pbi, &rb, data + PRE_OBU_SIZE_BYTES, data_end);
+    const size_t bytes_available = data_end - data;
+
+    if (bytes_available < 1) {
+      cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
+      return;
+    }
 
 #if CONFIG_OBU_SIZING
-    // OBUs are preceded by an unsigned leb128 coded unsigned integer padded to
-    // PRE_OBU_SIZE_BYTES bytes.
+    // OBUs are preceded by an unsigned leb128 coded unsigned integer.
     uint32_t u_obu_size = 0;
-    aom_uleb_decode(data, PRE_OBU_SIZE_BYTES, &u_obu_size);
+    aom_uleb_decode(data, bytes_available, &u_obu_size);
     const size_t obu_size = (size_t)u_obu_size;
+    const size_t length_field_size = aom_uleb_size_in_bytes(u_obu_size);
 #else
     // every obu is preceded by PRE_OBU_SIZE_BYTES-byte size of obu (obu header
     // + payload size)
     // The obu size is only needed for tile group OBUs
     const size_t obu_size = mem_get_le32(data);
+    const size_t length_field_size = PRE_OBU_SIZE_BYTES;
 #endif  // CONFIG_OBU_SIZING
 
+    av1_init_read_bit_buffer(pbi, &rb, data + length_field_size, data_end);
+
 #if !CONFIG_SCALABILITY
     const OBU_TYPE obu_type = read_obu_header(&rb, &obu_header_size, NULL);
 #else
@@ -295,7 +302,7 @@
         read_obu_header(&rb, &obu_header_size, &obu_extension_header);
 #endif
 
-    data += (PRE_OBU_SIZE_BYTES + obu_header_size);
+    data += length_field_size + obu_header_size;
     if (data_end < data) {
       cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
       return;
@@ -339,6 +346,7 @@
         break;
       default: break;
     }
+
     data += obu_payload_size;
     if (data_end < data) {
       cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index e7c6200..9416be5 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -4509,13 +4509,8 @@
 int write_uleb_obu_size(uint32_t obu_size, uint8_t *dest) {
   size_t coded_obu_size = 0;
 
-  // Encode an unsigned leb128 coded unsigned integer padded to
-  // PRE_OBU_SIZE_BYTES bytes.
-  if (aom_uleb_encode_fixed_size(obu_size, PRE_OBU_SIZE_BYTES,
-                                 PRE_OBU_SIZE_BYTES, dest, &coded_obu_size) ||
-      coded_obu_size != PRE_OBU_SIZE_BYTES) {
+  if (aom_uleb_encode(obu_size, sizeof(uint32_t), dest, &coded_obu_size) != 0)
     return AOM_CODEC_ERROR;
-  }
 
   return AOM_CODEC_OK;
 }
@@ -4610,12 +4605,9 @@
 static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst,
                                        unsigned int *max_tile_size,
                                        unsigned int *max_tile_col_size,
-                                       uint8_t *const frame_header_obu_location,
-                                       uint32_t frame_header_obu_size,
 #if CONFIG_EXT_TILE
                                        struct aom_write_bit_buffer *saved_wb,
 #endif
-                                       int insert_frame_header_obu_flag,
                                        uint8_t obu_extension_header) {
   AV1_COMMON *const cm = &cpi->common;
   aom_writer mode_bc;
@@ -4771,14 +4763,6 @@
         int is_last_tile_in_tg = 0;
 
         if (new_tg) {
-          if (insert_frame_header_obu_flag && tile_idx) {
-            // insert a copy of frame header OBU (including
-            // PRE_OBU_SIZE_BYTES-byte size),
-            // except before the first tile group
-            data = dst + total_size;
-            memmove(data, frame_header_obu_location, frame_header_obu_size);
-            total_size += frame_header_obu_size;
-          }
           data = dst + total_size;
           // A new tile group begins at this tile.  Write the obu header and
           // tile group header
@@ -4844,8 +4828,13 @@
         } else {
 // write current tile group size
 #if CONFIG_OBU_SIZING
+          const size_t length_field_size =
+              aom_uleb_size_in_bytes(curr_tg_data_size);
+          memmove(data + length_field_size, data, curr_tg_data_size);
           if (write_uleb_obu_size(curr_tg_data_size, data) != AOM_CODEC_OK)
             assert(0);
+          curr_tg_data_size += length_field_size;
+          total_size += length_field_size;
 #else
         mem_put_le32(data, curr_tg_data_size);
 #endif  // CONFIG_OBU_SIZING
@@ -4870,8 +4859,6 @@
 #if CONFIG_OBU
   AV1_COMMON *const cm = &cpi->common;
   uint32_t obu_size;
-  uint8_t *frame_header_location;
-  uint32_t frame_header_size;
 #if CONFIG_SCALABILITY
   const uint8_t enhancement_layers_cnt = cm->enhancement_layers_cnt;
   const uint8_t obu_extension_header =
@@ -4893,21 +4880,26 @@
     obu_size =
         write_obu_header(OBU_SEQUENCE_HEADER, 0, data + PRE_OBU_SIZE_BYTES);
 
-    obu_size += write_sequence_header_obu(
 #if CONFIG_SCALABILITY
+    obu_size += write_sequence_header_obu(
         cpi, data + PRE_OBU_SIZE_BYTES + obu_size, enhancement_layers_cnt);
 #else
-        cpi, data + PRE_OBU_SIZE_BYTES + obu_size);
+    obu_size +=
+        write_sequence_header_obu(cpi, data + PRE_OBU_SIZE_BYTES + obu_size);
 #endif  // CONFIG_SCALABILITY
 
 #if CONFIG_OBU_SIZING
+    const size_t length_field_size = aom_uleb_size_in_bytes(obu_size);
+    memmove(data + length_field_size, data, obu_size);
+
     if (write_uleb_obu_size(obu_size, data) != AOM_CODEC_OK)
       return AOM_CODEC_ERROR;
 #else
+    const size_t length_field_size = PRE_OBU_SIZE_BYTES;
     mem_put_le32(data, obu_size);
 #endif  // CONFIG_OBU_SIZING
 
-    data += obu_size + PRE_OBU_SIZE_BYTES;
+    data += obu_size + length_field_size;
   }
 
 #if CONFIG_EXT_TILE
@@ -4915,39 +4907,37 @@
 #endif
 
   // write frame header obu, preceded by 4-byte size
-  frame_header_location = data + PRE_OBU_SIZE_BYTES;
   obu_size = write_obu_header(OBU_FRAME_HEADER, obu_extension_header,
-                              frame_header_location);
-  frame_header_size =
-      write_frame_header_obu(cpi,
+                              data + PRE_OBU_SIZE_BYTES);
+  obu_size += write_frame_header_obu(cpi,
 #if CONFIG_EXT_TILE
-                             &saved_wb,
+                                     &saved_wb,
 #endif
-                             data + PRE_OBU_SIZE_BYTES + obu_size);
-  obu_size += frame_header_size;
+                                     data + PRE_OBU_SIZE_BYTES + obu_size);
 
 #if CONFIG_OBU_SIZING
+  const size_t length_field_size = aom_uleb_size_in_bytes(obu_size);
+  memmove(data + length_field_size, data, obu_size);
   if (write_uleb_obu_size(obu_size, data) != AOM_CODEC_OK)
     return AOM_CODEC_ERROR;
 #else
+  const size_t length_field_size = PRE_OBU_SIZE_BYTES;
   mem_put_le32(data, obu_size);
 #endif  // CONFIG_OBU_SIZING
 
-  data += obu_size + PRE_OBU_SIZE_BYTES;
+  data += obu_size + length_field_size;
 
   if (cm->show_existing_frame) {
     data_size = 0;
   } else {
     //  Each tile group obu will be preceded by 4-byte size of the tile group
     //  obu
-    data_size = write_tiles_in_tg_obus(
-        cpi, data, &max_tile_size, &max_tile_col_size,
-        frame_header_location - PRE_OBU_SIZE_BYTES,
-        obu_size + PRE_OBU_SIZE_BYTES,
+    data_size =
+        write_tiles_in_tg_obus(cpi, data, &max_tile_size, &max_tile_col_size,
 #if CONFIG_EXT_TILE
-        &saved_wb,
+                               &saved_wb,
 #endif
-        1 /* cm->error_resilient_mode */, obu_extension_header);
+                               obu_extension_header);
   }
 
 #endif  // CONFIG_OBU
@@ -4969,7 +4959,7 @@
 
     if (cm->show_existing_frame) {
       *size = aom_wb_bytes_written(&wb);
-      return;
+      return AOM_CODEC_OK;
     }
 
     // We do not know these in advance. Output placeholder bit.
diff --git a/test/aom_integer_test.cc b/test/aom_integer_test.cc
index 7c1535b..4daa64b 100644
--- a/test/aom_integer_test.cc
+++ b/test/aom_integer_test.cc
@@ -30,6 +30,10 @@
   uint32_t value = 0;
   aom_uleb_decode(&leb128_bytes[0], num_leb128_bytes, &value);
   ASSERT_EQ(expected_value, value);
+
+  // Make sure the decoder stops on the last marked LEB128 byte.
+  aom_uleb_decode(&leb128_bytes[0], num_leb128_bytes + 1, &value);
+  ASSERT_EQ(expected_value, value);
 }
 
 TEST(AomLeb128, EncodeTest) {
diff --git a/tools/obu_parser.cc b/tools/obu_parser.cc
index d63a484..667019a 100644
--- a/tools/obu_parser.cc
+++ b/tools/obu_parser.cc
@@ -153,10 +153,8 @@
 }
 
 bool DumpObu(const uint8_t *data, int length) {
-  const int kObuLengthFieldSizeBytes = 4;
   const int kObuHeaderLengthSizeBytes = 1;
-  const int kMinimumBytesRequired =
-      kObuLengthFieldSizeBytes + kObuHeaderLengthSizeBytes;
+  const int kMinimumBytesRequired = 1 + kObuHeaderLengthSizeBytes;
   int consumed = 0;
   ObuHeader obu_header;
   while (consumed < length) {
@@ -173,10 +171,13 @@
 
 #if CONFIG_OBU_SIZING
     uint32_t obu_size = 0;
-    aom_uleb_decode(data + consumed, kObuLengthFieldSizeBytes, &obu_size);
+    aom_uleb_decode(data + consumed, sizeof(obu_size), &obu_size);
     const int current_obu_length = static_cast<int>(obu_size);
+    const size_t length_field_size = aom_uleb_size_in_bytes(obu_size);
 #else
     const int current_obu_length = mem_get_le32(data + consumed);
+    const int kObuLengthFieldSizeBytes = 4;
+    const size_t length_field_size = kObuLengthFieldSizeBytes;
 #endif  // CONFIG_OBU_SIZING
 
     if (current_obu_length > remaining) {
@@ -186,7 +187,7 @@
               consumed, current_obu_length, remaining);
       return false;
     }
-    consumed += kObuLengthFieldSizeBytes;
+    consumed += length_field_size;
 
     obu_header = kEmptyObu;
     const uint8_t obu_header_byte = *(data + consumed);