Commit 8a3f55f2 authored by John Koleszar's avatar John Koleszar

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
parent c5b31705
......@@ -169,10 +169,10 @@ typedef struct VP9Common {
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;
......
......@@ -1275,12 +1275,13 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
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 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
* 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;
}
if (!scaling_active) {
pc->display_width = pc->Width;
pc->display_height = pc->Height;
}
data += 5;
if (width != pc->Width || height != pc->Height) {
if (pc->Width <= 0) {
......
......@@ -2270,7 +2270,18 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
{
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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
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 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
/* 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;
......
......@@ -1115,6 +1115,9 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
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 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
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 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
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 @@ int vp9_set_internal_size(VP9_PTR comp,
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 @@ int vp9_set_internal_size(VP9_PTR comp,
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);
cm->horiz_scale = horiz_mode;
cm->vert_scale = vert_mode;
Scale2Ratio(horiz_mode, &hr, &hs);
Scale2Ratio(vert_mode, &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;
// 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment