Commit 18c83b37 authored by Dmitry Kovalev's avatar Dmitry Kovalev

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
parent a4dd99b3
......@@ -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_
/*
* 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);
......
This diff is collapsed.
/*
* 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,60 +1480,63 @@ static void encode_segmentation(VP9_COMP *cpi, vp9_writer *w) {
}
}
void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
int i;
VP9_HEADER oh;
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;
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;
oh.show_frame = (int) pc->show_frame;
oh.type = (int)pc->frame_type;
oh.version = pc->version;
oh.first_partition_length_in_bytes = 0;
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);
cx_data += 3;
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 defined(SECTIONBITS_OUTPUT)
Sectionbits[active_section = 1] += sizeof(VP9_HEADER) * 8 * 256;
#endif
if (scaling_active) {
vp9_wb_write_literal(wb, cm->display_width, 16);
vp9_wb_write_literal(wb, cm->display_height, 16);
}
compute_update_table();
vp9_wb_write_literal(wb, cm->width, 16);
vp9_wb_write_literal(wb, cm->height, 16);
/* 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;
}
vp9_wb_write_literal(wb, cm->frame_context_idx, NUM_FRAME_CONTEXTS_LG2);
vp9_wb_write_bit(wb, cm->clr_type);
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;
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, bytes_packed;
VP9_COMMON *const pc = &cpi->common;
vp9_writer header_bc, residual_bc;
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
write_le16(cx_data, pc->width);
write_le16(cx_data + 2, pc->height);
extra_bytes_packed += 4;
cx_data += 4;
uint8_t *cx_data = dest;
struct vp9_write_bit_buffer wb = {dest, 0};
struct vp9_write_bit_buffer first_partition_size_wb;
vp9_start_encode(&header_bc, cx_data);
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
// TODO(jkoleszar): remove these two unused bits?
vp9_write_bit(&header_bc, pc->clr_type);
bytes_packed = vp9_rb_bytes_written(&wb);
cx_data += bytes_packed;
// error resilient mode
vp9_write_bit(&header_bc, pc->error_resilient_mode);
compute_update_table();
vp9_start_encode(&header_bc, cx_data);
encode_loopfilter(pc, xd, &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;
......
/*
* 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
......
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