Compressed/uncompressed frame header changes.
Adding API to read/write uncompressed frame header bits (it is not final yet). Separate functions to read/write uncompressed header. Moving clr_type, error_resilient_mode, refresh_frame_context, frame_parallel_decoding_mode, frame_context_idx from compressed partition to uncompressed frame header. Change-Id: Id3ed8a387980c652ae147549412f4ec24a0a5bd0
This commit is contained in:
@@ -60,4 +60,9 @@ static INLINE int multiple16(int value) {
|
||||
return (value + 15) & ~15;
|
||||
}
|
||||
|
||||
#define SYNC_CODE_0 0x49
|
||||
#define SYNC_CODE_1 0x83
|
||||
#define SYNC_CODE_2 0x42
|
||||
|
||||
|
||||
#endif // VP9_COMMON_VP9_COMMON_H_
|
||||
|
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef VP9_COMMON_VP9_HEADER_H_
|
||||
#define VP9_COMMON_VP9_HEADER_H_
|
||||
|
||||
/* 24 bits total */
|
||||
typedef struct {
|
||||
unsigned int type: 1;
|
||||
unsigned int version: 3;
|
||||
unsigned int show_frame: 1;
|
||||
|
||||
/* Allow 2^20 bytes = 8 megabits for first partition */
|
||||
|
||||
unsigned int first_partition_length_in_bytes: 19;
|
||||
|
||||
#ifdef PACKET_TESTING
|
||||
unsigned int frame_number;
|
||||
unsigned int update_gold: 1;
|
||||
unsigned int uses_gold: 1;
|
||||
unsigned int update_last: 1;
|
||||
unsigned int uses_last: 1;
|
||||
#endif
|
||||
} VP9_HEADER;
|
||||
|
||||
#ifdef PACKET_TESTING
|
||||
#define VP9_HEADER_SIZE 8
|
||||
#else
|
||||
#define VP9_HEADER_SIZE 3
|
||||
#endif
|
||||
|
||||
#endif // VP9_COMMON_VP9_HEADER_H_
|
@@ -11,6 +11,8 @@
|
||||
#ifndef VP9_COMMON_VP9_MODECONT_H_
|
||||
#define VP9_COMMON_VP9_MODECONT_H_
|
||||
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
|
||||
extern const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4];
|
||||
|
||||
#endif // VP9_COMMON_VP9_MODECONT_H_
|
||||
|
@@ -24,10 +24,6 @@
|
||||
#include "vp9/common/vp9_postproc.h"
|
||||
#endif
|
||||
|
||||
/*#ifdef PACKET_TESTING*/
|
||||
#include "vp9/common/vp9_header.h"
|
||||
/*#endif*/
|
||||
|
||||
/* Create/destroy static data structures. */
|
||||
|
||||
void vp9_initialize_common(void);
|
||||
|
@@ -10,29 +10,30 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "vp9/decoder/vp9_onyxd_int.h"
|
||||
#include "./vp9_rtcd.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vpx_scale/vpx_scale.h"
|
||||
|
||||
#include "vp9/common/vp9_extend.h"
|
||||
#include "vp9/common/vp9_modecont.h"
|
||||
#include "vp9/common/vp9_common.h"
|
||||
#include "vp9/common/vp9_header.h"
|
||||
#include "vp9/common/vp9_reconintra.h"
|
||||
#include "vp9/common/vp9_reconinter.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/decoder/vp9_decodframe.h"
|
||||
#include "vp9/decoder/vp9_detokenize.h"
|
||||
#include "vp9/common/vp9_invtrans.h"
|
||||
#include "vp9/common/vp9_alloccommon.h"
|
||||
#include "vp9/common/vp9_entropymode.h"
|
||||
#include "vp9/common/vp9_quant_common.h"
|
||||
#include "vpx_scale/vpx_scale.h"
|
||||
|
||||
#include "vp9/decoder/vp9_decodemv.h"
|
||||
#include "vp9/common/vp9_extend.h"
|
||||
#include "vp9/common/vp9_modecont.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vp9/decoder/vp9_dboolhuff.h"
|
||||
|
||||
#include "vp9/common/vp9_seg_common.h"
|
||||
#include "vp9/common/vp9_tile_common.h"
|
||||
#include "./vp9_rtcd.h"
|
||||
|
||||
#include "vp9/decoder/vp9_dboolhuff.h"
|
||||
#include "vp9/decoder/vp9_decodframe.h"
|
||||
#include "vp9/decoder/vp9_detokenize.h"
|
||||
#include "vp9/decoder/vp9_decodemv.h"
|
||||
#include "vp9/decoder/vp9_onyxd_int.h"
|
||||
#include "vp9/decoder/vp9_read_bit_buffer.h"
|
||||
|
||||
|
||||
// #define DEC_DEBUG
|
||||
#ifdef DEC_DEBUG
|
||||
@@ -743,32 +744,24 @@ static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) {
|
||||
: vp9_read_literal(r, 2);
|
||||
}
|
||||
|
||||
static const uint8_t *read_frame_size(VP9_COMMON *const pc, const uint8_t *data,
|
||||
const uint8_t *data_end,
|
||||
static void read_frame_size(VP9_COMMON *cm,
|
||||
struct vp9_read_bit_buffer *rb,
|
||||
int *width, int *height) {
|
||||
if (data + 4 < data_end) {
|
||||
const int w = read_le16(data);
|
||||
const int h = read_le16(data + 2);
|
||||
const int w = vp9_rb_read_literal(rb, 16);
|
||||
const int h = vp9_rb_read_literal(rb, 16);
|
||||
if (w <= 0)
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Invalid frame width");
|
||||
|
||||
if (h <= 0)
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Invalid frame height");
|
||||
*width = w;
|
||||
*height = h;
|
||||
data += 4;
|
||||
} else {
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Failed to read frame size");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active,
|
||||
const uint8_t *data,
|
||||
const uint8_t *data_end) {
|
||||
static void setup_frame_size(VP9D_COMP *pbi, int scaling_active,
|
||||
struct vp9_read_bit_buffer *rb) {
|
||||
// If error concealment is enabled we should only parse the new size
|
||||
// if we have enough data. Otherwise we will end up with the wrong size.
|
||||
VP9_COMMON *const pc = &pbi->common;
|
||||
@@ -778,9 +771,9 @@ static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active,
|
||||
int height = pc->height;
|
||||
|
||||
if (scaling_active)
|
||||
data = read_frame_size(pc, data, data_end, &display_width, &display_height);
|
||||
read_frame_size(pc, rb, &display_width, &display_height);
|
||||
|
||||
data = read_frame_size(pc, data, data_end, &width, &height);
|
||||
read_frame_size(pc, rb, &width, &height);
|
||||
|
||||
if (pc->width != width || pc->height != height) {
|
||||
if (!pbi->initial_width || !pbi->initial_height) {
|
||||
@@ -806,8 +799,6 @@ static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active,
|
||||
|
||||
vp9_update_frame_size(pc);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void update_frame_context(FRAME_CONTEXT *fc) {
|
||||
@@ -937,59 +928,78 @@ static void decode_tiles(VP9D_COMP *pbi,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void error_handler(void *data, int bit_offset) {
|
||||
VP9_COMMON *const cm = (VP9_COMMON *)data;
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
|
||||
}
|
||||
|
||||
size_t read_uncompressed_header(VP9D_COMP *pbi,
|
||||
struct vp9_read_bit_buffer *rb) {
|
||||
VP9_COMMON *const cm = &pbi->common;
|
||||
|
||||
int scaling_active;
|
||||
cm->last_frame_type = cm->frame_type;
|
||||
cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
|
||||
cm->version = vp9_rb_read_literal(rb, 3);
|
||||
cm->show_frame = vp9_rb_read_bit(rb);
|
||||
scaling_active = vp9_rb_read_bit(rb);
|
||||
cm->subsampling_x = vp9_rb_read_bit(rb);
|
||||
cm->subsampling_y = vp9_rb_read_bit(rb);
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 ||
|
||||
vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 ||
|
||||
vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) {
|
||||
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
||||
"Invalid frame sync code");
|
||||
}
|
||||
}
|
||||
setup_frame_size(pbi, scaling_active, rb);
|
||||
|
||||
cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
|
||||
cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);
|
||||
|
||||
cm->error_resilient_mode = vp9_rb_read_bit(rb);
|
||||
if (!cm->error_resilient_mode) {
|
||||
cm->refresh_frame_context = vp9_rb_read_bit(rb);
|
||||
cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
|
||||
} else {
|
||||
cm->refresh_frame_context = 0;
|
||||
cm->frame_parallel_decoding_mode = 1;
|
||||
}
|
||||
|
||||
return vp9_rb_read_literal(rb, 16);
|
||||
}
|
||||
|
||||
int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
int i;
|
||||
vp9_reader header_bc, residual_bc;
|
||||
VP9_COMMON *const pc = &pbi->common;
|
||||
MACROBLOCKD *const xd = &pbi->mb;
|
||||
const uint8_t *data = pbi->source;
|
||||
const uint8_t *data_end = data + pbi->source_sz;
|
||||
size_t first_partition_size = 0;
|
||||
YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
|
||||
int i;
|
||||
const uint8_t *data = pbi->source;
|
||||
const uint8_t *data_end = pbi->source + pbi->source_sz;
|
||||
|
||||
xd->corrupted = 0; // start with no corruption of current frame
|
||||
struct vp9_read_bit_buffer rb = { data, data_end, 0,
|
||||
pc, error_handler };
|
||||
const size_t first_partition_size = read_uncompressed_header(pbi, &rb);
|
||||
const int keyframe = pc->frame_type == KEY_FRAME;
|
||||
|
||||
data += vp9_rb_bytes_read(&rb);
|
||||
xd->corrupted = 0;
|
||||
new_fb->corrupted = 0;
|
||||
|
||||
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;
|
||||
scaling_active = (data[0] >> 5) & 1;
|
||||
pc->subsampling_x = (data[0] >> 6) & 1;
|
||||
pc->subsampling_y = (data[0] >> 7) & 1;
|
||||
first_partition_size = read_le16(data + 1);
|
||||
|
||||
if (!read_is_valid(data, first_partition_size, data_end))
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Truncated packet or corrupt partition 0 length");
|
||||
|
||||
data += 3;
|
||||
|
||||
vp9_setup_version(pc);
|
||||
|
||||
if (pc->frame_type == KEY_FRAME) {
|
||||
// When error concealment is enabled we should only check the sync
|
||||
// code if we have enough bits available
|
||||
if (data + 3 < data_end) {
|
||||
if (data[0] != 0x49 || data[1] != 0x83 || data[2] != 0x42)
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
|
||||
"Invalid frame sync code");
|
||||
}
|
||||
data += 3;
|
||||
}
|
||||
|
||||
data = setup_frame_size(pbi, scaling_active, data, data_end);
|
||||
}
|
||||
|
||||
if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
|
||||
if ((!pbi->decoded_key_frame && !keyframe) ||
|
||||
pc->width == 0 || pc->height == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
vp9_setup_version(pc);
|
||||
if (!read_is_valid(data, first_partition_size, data_end))
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Truncated packet or corrupt partition 0 length");
|
||||
|
||||
init_frame(pbi);
|
||||
|
||||
// Reset the frame pointers to the current frame size
|
||||
@@ -1001,9 +1011,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
|
||||
"Failed to allocate bool decoder 0");
|
||||
|
||||
pc->clr_type = (YUV_TYPE)vp9_read_bit(&header_bc);
|
||||
pc->error_resilient_mode = vp9_read_bit(&header_bc);
|
||||
|
||||
setup_loopfilter(pc, xd, &header_bc);
|
||||
|
||||
setup_quantization(pbi, &header_bc);
|
||||
@@ -1025,7 +1032,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
// Determine if the golden frame or ARF buffer should be updated and how.
|
||||
// For all non key frames the GF and ARF refresh flags and sign bias
|
||||
// flags must be set explicitly.
|
||||
if (pc->frame_type == KEY_FRAME) {
|
||||
if (keyframe) {
|
||||
for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
|
||||
pc->active_ref_idx[i] = pc->new_fb_idx;
|
||||
} else {
|
||||
@@ -1050,15 +1057,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
|
||||
}
|
||||
|
||||
if (!pc->error_resilient_mode) {
|
||||
pc->refresh_frame_context = vp9_read_bit(&header_bc);
|
||||
pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc);
|
||||
} else {
|
||||
pc->refresh_frame_context = 0;
|
||||
pc->frame_parallel_decoding_mode = 1;
|
||||
}
|
||||
|
||||
pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
|
||||
pc->fc = pc->frame_contexts[pc->frame_context_idx];
|
||||
|
||||
setup_segmentation(pc, xd, &header_bc);
|
||||
@@ -1068,7 +1066,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
setup_txfm_mode(pc, xd->lossless, &header_bc);
|
||||
|
||||
// Read inter mode probability context updates
|
||||
if (pc->frame_type != KEY_FRAME) {
|
||||
if (!keyframe) {
|
||||
int i, j;
|
||||
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
|
||||
for (j = 0; j < 4; ++j)
|
||||
@@ -1076,7 +1074,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
pc->fc.vp9_mode_contexts[i][j] = vp9_read_prob(&header_bc);
|
||||
}
|
||||
// Is this needed ?
|
||||
if (pc->frame_type == KEY_FRAME)
|
||||
if (keyframe)
|
||||
vp9_default_coef_probs(pc);
|
||||
|
||||
update_frame_context(&pc->fc);
|
||||
@@ -1109,7 +1107,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted;
|
||||
|
||||
if (!pbi->decoded_key_frame) {
|
||||
if (pc->frame_type == KEY_FRAME && !new_fb->corrupted)
|
||||
if (keyframe && !new_fb->corrupted)
|
||||
pbi->decoded_key_frame = 1;
|
||||
else
|
||||
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
|
||||
@@ -1120,7 +1118,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
|
||||
if (!pc->error_resilient_mode && !pc->frame_parallel_decoding_mode) {
|
||||
vp9_adapt_coef_probs(pc);
|
||||
|
||||
if (pc->frame_type != KEY_FRAME) {
|
||||
if (!keyframe) {
|
||||
vp9_adapt_mode_probs(pc);
|
||||
vp9_adapt_mode_context(pc);
|
||||
vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
|
||||
|
50
vp9/decoder/vp9_read_bit_buffer.h
Normal file
50
vp9/decoder/vp9_read_bit_buffer.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef VP9_READ_BIT_BUFFER_
|
||||
#define VP9_READ_BIT_BUFFER_
|
||||
|
||||
typedef void (*vp9_rb_error_handler)(void *data, int bit_offset);
|
||||
|
||||
struct vp9_read_bit_buffer {
|
||||
const uint8_t *bit_buffer;
|
||||
const uint8_t *bit_buffer_end;
|
||||
size_t bit_offset;
|
||||
|
||||
void *error_handler_data;
|
||||
vp9_rb_error_handler error_handler;
|
||||
};
|
||||
|
||||
static size_t vp9_rb_bytes_read(struct vp9_read_bit_buffer *rb) {
|
||||
return rb->bit_offset / CHAR_BIT + (rb->bit_offset % CHAR_BIT > 0);
|
||||
}
|
||||
|
||||
static int vp9_rb_read_bit(struct vp9_read_bit_buffer *rb) {
|
||||
const int off = rb->bit_offset;
|
||||
const int p = off / CHAR_BIT;
|
||||
const int q = CHAR_BIT - 1 - off % CHAR_BIT;
|
||||
if (rb->bit_buffer + p >= rb->bit_buffer_end) {
|
||||
rb->error_handler(rb->error_handler_data, rb->bit_offset);
|
||||
return 0;
|
||||
} else {
|
||||
const int bit = (rb->bit_buffer[p] & (1 << q)) >> q;
|
||||
rb->bit_offset = off + 1;
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
|
||||
static int vp9_rb_read_literal(struct vp9_read_bit_buffer *rb, int bits) {
|
||||
int value = 0, bit;
|
||||
for (bit = bits - 1; bit >= 0; bit--)
|
||||
value |= vp9_rb_read_bit(rb) << bit;
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif // VP9_READ_BIT_BUFFER_
|
@@ -12,26 +12,28 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vp9/common/vp9_header.h"
|
||||
#include "vp9/encoder/vp9_encodemv.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
|
||||
#include "vp9/common/vp9_entropymode.h"
|
||||
#include "vp9/common/vp9_entropymv.h"
|
||||
#include "vp9/common/vp9_findnearmv.h"
|
||||
#include "vp9/common/vp9_tile_common.h"
|
||||
#include "vp9/encoder/vp9_mcomp.h"
|
||||
#include "vp9/common/vp9_systemdependent.h"
|
||||
#include "vp9/common/vp9_pragmas.h"
|
||||
#include "vpx/vpx_encoder.h"
|
||||
#include "vpx_mem/vpx_mem.h"
|
||||
#include "vp9/encoder/vp9_bitstream.h"
|
||||
#include "vp9/encoder/vp9_segmentation.h"
|
||||
|
||||
#include "vp9/common/vp9_seg_common.h"
|
||||
#include "vp9/common/vp9_pred_common.h"
|
||||
#include "vp9/common/vp9_entropy.h"
|
||||
#include "vp9/common/vp9_entropymv.h"
|
||||
#include "vp9/common/vp9_mvref_common.h"
|
||||
#include "vp9/common/vp9_treecoder.h"
|
||||
#include "vp9/common/vp9_systemdependent.h"
|
||||
#include "vp9/common/vp9_pragmas.h"
|
||||
|
||||
#include "vp9/encoder/vp9_mcomp.h"
|
||||
#include "vp9/encoder/vp9_encodemv.h"
|
||||
#include "vp9/encoder/vp9_bitstream.h"
|
||||
#include "vp9/encoder/vp9_segmentation.h"
|
||||
#include "vp9/encoder/vp9_write_bit_buffer.h"
|
||||
|
||||
|
||||
#if defined(SECTIONBITS_OUTPUT)
|
||||
unsigned __int64 Sectionbits[500];
|
||||
@@ -1278,10 +1280,6 @@ static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PACKET_TESTING
|
||||
FILE *vpxlogc = 0;
|
||||
#endif
|
||||
|
||||
static void decide_kf_ymode_entropy(VP9_COMP *cpi) {
|
||||
int mode_cost[MB_MODE_COUNT];
|
||||
int bestcost = INT_MAX;
|
||||
@@ -1482,61 +1480,64 @@ static void encode_segmentation(VP9_COMP *cpi, vp9_writer *w) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void write_uncompressed_header(VP9_COMMON *cm,
|
||||
struct vp9_write_bit_buffer *wb) {
|
||||
const int scaling_active = cm->width != cm->display_width ||
|
||||
cm->height != cm->display_height;
|
||||
|
||||
vp9_wb_write_bit(wb, cm->frame_type);
|
||||
vp9_wb_write_literal(wb, cm->version, 3);
|
||||
vp9_wb_write_bit(wb, cm->show_frame);
|
||||
vp9_wb_write_bit(wb, scaling_active);
|
||||
vp9_wb_write_bit(wb, cm->subsampling_x);
|
||||
vp9_wb_write_bit(wb, cm->subsampling_y);
|
||||
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
vp9_wb_write_literal(wb, SYNC_CODE_0, 8);
|
||||
vp9_wb_write_literal(wb, SYNC_CODE_1, 8);
|
||||
vp9_wb_write_literal(wb, SYNC_CODE_2, 8);
|
||||
}
|
||||
|
||||
if (scaling_active) {
|
||||
vp9_wb_write_literal(wb, cm->display_width, 16);
|
||||
vp9_wb_write_literal(wb, cm->display_height, 16);
|
||||
}
|
||||
|
||||
vp9_wb_write_literal(wb, cm->width, 16);
|
||||
vp9_wb_write_literal(wb, cm->height, 16);
|
||||
|
||||
vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
|
||||
vp9_wb_write_bit(wb, cm->clr_type);
|
||||
|
||||
vp9_wb_write_bit(wb, cm->error_resilient_mode);
|
||||
if (!cm->error_resilient_mode) {
|
||||
vp9_wb_write_bit(wb, cm->refresh_frame_context);
|
||||
vp9_wb_write_bit(wb, cm->frame_parallel_decoding_mode);
|
||||
}
|
||||
}
|
||||
|
||||
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
|
||||
int i;
|
||||
VP9_HEADER oh;
|
||||
int i, bytes_packed;
|
||||
VP9_COMMON *const pc = &cpi->common;
|
||||
vp9_writer header_bc, residual_bc;
|
||||
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
||||
int extra_bytes_packed = 0;
|
||||
|
||||
uint8_t *cx_data = dest;
|
||||
struct vp9_write_bit_buffer wb = {dest, 0};
|
||||
struct vp9_write_bit_buffer first_partition_size_wb;
|
||||
|
||||
oh.show_frame = (int) pc->show_frame;
|
||||
oh.type = (int)pc->frame_type;
|
||||
oh.version = pc->version;
|
||||
oh.first_partition_length_in_bytes = 0;
|
||||
write_uncompressed_header(pc, &wb);
|
||||
first_partition_size_wb = wb;
|
||||
vp9_wb_write_literal(&wb, 0, 16); // don't know in advance first part. size
|
||||
|
||||
cx_data += 3;
|
||||
|
||||
#if defined(SECTIONBITS_OUTPUT)
|
||||
Sectionbits[active_section = 1] += sizeof(VP9_HEADER) * 8 * 256;
|
||||
#endif
|
||||
bytes_packed = vp9_rb_bytes_written(&wb);
|
||||
cx_data += bytes_packed;
|
||||
|
||||
compute_update_table();
|
||||
|
||||
/* every keyframe send startcode, width, height, scale factor, clamp
|
||||
* and color type.
|
||||
*/
|
||||
if (oh.type == KEY_FRAME) {
|
||||
// Start / synch code
|
||||
cx_data[0] = 0x49;
|
||||
cx_data[1] = 0x83;
|
||||
cx_data[2] = 0x42;
|
||||
extra_bytes_packed = 3;
|
||||
cx_data += extra_bytes_packed;
|
||||
}
|
||||
|
||||
if (pc->width != pc->display_width || pc->height != pc->display_height) {
|
||||
write_le16(cx_data, pc->display_width);
|
||||
write_le16(cx_data + 2, pc->display_height);
|
||||
cx_data += 4;
|
||||
extra_bytes_packed += 4;
|
||||
}
|
||||
|
||||
write_le16(cx_data, pc->width);
|
||||
write_le16(cx_data + 2, pc->height);
|
||||
extra_bytes_packed += 4;
|
||||
cx_data += 4;
|
||||
|
||||
vp9_start_encode(&header_bc, cx_data);
|
||||
|
||||
// TODO(jkoleszar): remove these two unused bits?
|
||||
vp9_write_bit(&header_bc, pc->clr_type);
|
||||
|
||||
// error resilient mode
|
||||
vp9_write_bit(&header_bc, pc->error_resilient_mode);
|
||||
|
||||
encode_loopfilter(pc, xd, &header_bc);
|
||||
|
||||
encode_quantization(pc, &header_bc);
|
||||
@@ -1617,14 +1618,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
|
||||
vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2);
|
||||
}
|
||||
|
||||
if (!pc->error_resilient_mode) {
|
||||
vp9_write_bit(&header_bc, pc->refresh_frame_context);
|
||||
vp9_write_bit(&header_bc, pc->frame_parallel_decoding_mode);
|
||||
}
|
||||
|
||||
vp9_write_literal(&header_bc, pc->frame_context_idx,
|
||||
NUM_FRAME_CONTEXTS_LG2);
|
||||
|
||||
#ifdef ENTROPY_STATS
|
||||
if (pc->frame_type == INTER_FRAME)
|
||||
active_section = 0;
|
||||
@@ -1820,27 +1813,11 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
|
||||
|
||||
vp9_stop_encode(&header_bc);
|
||||
|
||||
oh.first_partition_length_in_bytes = header_bc.pos;
|
||||
|
||||
/* update frame tag */
|
||||
{
|
||||
int scaling = (pc->width != pc->display_width ||
|
||||
pc->height != pc->display_height);
|
||||
int v = (oh.first_partition_length_in_bytes << 8) |
|
||||
(pc->subsampling_y << 7) |
|
||||
(pc->subsampling_x << 6) |
|
||||
(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;
|
||||
}
|
||||
|
||||
*size = VP9_HEADER_SIZE + extra_bytes_packed + header_bc.pos;
|
||||
// first partition size
|
||||
assert(header_bc.pos <= 0xffff);
|
||||
vp9_wb_write_literal(&first_partition_size_wb, header_bc.pos, 16);
|
||||
*size = bytes_packed + header_bc.pos;
|
||||
|
||||
if (pc->frame_type == KEY_FRAME) {
|
||||
decide_kf_ymode_entropy(cpi);
|
||||
|
@@ -258,9 +258,6 @@ void vp9_initialize_enc() {
|
||||
init_done = 1;
|
||||
}
|
||||
}
|
||||
#ifdef PACKET_TESTING
|
||||
extern FILE *vpxlogc;
|
||||
#endif
|
||||
|
||||
static void setup_features(VP9_COMP *cpi) {
|
||||
MACROBLOCKD *xd = &cpi->mb.e_mbd;
|
||||
|
42
vp9/encoder/vp9_write_bit_buffer.h
Normal file
42
vp9/encoder/vp9_write_bit_buffer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef VP9_BIT_WRITE_BUFFER_H_
|
||||
#define VP9_BIT_WRITE_BUFFER_H_
|
||||
|
||||
#include "vpx/vpx_integer.h"
|
||||
|
||||
struct vp9_write_bit_buffer {
|
||||
uint8_t *bit_buffer;
|
||||
size_t bit_offset;
|
||||
};
|
||||
|
||||
static size_t vp9_rb_bytes_written(struct vp9_write_bit_buffer *wb) {
|
||||
return wb->bit_offset / CHAR_BIT + (wb->bit_offset % CHAR_BIT > 0);
|
||||
}
|
||||
|
||||
static void vp9_wb_write_bit(struct vp9_write_bit_buffer *wb, int bit) {
|
||||
const int off = wb->bit_offset;
|
||||
const int p = off / CHAR_BIT;
|
||||
const int q = CHAR_BIT - 1 - off % CHAR_BIT;
|
||||
wb->bit_buffer[p] &= ~(1 << q);
|
||||
wb->bit_buffer[p] |= bit << q;
|
||||
wb->bit_offset = off + 1;
|
||||
}
|
||||
|
||||
static void vp9_wb_write_literal(struct vp9_write_bit_buffer *wb,
|
||||
int data, int bits) {
|
||||
int bit;
|
||||
for (bit = bits - 1; bit >= 0; bit--)
|
||||
vp9_wb_write_bit(wb, (data >> bit) & 1);
|
||||
}
|
||||
|
||||
|
||||
#endif // VP9_BIT_WRITE_BUFFER_H_
|
@@ -38,7 +38,6 @@ VP9_COMMON_SRCS-yes += common/vp9_entropymv.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_enums.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_extend.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_findnearmv.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_header.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_idct.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_invtrans.h
|
||||
VP9_COMMON_SRCS-yes += common/vp9_loopfilter.h
|
||||
|
@@ -215,26 +215,19 @@ static vpx_codec_err_t vp8_peek_si(const uint8_t *data,
|
||||
if (data + data_sz <= data)
|
||||
res = VPX_CODEC_INVALID_PARAM;
|
||||
else {
|
||||
/* Parse uncompresssed part of key frame header.
|
||||
* 3 bytes:- including version, frame type and an offset
|
||||
* 3 bytes:- sync code (0x49, 0x83, 0x42)
|
||||
* 4 bytes:- including image width and height in the lowest 14 bits
|
||||
* of each 2-byte value.
|
||||
*/
|
||||
si->is_kf = 0;
|
||||
|
||||
if (data_sz >= 10 && !(data[0] & 0x01)) { /* I-Frame */
|
||||
const uint8_t *c = data + 3;
|
||||
if (data_sz >= 8 && !(data[0] & 0x80)) { /* I-Frame */
|
||||
const uint8_t *c = data + 1;
|
||||
si->is_kf = 1;
|
||||
|
||||
/* vet via sync code */
|
||||
if (c[0] != 0x49 || c[1] != 0x83 || c[2] != 0x42)
|
||||
if (c[0] != SYNC_CODE_0 || c[1] != SYNC_CODE_1 || c[2] != SYNC_CODE_2)
|
||||
res = VPX_CODEC_UNSUP_BITSTREAM;
|
||||
|
||||
si->w = (c[3] | (c[4] << 8));
|
||||
si->h = (c[5] | (c[6] << 8));
|
||||
si->w = (c[3] << 8) | c[4];
|
||||
si->h = (c[5] << 8) | c[6];
|
||||
|
||||
/*printf("w=%d, h=%d\n", si->w, si->h);*/
|
||||
// printf("w=%d, h=%d\n", si->w, si->h);
|
||||
if (!(si->h | si->w))
|
||||
res = VPX_CODEC_UNSUP_BITSTREAM;
|
||||
} else
|
||||
@@ -242,7 +235,6 @@ static vpx_codec_err_t vp8_peek_si(const uint8_t *data,
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx,
|
||||
|
@@ -28,6 +28,7 @@ VP9_CX_SRCS-yes += encoder/vp9_encodemv.c
|
||||
VP9_CX_SRCS-yes += encoder/vp9_firstpass.c
|
||||
VP9_CX_SRCS-yes += encoder/vp9_block.h
|
||||
VP9_CX_SRCS-yes += encoder/vp9_boolhuff.h
|
||||
VP9_CX_SRCS-yes += encoder/vp9_write_bit_buffer.h
|
||||
VP9_CX_SRCS-yes += encoder/vp9_bitstream.h
|
||||
VP9_CX_SRCS-yes += encoder/vp9_encodeintra.h
|
||||
VP9_CX_SRCS-yes += encoder/vp9_encodemb.h
|
||||
|
@@ -24,6 +24,7 @@ VP9_DX_SRCS-yes += decoder/vp9_decodframe.c
|
||||
VP9_DX_SRCS-yes += decoder/vp9_decodframe.h
|
||||
VP9_DX_SRCS-yes += decoder/vp9_detokenize.c
|
||||
VP9_DX_SRCS-yes += decoder/vp9_dboolhuff.h
|
||||
VP9_DX_SRCS-yes += decoder/vp9_read_bit_buffer.h
|
||||
VP9_DX_SRCS-yes += decoder/vp9_decodemv.h
|
||||
VP9_DX_SRCS-yes += decoder/vp9_detokenize.h
|
||||
VP9_DX_SRCS-yes += decoder/vp9_onyxd.h
|
||||
|
Reference in New Issue
Block a user