UNPKG

jsvpx

Version:

Javascript implementation of libvpx

962 lines (666 loc) 25.1 kB
'use strict'; var vp8_loopfilter = require('../common/vp8_loopfilter'); var vp8_loop_filter_row_simple = vp8_loopfilter.vp8_loop_filter_row_simple; var vp8_loop_filter_row_normal = vp8_loopfilter.vp8_loop_filter_row_normal; var detokenize = require('../decoder/detokenize'); var decode_mb_tokens = detokenize.decode_mb_tokens; var vp8_reset_mb_tokens_context = detokenize.vp8_reset_mb_tokens_context; var bitreader = require('../../vpx_dsp/bitreader.js'); var vpx_read = bitreader.vpx_read; var vpx_read_bit = bitreader.vpx_read_bit; var entropymv = require('../common/entropymv.js'); var vp8_default_mv_context = entropymv.vp8_default_mv_context; var entropy = require('../common/entropy.js'); var vp8_default_coef_probs = entropy.vp8_default_coef_probs; var quant_common = require('../common/quant_common.js'); var vp8_dc_quant = quant_common.vp8_dc_quant; var vp8_dc2quant = quant_common.vp8_dc2quant; var vp8_dc_uv_quant = quant_common.vp8_dc_uv_quant; var vp8_ac_yquant = quant_common.vp8_ac_yquant; var vp8_ac2quant = quant_common.vp8_ac2quant; var vp8_ac_uv_quant = quant_common.vp8_ac_uv_quant; var reconinter = require('../common/reconinter.js'); var vp8_build_inter_predictors_mb = reconinter.vp8_build_inter_predictors_mb; var reconintra = require('../common/reconintra.js'); var predict_intra_chroma = reconintra.predict_intra_chroma; var predict_intra_luma = reconintra.predict_intra_luma; var dboolhuff = require('./dboolhuff.js'); var vp8dx_start_decode = dboolhuff.vp8dx_start_decode; var decodemv = require("./decodemv.js"); var vp8_decode_mode_mvs = decodemv.vp8_decode_mode_mvs; var entropymode = require('../common/entropymode.js'); var vp8_init_mbmode_probs = entropymode.vp8_init_mbmode_probs; var vpx_image = require('../../vpx/vpx_image.js'); var vpx_img_set_rect = vpx_image.vpx_img_set_rect; var img_alloc_helper = vpx_image.img_alloc_helper; var filter = require('../common/filter.js'); var vp8_sub_pel_filters = filter.vp8_sub_pel_filters; var vp8_bilinear_filters = filter.vp8_bilinear_filters; var c_utils = require('../../util/c_utils.js'); var copy_entropy_values = c_utils.copy_entropy_values; var memset = c_utils.memset; var memset_32 = c_utils.memset_32; var FRAME_HEADER_SZ = 3; var KEYFRAME_HEADER_SZ = 7; var CURRENT_FRAME = 0; var LAST_FRAME = 1; var GOLDEN_FRAME = 2; var ALTREF_FRAME = 3; var NUM_REF_FRAMES = 4; var MAX_MB_SEGMENTS = 4; var TOKEN_BLOCK_Y1 = 0; var TOKEN_BLOCK_UV = 1; var TOKEN_BLOCK_Y2 = 2; var VPX_PLANE_PACKED = 0; var VPX_PLANE_Y = 0; var VPX_PLANE_U = 1; var VPX_PLANE_V = 2; var VPX_PLANE_ALPHA = 3; var PLANE_PACKED = VPX_PLANE_PACKED; var PLANE_Y = VPX_PLANE_Y; var PLANE_U = VPX_PLANE_U; var PLANE_V = VPX_PLANE_V; var CURRENT_FRAME = 0; var LAST_FRAME = 1; var GOLDEN_FRAME = 2; var ALTREF_FRAME = 3; var NUM_REF_FRAMES = 4; var BORDER_PIXELS = 16; var MV_PROB_CNT = 19; var VPX_IMG_FMT_I420 = 258; var VPX_PLANE_PACKED = 0; var VPX_PLANE_Y = 0; var VPX_PLANE_U = 1; var VPX_PLANE_V = 2; var VPX_PLANE_ALPHA = 3; var PLANE_PACKED = VPX_PLANE_PACKED; var PLANE_Y = VPX_PLANE_Y; var PLANE_U = VPX_PLANE_U; var PLANE_V = VPX_PLANE_V; var PLANE_ALPHA = VPX_PLANE_ALPHA; var DC_PRED = 0; var B_PRED = 4; var CURRENT_FRAME = 0; var MB_FEATURE_TREE_PROBS = 3; var MAX_MB_SEGMENTS = 4; var FRAME_HEADER_SZ = 3; var KEYFRAME_HEADER_SZ = 7; /* * was dequant_init * @param {type} factors * @param {type} seg * @param {type} common * @returns {undefined} */ function vp8cx_init_de_quantizer(factors, seg, common) { var i = 0; var q = 0; var dqf = factors; var factor; var length = 1; if (seg.enabled === 1) { length = MAX_MB_SEGMENTS; } for (i = 0; i < length; i++) { q = common.mbmi_qindex; if (seg.enabled === 1) q = (!seg.abs) ? q + seg.quant_idx[i] : seg.quant_idx[i]; factor = dqf[i].factor; if (dqf[i].quant_idx !== q || common.delta_update) { factor[TOKEN_BLOCK_Y1][0] = vp8_dc_quant(q, common.y1dc_delta_q); factor[TOKEN_BLOCK_Y2][0] = vp8_dc2quant(q, common.y2dc_delta_q); factor[TOKEN_BLOCK_UV][0] = vp8_dc_uv_quant(q, common.uvdc_delta_q); factor[TOKEN_BLOCK_Y1][1] = vp8_ac_yquant(q); factor[TOKEN_BLOCK_Y2][1] = vp8_ac2quant(q, common.y2ac_delta_q); factor[TOKEN_BLOCK_UV][1] = vp8_ac_uv_quant(q, common.uvac_delta_q); dqf[i].quant_idx = q; } } } var img = {//img_index litteral y: null, u: null, v: null, data_32: null, y_off: 0, u_off: 0, v_off: 0, stride: 0, uv_stride: 0 }; var recon_above_off = new Uint32Array([0, 0, 0]); var recon_left_off = new Uint32Array([0, 0, 0]); function decode_mb_rows(ctx) { var mb_idx = 0; var pc = ctx.common; // change this later //var img = ctx.ref_frames[CURRENT_FRAME].img; //INTRA_FRAME var yv12_fb_new = ctx.ref_frames[CURRENT_FRAME].img;// cache reference img.stride = yv12_fb_new.stride[PLANE_Y]; img.uv_stride = yv12_fb_new.stride[PLANE_U]; img.y = img.v = img.u = yv12_fb_new.img_data; img.data_32 = yv12_fb_new.img_data.data_32; var mb_rows = ctx.mb_rows; var mb_cols = ctx.mb_cols; var recon_y_stride = yv12_fb_new.stride; var recon_uv_stride = yv12_fb_new.uv_stride; //vp8_setup_intra_recon(img.y, img.y_off, img.u_off, img.v_off, img.stride, img.uv_stride); //vp8_setup_intra_recon_top_line(yv12_fb_new); var planes = yv12_fb_new.planes_off; for (var row = 0, partition = 0; row < mb_rows; row++) { var mbi; var mbi_off = 0; var col = 0; var coeffs = 0; var coeffs_off = 0; img.y_off = planes[PLANE_Y]; img.u_off = planes[PLANE_U]; img.v_off = planes[PLANE_V]; img.y_off += (img.stride * row) << 4; img.u_off += (img.uv_stride * row) << 3; img.v_off += (img.uv_stride * row) << 3; mbi = ctx.mb_info_rows; //[1 + row]; mbi_off = (ctx.mb_info_rows_off[1 + row]); //coeffs = ctx.tokens[row & (ctx.token_hdr.partitions - 1)].coeffs; coeffs = ctx.tokens[row & (ctx.token_hdr.partitions - 1)].coeffs; //if (ctx.tokens[row & (ctx.token_hdr.partitions - 1)].coeffs === null) { //console.warn(ctx.tokens); //} recon_above_off[0] = img.y_off; recon_above_off[1] = img.u_off; recon_above_off[2] = img.v_off; recon_left_off[0] = recon_above_off[0] - 1; recon_left_off[1] = recon_above_off[1] - 1; recon_left_off[2] = recon_above_off[2] - 1; // Fix up the out-of-frame pixels var mbi_cache = mbi[mbi_off]; fixup_left(img.y, img.y_off, 16, img.stride, row, mbi_cache.mbmi.y_mode); fixup_left(img.u, img.u_off, 8, img.uv_stride, row, mbi_cache.mbmi.uv_mode); fixup_left(img.v, img.v_off, 8, img.uv_stride, row, mbi_cache.mbmi.uv_mode); //doesnt seem to do anything //if (row === 0) // img.y[img.y_off - img.stride - 1]= 127; //console.warn(img.y_off - img.stride - 1); //vp8_setup_intra_recon(img.y, img.y_off, img.u_off, img.v_off, img.stride, img.uv_stride); //probably line 485 for (col = 0; col < mb_cols; col++) { //if (col > 0) { if (row === 0) { //vp8_setup_intra_recon_top_line fixup_above(img.y, img.y_off, 16, img.stride, col, mbi[mbi_off].mbmi.y_mode); fixup_above(img.u, img.u_off, 8, img.uv_stride, col, mbi[mbi_off].mbmi.uv_mode); fixup_above(img.v, img.v_off, 8, img.uv_stride, col, mbi[mbi_off].mbmi.uv_mode); } //swap these two decode_macroblock(ctx, partition, row, col, img, mbi_cache, coeffs, coeffs_off); mbi_off++; img.y_off += 16; img.u_off += 8; img.v_off += 8; coeffs_off += 400; } //decode frame line 605 if (ctx.common.level && row) { if (ctx.common.filter_type) vp8_loop_filter_row_simple(ctx, row - 1); else vp8_loop_filter_row_normal(ctx, row - 1, 0, ctx.mb_cols); } if (col === ctx.mb_cols) { var extend = img.y; var extend_off = (img.y_off + 15 * img.stride);//(uint32_t *) var val = img.y[img.y_off - 1 + 15 * img.stride];//0x01010101 * extend[extend_off] = extend[extend_off + 1] = extend[extend_off + 2] = extend[extend_off + 3] = val; } if (++partition === ctx.token_hdr.partitions) partition = 0; } if (ctx.common.level) { if (ctx.common.filter_type) vp8_loop_filter_row_simple(ctx, row - 1); else vp8_loop_filter_row_normal(ctx, row - 1, 0, ctx.mb_cols); } } function fixup_left(predict, predict_off, width, stride, row, mode) { //The left column of out-of-frame pixels is taken to be 129, // unless we're doing DC_PRED, in which case we duplicate the // above row, unless this is also row 0, in which case we use // 129. // var left = predict; var left_off = (predict_off - 1); var i = 0; if (mode === DC_PRED && row) { var above = predict; var above_off = predict_off - stride;//* for (i = 0; i < width; i++) { left[left_off] = above[above_off + i];//* left_off += stride; } } else { left_off -= stride; for (i = -1; i < width; i++) { left[left_off] = 129;//* left_off += stride; } // } } } function fixup_above(predict, predict_off, width, stride, col, mode) { // The above row of out-of-frame pixels is taken to be 127, // unless we're doing DC_PRED, in which case we duplicate the // left col, unless this is also col 0, in which case we use // 127. // var above = predict; var above_off = predict_off - stride;//* var i = 0; //maybe yv12_extend_frame_top_c if (mode === DC_PRED && col) { var left = predict; var left_off = predict_off - 1;//* for (i = 0; i < width; i++) { above[above_off + i] = left[left_off];//* left_off += stride; } } else /* Need to re-set the left col, in case the last MB was * DC_PRED. */ memset(above, above_off - 1, 127, width + 1); memset_32(above, above_off + width, 127, 4); // for above-right subblock modes } function memset_32(ptr, ptr_off, value, num) { var i = num;//>> 2; var ptr_off_32 = ptr_off >> 2; var ptr_32 = ptr.data_32; var value_32 = value | value << 8 | value << 16 | value << 24; var num_32 = num >> 2; for (var i = 0; i < num_32; i++) { ptr_32[ptr_off_32 + (i >> 2)] = value_32; } } var coeff_clear = new Uint8Array(400); function decode_macroblock(ctx, partition, row, start_col, img, xd, coeffs, coeffs_off) { var tokens = ctx.tokens[partition]; var coeffs = tokens.coeffs; var coeffs_off = 0; var col = 0; var above = ctx.above_token_entropy_ctx; var above_off = +start_col; var left = tokens.left_token_entropy_ctx; var left_off = 0; var mbi = ctx.mb_info_rows; var mbi_off = ctx.mb_info_rows_off[1 + row] + start_col; if (start_col === 0) reset_row_context(left); var mbi_cache = mbi[mbi_off]; var mbmi_cache = mbi_cache.mbmi; //wtf why!?!?!?! /* if (coeffs === null) { //throw "coeff data missing"; console.warn("Missing partition " + partition + " : " + ctx.token_hdr.partitions); coeffs = new Uint32Array(ctx.mb_cols * 400); //coeffs.data_64 = new Float64Array(coeffs.buffer); } else { var copy_dest = coeffs.data_64; copy_dest.set(coeff_clear); } */ var copy_dest = coeffs.data_64; // copy_dest.set(coeff_clear); //coeffs.set(coeff_clear); //var copy_dest = coeffs.data_64; //copy_dest.set(coeff_clear); //memset(coeffs, coeffs_off, 0, 400); for (var c = 0; c < 200; c++) { copy_dest[c] = 0; } if (mbmi_cache.mb_skip_coeff === 1) { //vp8_reset_mb_tokens_context vp8_reset_mb_tokens_context(left, above[above_off], mbmi_cache.y_mode); mbmi_cache.eob_mask = 0; } else { var dqf; var dqf_off = 0; dqf = ctx.dequant_factors; dqf_off = +mbmi_cache.segment_id; //vp8_decode_mb_tokens mbmi_cache.eob_mask = decode_mb_tokens(tokens.bool, left, above[above_off], coeffs, coeffs_off, mbmi_cache.y_mode, ctx.common.entropy_hdr.coeff_probs, dqf[dqf_off].factor); } if (mbmi_cache.y_mode <= B_PRED) { predict_intra_chroma(img.u, img.u_off, img.v, img.v_off, img.uv_stride, mbi_cache, coeffs, coeffs_off); predict_intra_luma(img.y, img.y_off, img.stride, mbi_cache, coeffs, coeffs_off); } else { vp8_build_inter_predictors_mb(ctx, img, coeffs, coeffs_off, mbi_cache, start_col, row); } } var left_reset = new Int32Array(9); function reset_row_context(left) { //console.warn(left.length); left.set(left_reset); //var i = left.length; //while (i--) // left[i] = 0; } function setup_token_decoder(hdr, data, ptr, sz) { var partition_change = 0; var i = 0; var decoder = hdr.decoder; var bool = decoder.boolDecoder; var partitions = 1 << bool.get_uint(2); //console.warn("New partitions : " + partitions); if(hdr.partitions !== partitions) partition_change = 1; hdr.partitions = partitions; //var partitions = hdr.partitions;//cache if (sz < 3 * (partitions - 1)) throw "Truncated packet found parsing partition lenghts"; sz -= 3 * (partitions - 1); for (i = 0; i < partitions; i++) { if (i < partitions - 1) { hdr.partition_sz[i] = (data[ptr + 2] << 16) | (data[ptr + 1] << 8) | data[ptr]; ptr += 3; } else hdr.partition_sz[i] = sz; if (sz < hdr.partition_sz[i]) throw "Truncated partition"; sz -= hdr.partition_sz[i]; } for (i = 0; i < partitions; i++) { vp8dx_start_decode(decoder.tokens[i].bool, data, ptr, hdr.partition_sz[i]); ptr += hdr.partition_sz[i]; } return partition_change; } function vp8_dixie_release_ref_frame(rcimg) { if (rcimg) { if (rcimg.ref_cnt === 0) throw "ERROR :("; rcimg.ref_cnt--; } } function vpx_img_free(img) { if (img) { if (img.img_data && img.img_data_owner) img.img_data = null; if (img.self_allocd) img = null; } } function vp8_dixie_find_free_ref_frame(frames) { var i = 0; for (i = 0; i < NUM_REF_FRAMES; i++) if (frames[i].ref_cnt === 0) { frames[i].ref_cnt = 1; return frames[i]; } return null; } function init_frame(pbi) { var pc = pbi.common; var xd = pbi.segment_hdr; var to = pc.entropy_hdr.mv_probs; if (pc.is_keyframe === true) { //for (var i = 0; i < MV_PROB_CNT; i++) // to[0][i] = vp8_default_mv_context[0][i]; to[0].set(vp8_default_mv_context[0]); to[1].set(vp8_default_mv_context[1]); //for (var i = 0; i < MV_PROB_CNT; i++) // to[1][i] = vp8_default_mv_context[1][i]; vp8_init_mbmode_probs(pc); vp8_default_coef_probs(pc); } else { } } function vp8_decode_frame(data, decoder) { var bc = decoder.boolDecoder; var pc = decoder.common; var xd = decoder.segment_hdr; var sz = data.byteLength; var first_partition_length_in_bytes = 0; var res; decoder.common.saved_entropy_valid = 0; var clear0 = data[0]; pc.is_keyframe = !(clear0 & 0x01); pc.version = (clear0 >> 1) & 7; pc.show_frame = (clear0 >> 4) & 1; first_partition_length_in_bytes = (clear0 | (data[1] << 8) | (data[2] << 16)) >> 5; if (sz <= first_partition_length_in_bytes + (pc.is_keyframe ? 10 : 3)) return -1;//VPX_CODEC_CORRUPT_FRAME; pc.frame_size_updated = 0; if (pc.is_keyframe === true) { var w = pc.Width; var h = pc.Height; var scale_h = pc.vert_scale; var scale_w = pc.horiz_scale; if (data[3] !== 0x9d || data[4] !== 0x01 || data[5] !== 0x2a) return -1;//VPX_CODEC_UNSUP_BITSTREAM; var data7 = data[7]; pc.Width = ((data[6] | (data7 << 8)) & 0x3fff); pc.horiz_scale = data7 >> 6; pc.Height = ((data[8] | (data[9] << 8)) & 0x3fff); pc.vert_scale = data[9] >> 6; if (w !== pc.Width || h !== pc.Height || scale_h !== pc.vert_scale || scale_w !== pc.horiz_scale) { pc.frame_size_updated = 1; } } //now calculate how many macroblock rows and columns data.ptr += FRAME_HEADER_SZ; sz -= FRAME_HEADER_SZ; if (pc.is_keyframe === true) { data.ptr += KEYFRAME_HEADER_SZ; sz -= KEYFRAME_HEADER_SZ; decoder.mb_cols = ((pc.Width + 15) >> 4) | 0; decoder.mb_rows = ((pc.Height + 15) >> 4) | 0; } // bc.init(data, data.ptr, decoder.common.part0_sz); vp8dx_start_decode(bc, data, data.ptr, first_partition_length_in_bytes); if (pc.is_keyframe) { bc.get_uint(2);//skip bits for now } //START Decode segment hdr init_frame(decoder); xd.enabled = vpx_read_bit(bc); if (xd.enabled === 1) { var i = 0; xd.update_map = vpx_read_bit(bc); xd.update_data = vpx_read_bit(bc); if (xd.update_data === 1) { xd.abs = vpx_read_bit(bc); for (i = 0; i < MAX_MB_SEGMENTS; i++) xd.quant_idx[i] = bc.maybe_get_int(7); for (i = 0; i < MAX_MB_SEGMENTS; i++) xd.lf_level[i] = bc.maybe_get_int(6); } if (xd.update_map === 1) { for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) { if (vpx_read_bit(bc) === 1) { xd.tree_probs[i] = bc.get_uint(8); } else { xd.tree_probs[i] = 255; } } } } else { xd.update_map = 0; xd.update_data = 0; } //end decode segment header //pc.decode(decoder.boolDecoder); if (pc.is_keyframe === true) { pc.filter_type = 0; pc.level = 0; pc.sharpness = 0; pc.delta_enabled = 0; pc.ref_delta[0] = 0; pc.ref_delta[1] = 0; pc.ref_delta[2] = 0; pc.ref_delta[3] = 0; pc.mode_delta[0] = 0; pc.mode_delta[1] = 0; pc.mode_delta[2] = 0; pc.mode_delta[3] = 0; } pc.filter_type = vpx_read_bit(bc); pc.level = bc.get_uint(6); pc.sharpness = bc.get_uint(3); pc.delta_enabled = vpx_read_bit(bc); var ref_delta = pc.ref_delta; if (pc.delta_enabled === 1 && vpx_read_bit(bc) === 1) { ref_delta[0] = bc.maybe_get_int(6); ref_delta[1] = bc.maybe_get_int(6); ref_delta[2] = bc.maybe_get_int(6); ref_delta[3] = bc.maybe_get_int(6); pc.mode_delta[0] = bc.maybe_get_int(6); pc.mode_delta[1] = bc.maybe_get_int(6); pc.mode_delta[2] = bc.maybe_get_int(6); pc.mode_delta[3] = bc.maybe_get_int(6); } var partition_change = setup_token_decoder(decoder.token_hdr, data, data.ptr + first_partition_length_in_bytes, sz - first_partition_length_in_bytes); var q_update = 0; var last_q = pc.mbmi_qindex; pc.mbmi_qindex = bc.get_uint(7); q_update = (last_q !== pc.mbmi_qindex) + 0; q_update |= (pc.y1dc_delta_q = bc.maybe_get_int(4)); q_update |= (pc.y2dc_delta_q = bc.maybe_get_int(4)); q_update |= (pc.y2ac_delta_q = bc.maybe_get_int(4)); q_update |= (pc.uvdc_delta_q = bc.maybe_get_int(4)); q_update |= (pc.uvac_delta_q = bc.maybe_get_int(4)); pc.delta_update = q_update; //Reference Header var key = pc.is_keyframe; if (key === true) { pc.refresh_gf = 1; pc.refresh_arf = 1; pc.copy_gf = 0; pc.copy_arf = 0; pc.sign_bias[GOLDEN_FRAME] = 0; pc.sign_bias[ALTREF_FRAME] = 0; } else { pc.refresh_gf = vpx_read_bit(bc); pc.refresh_arf = vpx_read_bit(bc); pc.copy_gf = !pc.refresh_gf ? bc.get_uint(2) : 0; pc.copy_arf = !pc.refresh_arf ? bc.get_uint(2) : 0; pc.sign_bias[GOLDEN_FRAME] = vpx_read_bit(bc); pc.sign_bias[ALTREF_FRAME] = vpx_read_bit(bc); } pc.refresh_entropy_probs = vpx_read_bit(bc); if (key === true) { pc.refresh_last = 1; } else { pc.refresh_last = vpx_read_bit(bc); } if (pc.refresh_entropy_probs === 0) { copy_entropy_values(pc.saved_entropy, pc.entropy_hdr); decoder.saved_entropy_valid = 1; } decoder.modemv_init(); var ctx = decoder; var partitions = ctx.token_hdr.partitions; //PREDICT INIT var i = 0; var this_frame_mbmi = 0; var this_frame_mbmi_off = 0; var coeff_row_sz = ctx.mb_cols * 400; if (pc.frame_size_updated === 1) { //console.warn("Frame size updated"); var i = 0; for (i = 0; i < partitions; i++) { //ctx.tokens[i].coeffs = new Uint32Array(coeff_row_sz); //ctx.tokens[i].coeffs.data_64 = new Float64Array(ctx.tokens[i].coeffs.buffer); } var mb_cols = ctx.mb_cols; //ENTROPY_CONTEXT_PLANES ctx.above_token_entropy_ctx = new Array(mb_cols); for ( i = 0; i < mb_cols; i++) ctx.above_token_entropy_ctx[i] = new Int32Array(9); var w = ((decoder.mb_cols << 4) + 32) | 0; var h = ((decoder.mb_rows << 4) + 32) | 0; for (i = 0; i < NUM_REF_FRAMES; i++) { vpx_img_free(decoder.frame_strg[i].img); decoder.frame_strg[i].ref_cnt = 0; decoder.ref_frames[i] = null; img_alloc_helper(decoder.frame_strg[i].img, VPX_IMG_FMT_I420, w, h, 16); vpx_img_set_rect(decoder.frame_strg[i].img, BORDER_PIXELS, BORDER_PIXELS, decoder.common.Width, decoder.common.Height); } if (pc.version) decoder.subpixel_filters = vp8_bilinear_filters; else decoder.subpixel_filters = vp8_sub_pel_filters; } if(pc.frame_size_updated === 1 || partition_change === 1){ //console.log("Partition changing : " + partitions); for (i = 0; i < partitions; i++) { ctx.tokens[i].coeffs = new Uint32Array(coeff_row_sz); ctx.tokens[i].coeffs.data_64 = new Float64Array(ctx.tokens[i].coeffs.buffer); } } var ref_frames = decoder.ref_frames; /* Find a free framebuffer to predict into */ if (ref_frames[CURRENT_FRAME]) vp8_dixie_release_ref_frame(ref_frames[CURRENT_FRAME]); ref_frames[CURRENT_FRAME] = vp8_dixie_find_free_ref_frame(decoder.frame_strg); this_frame_mbmi = ref_frames[CURRENT_FRAME].img.img_data; /* Calculate offsets to the other reference frames */ for (i = 0; i < NUM_REF_FRAMES; i++) { var ref = ref_frames[i]; if (ref) { decoder.ref_frame_offsets[i] = ref.img.img_data_off - this_frame_mbmi_off; decoder.ref_frame_offsets_[i] = ref.img.img_data; } else { decoder.ref_frame_offsets[i] = 0; decoder.ref_frame_offsets_[i] = this_frame_mbmi; } } //END PREDICT INIT vp8cx_init_de_quantizer(decoder.dequant_factors, xd, pc); var length = 1; if (xd.enabled === 1) { length = 4; } vp8_decode_mode_mvs(decoder, bc); var above = decoder.above_token_entropy_ctx; var mb_cols = decoder.mb_cols; for (var col = 0; col < mb_cols; ++col) memset(above[col], 0, 0, 9); decode_mb_rows(decoder); decoder.frame_cnt++; //UPDATE REFERENCES TO FRAMES AND STUFF if (decoder.saved_entropy_valid === 1) { //decoder.common.entropy_hdr.copyValues(decoder.common.saved_entropy); copy_entropy_values(pc.entropy_hdr, pc.saved_entropy); decoder.saved_entropy_valid = 0; } decoder.img_avail = decoder.common.show_frame; } module.exports = {}; module.exports.vp8cx_init_de_quantizer = vp8cx_init_de_quantizer; module.exports.decode_mb_rows = decode_mb_rows; module.exports.setup_token_decoder = setup_token_decoder; module.exports.vp8_decode_frame = vp8_decode_frame;