diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_bitstream.c | 145 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_write_bit_buffer.h | 42 |
3 files changed, 103 insertions, 87 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 15253406d..b19bf3a33 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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); diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index d42bcbb7e..e2f24848f 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -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; diff --git a/vp9/encoder/vp9_write_bit_buffer.h b/vp9/encoder/vp9_write_bit_buffer.h new file mode 100644 index 000000000..18cf40366 --- /dev/null +++ b/vp9/encoder/vp9_write_bit_buffer.h @@ -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_ |