shithub: libvpx

Download patch

ref: 8a3f55f2d459b1de112502d32719ffa56fe7604c
parent: c5b317057b292718afc07a842b69f5f06caadb4e
author: John Koleszar <jkoleszar@google.com>
date: Thu Mar 14 10:36:08 EDT 2013

Replace scaling byte with explicit display size

If the intended display size is different than the size the frame is
coded at, then send that size explicitly in the bitstream. Adds a new
bit to the frame header to indicate whether the extra size fields
are present.

Change-Id: I525c66f22d207efaf1e5f903c6a2a91b80245854

--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -169,10 +169,10 @@
 
   int Width;
   int Height;
+  int display_width;
+  int display_height;
   int last_width;
   int last_height;
-  int horiz_scale;
-  int vert_scale;
 
   YUV_TYPE clr_type;
   CLAMP_TYPE  clamp_type;
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1275,12 +1275,13 @@
   if (data_end - data < 3) {
     vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
   } else {
+    int scaling_active;
     pc->last_frame_type = pc->frame_type;
     pc->frame_type = (FRAME_TYPE)(data[0] & 1);
     pc->version = (data[0] >> 1) & 7;
     pc->show_frame = (data[0] >> 4) & 1;
-    first_partition_length_in_bytes =
-      (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
+    scaling_active = (data[0] >> 5) & 1;
+    first_partition_length_in_bytes = data[1] | (data[2] << 8);
 
     if (!read_is_valid(data, first_partition_length_in_bytes, data_end))
       vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
@@ -1310,14 +1311,20 @@
        * if we have enough data. Otherwise we will end up with the wrong
        * size.
        */
-      if (data + 5 < data_end) {
-        pc->Width  = read_le16(data);
+      if (scaling_active && data + 4 < data_end) {
+        pc->display_width = read_le16(data + 0);
+        pc->display_height = read_le16(data + 2);
+        data += 4;
+      }
+      if (data + 4 < data_end) {
+        pc->Width = read_le16(data + 0);
         pc->Height = read_le16(data + 2);
-
-        pc->horiz_scale = data[4] >> 4;
-        pc->vert_scale  = data[4] & 0x0F;
+        data += 4;
       }
-      data += 5;
+      if (!scaling_active) {
+        pc->display_width = pc->Width;
+        pc->display_height = pc->Height;
+      }
 
       if (width != pc->Width || height != pc->Height) {
         if (pc->Width <= 0) {
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -2270,7 +2270,18 @@
   {
     int v;
 
-    // support arbitrary resolutions
+    if (pc->Width != pc->display_width || pc->Height != pc->display_height) {
+      v = pc->display_width;
+      cx_data[0] = v;
+      cx_data[1] = v >> 8;
+
+      v = pc->display_height;
+      cx_data[2] = v;
+      cx_data[3] = v >> 8;
+      cx_data += 4;
+      extra_bytes_packed += 4;
+    }
+
     v = pc->Width;
     cx_data[0] = v;
     cx_data[1] = v >> 8;
@@ -2279,11 +2290,8 @@
     cx_data[2] = v;
     cx_data[3] = v >> 8;
 
-    // use a separate byte to store the scale factors, each ranging 0-15
-    cx_data[4] = (pc->horiz_scale << 4) | (pc->vert_scale);
-
-    extra_bytes_packed += 5;
-    cx_data += 5;
+    extra_bytes_packed += 4;
+    cx_data += 4;
   }
 
   vp9_start_encode(&header_bc, cx_data);
@@ -2801,11 +2809,15 @@
 
   /* update frame tag */
   {
-    int v = (oh.first_partition_length_in_bytes << 5) |
+    int scaling = (pc->Width != pc->display_width
+                   || pc->Height != pc->display_height);
+    int v = (oh.first_partition_length_in_bytes << 8) |
+            (scaling << 5) |
             (oh.show_frame << 4) |
             (oh.version << 1) |
             oh.type;
 
+    assert(oh.first_partition_length_in_bytes <= 0xffff);
     dest[0] = v;
     dest[1] = v >> 8;
     dest[2] = v >> 16;
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1115,6 +1115,9 @@
   cm->version = oxcf->Version;
   vp9_setup_version(cm);
 
+  cm->Width = oxcf->Width;
+  cm->Height = oxcf->Height;
+
   // change includes all joint functionality
   vp9_change_config(ptr, oxcf);
 
@@ -1299,8 +1302,8 @@
 
   cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
 
-  cm->Width       = cpi->oxcf.Width;
-  cm->Height      = cpi->oxcf.Height;
+  cm->display_width = cpi->oxcf.Width;
+  cm->display_height = cpi->oxcf.Height;
 
   // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
   if (cpi->oxcf.Sharpness > 7)
@@ -1308,18 +1311,6 @@
 
   cm->sharpness_level = cpi->oxcf.Sharpness;
 
-  if (cm->horiz_scale != NORMAL || cm->vert_scale != NORMAL) {
-    int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
-    int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
-
-    Scale2Ratio(cm->horiz_scale, &hr, &hs);
-    Scale2Ratio(cm->vert_scale, &vr, &vs);
-
-    // always go to the next whole number
-    cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
-    cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
-  }
-
   // Increasing the size of the frame beyond the first seen frame, or some
   // otherwise signalled maximum size, is not supported.
   // TODO(jkoleszar): exit gracefully.
@@ -4149,6 +4140,7 @@
                           VPX_SCALING horiz_mode, VPX_SCALING vert_mode) {
   VP9_COMP *cpi = (VP9_COMP *) comp;
   VP9_COMMON *cm = &cpi->common;
+  int hr = 0, hs = 0, vr = 0, vs = 0;
 
   if (horiz_mode > ONETWO)
     return -1;
@@ -4156,20 +4148,13 @@
   if (vert_mode > ONETWO)
     return -1;
 
-  if (cm->horiz_scale != horiz_mode || cm->vert_scale != vert_mode) {
-    int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
-    int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+  Scale2Ratio(horiz_mode, &hr, &hs);
+  Scale2Ratio(vert_mode, &vr, &vs);
 
-    cm->horiz_scale = horiz_mode;
-    cm->vert_scale = vert_mode;
+  // always go to the next whole number
+  cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
+  cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
 
-    Scale2Ratio(cm->horiz_scale, &hr, &hs);
-    Scale2Ratio(cm->vert_scale, &vr, &vs);
-
-    // always go to the next whole number
-    cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
-    cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
-  }
   assert(cm->Width <= cpi->initial_width);
   assert(cm->Height <= cpi->initial_height);
   update_frame_size(cpi);