Add util function for reading OBU type.

This began as an investigation into decoder_peek_si()
and decoder_peek_si_internal(). Both functions need
additional changes to function correctly, but since
existing code and tests depends on current behavior the
changes to those functions have been deferred and the
required updates noted in TODOs and comments within
decoder_peek_si_internal() within av1_dx_iface.c.

BUG=aomedia:1445

Change-Id: I89ee3f1a7adcf7c09938645d3fb2280ab1960698
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c
index 707629a..36f35a7 100644
--- a/av1/av1_dx_iface.c
+++ b/av1/av1_dx_iface.c
@@ -29,6 +29,7 @@
 
 #include "av1/decoder/decoder.h"
 #include "av1/decoder/decodeframe.h"
+#include "av1/decoder/obu.h"
 
 #include "av1/av1_iface_common.h"
 
@@ -178,9 +179,15 @@
   if (data + data_sz <= data) return AOM_CODEC_INVALID_PARAM;
 
   si->w = 0;
-  si->is_kf = 1;
+  si->h = 0;
+  si->is_kf = 0;
+
+  // TODO(tomfinegan): This function needs Sequence and Frame Header OBUs to
+  // operate properly. At present it hard codes the values to 1 for the keyframe
+  // and intra only flags, and assumes the data being parsed is a Sequence
+  // Header OBU.
   intra_only_flag = 1;
-  si->h = 1;
+  si->is_kf = 1;
 
 #if CONFIG_OBU_SIZING
   size_t length_field_size = 1;
@@ -195,7 +202,18 @@
   mem_get_le32(data);
 #endif
 
-  aom_rb_read_literal(&rb, 8);  // obu_header
+  const uint8_t obu_header = (uint8_t)aom_rb_read_literal(&rb, 8);
+  OBU_TYPE obu_type;
+
+  if (get_obu_type(obu_header, &obu_type) != 0)
+    return AOM_CODEC_UNSUP_BITSTREAM;
+
+  // This check is disabled because existing behavior is depended upon by
+  // decoder tests (see decode_test_driver.cc), scalability_decoder (see
+  // scalable_decoder.c), and decode_once() in this file.
+  // if (obu_type != OBU_SEQUENCE_HEADER)
+  //   return AOM_CODEC_INVALID_PARAM;
+
   av1_read_profile(&rb);        // profile
   aom_rb_read_literal(&rb, 4);  // level
 #if CONFIG_SCALABILITY
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index 5f09523..89f7f6f 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -41,6 +41,21 @@
 } SCALABILITY_STRUCTURES;
 #endif
 
+int get_obu_type(uint8_t obu_header, OBU_TYPE *obu_type) {
+  if (!obu_type) return -1;
+  *obu_type = (OBU_TYPE)((obu_header >> 3) & 0xF);
+  switch (*obu_type) {
+    case OBU_SEQUENCE_HEADER: break;
+    case OBU_TEMPORAL_DELIMITER: break;
+    case OBU_FRAME_HEADER: break;
+    case OBU_TILE_GROUP: break;
+    case OBU_METADATA: break;
+    case OBU_PADDING: break;
+    default: return -1;
+  }
+  return 0;
+}
+
 static OBU_TYPE read_obu_header(struct aom_read_bit_buffer *rb,
                                 size_t *header_size,
                                 uint8_t *obu_extension_header) {
diff --git a/av1/decoder/obu.h b/av1/decoder/obu.h
index fe7d2ad..70e20d0 100644
--- a/av1/decoder/obu.h
+++ b/av1/decoder/obu.h
@@ -12,6 +12,15 @@
 #ifndef AV1_DECODER_OBU_H
 #define AV1_DECODER_OBU_H
 
+#include "aom/aom_codec.h"
+#include "av1/decoder/decoder.h"
+
+// Extracts OBU type from 'obu_header_byte' and returns it via 'obu_type'
+// pointer.
+// Return value is 0 when the OBU header contains a valid OBU_TYPE value, -1
+// otherwise.
+int get_obu_type(uint8_t obu_header_byte, OBU_TYPE *obu_type);
+
 void av1_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
                                 const uint8_t *data_end,
                                 const uint8_t **p_data_end);
diff --git a/obudec.c b/obudec.c
index 6f60102..11c8758 100644
--- a/obudec.c
+++ b/obudec.c
@@ -17,6 +17,7 @@
 
 #include "aom_ports/mem_ops.h"
 #include "av1/common/common.h"
+#include "av1/decoder/obu.h"
 
 #define OBU_HEADER_SIZE_BYTES 1
 #define OBU_HEADER_EXTENSION_SIZE_BYTES 1
@@ -34,20 +35,6 @@
 #endif
 
 #if CONFIG_OBU_NO_IVF
-int read_obu_type(uint8_t obu_header, OBU_TYPE *obu_type) {
-  if (!obu_type) return -1;
-  const int obu_type_value = (obu_header >> 3) & 0xF;
-  switch (obu_type_value) {
-    case OBU_SEQUENCE_HEADER: *obu_type = OBU_SEQUENCE_HEADER; break;
-    case OBU_TEMPORAL_DELIMITER: *obu_type = OBU_TEMPORAL_DELIMITER; break;
-    case OBU_FRAME_HEADER: *obu_type = OBU_FRAME_HEADER; break;
-    case OBU_TILE_GROUP: *obu_type = OBU_TILE_GROUP; break;
-    case OBU_METADATA: *obu_type = OBU_METADATA; break;
-    case OBU_PADDING: *obu_type = OBU_PADDING; break;
-    default: return -1;
-  }
-  return 0;
-}
 
 // Reads OBU size from infile and returns 0 upon success. Returns obu_size via
 // output pointer obu_size. Returns -1 when reading or parsing fails. Always
@@ -130,7 +117,7 @@
     *bytes_read += obu_size;
 
     OBU_TYPE obu_type;
-    if (read_obu_type(data[length_field_size], &obu_type) != 0) {
+    if (get_obu_type(data[length_field_size], &obu_type) != 0) {
       warn("Invalid OBU type.\n");
       return 1;
     }
@@ -197,7 +184,7 @@
     return 0;
   }
   OBU_TYPE obu_type;
-  if (read_obu_type(obutd[obu_header_offset], &obu_type) != 0) {
+  if (get_obu_type(obutd[obu_header_offset], &obu_type) != 0) {
     warn("Invalid OBU type found while probing for OBU_TEMPORAL_DELIMITER.\n");
     return 0;
   }