1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/header.h"
12*fb1b10abSAndroid Build Coastguard Worker #include "encodemv.h"
13*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/entropymode.h"
14*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/findnearmv.h"
15*fb1b10abSAndroid Build Coastguard Worker #include "mcomp.h"
16*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/systemdependent.h"
17*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
18*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
19*fb1b10abSAndroid Build Coastguard Worker #include <limits.h>
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_encoder.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/compiler_attributes.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/system_state.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "bitstream.h"
25*fb1b10abSAndroid Build Coastguard Worker
26*fb1b10abSAndroid Build Coastguard Worker #include "defaultcoefcounts.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/common.h"
28*fb1b10abSAndroid Build Coastguard Worker
29*fb1b10abSAndroid Build Coastguard Worker const int vp8cx_base_skip_false_prob[128] = {
30*fb1b10abSAndroid Build Coastguard Worker 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
31*fb1b10abSAndroid Build Coastguard Worker 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
32*fb1b10abSAndroid Build Coastguard Worker 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33*fb1b10abSAndroid Build Coastguard Worker 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251, 248, 244, 240,
34*fb1b10abSAndroid Build Coastguard Worker 236, 232, 229, 225, 221, 217, 213, 208, 204, 199, 194, 190, 187, 183, 179,
35*fb1b10abSAndroid Build Coastguard Worker 175, 172, 168, 164, 160, 157, 153, 149, 145, 142, 138, 134, 130, 127, 124,
36*fb1b10abSAndroid Build Coastguard Worker 120, 117, 114, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, 77,
37*fb1b10abSAndroid Build Coastguard Worker 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 44, 41, 38, 35, 32,
38*fb1b10abSAndroid Build Coastguard Worker 30, 28, 26, 24, 22, 20, 18, 16,
39*fb1b10abSAndroid Build Coastguard Worker };
40*fb1b10abSAndroid Build Coastguard Worker
41*fb1b10abSAndroid Build Coastguard Worker #if defined(SECTIONBITS_OUTPUT)
42*fb1b10abSAndroid Build Coastguard Worker unsigned __int64 Sectionbits[500];
43*fb1b10abSAndroid Build Coastguard Worker #endif
44*fb1b10abSAndroid Build Coastguard Worker
45*fb1b10abSAndroid Build Coastguard Worker #ifdef MODE_STATS
46*fb1b10abSAndroid Build Coastguard Worker int count_mb_seg[4] = { 0, 0, 0, 0 };
47*fb1b10abSAndroid Build Coastguard Worker #endif
48*fb1b10abSAndroid Build Coastguard Worker
update_mode(vp8_writer * const w,int n,vp8_token tok[],vp8_tree tree,vp8_prob Pnew[],vp8_prob Pcur[],unsigned int bct[][2],const unsigned int num_events[])49*fb1b10abSAndroid Build Coastguard Worker static void update_mode(vp8_writer *const w, int n, vp8_token tok[/* n */],
50*fb1b10abSAndroid Build Coastguard Worker vp8_tree tree, vp8_prob Pnew[/* n-1 */],
51*fb1b10abSAndroid Build Coastguard Worker vp8_prob Pcur[/* n-1 */],
52*fb1b10abSAndroid Build Coastguard Worker unsigned int bct[/* n-1 */][2],
53*fb1b10abSAndroid Build Coastguard Worker const unsigned int num_events[/* n */]) {
54*fb1b10abSAndroid Build Coastguard Worker unsigned int new_b = 0, old_b = 0;
55*fb1b10abSAndroid Build Coastguard Worker int i = 0;
56*fb1b10abSAndroid Build Coastguard Worker
57*fb1b10abSAndroid Build Coastguard Worker vp8_tree_probs_from_distribution(n--, tok, tree, Pnew, bct, num_events, 256,
58*fb1b10abSAndroid Build Coastguard Worker 1);
59*fb1b10abSAndroid Build Coastguard Worker
60*fb1b10abSAndroid Build Coastguard Worker do {
61*fb1b10abSAndroid Build Coastguard Worker new_b += vp8_cost_branch(bct[i], Pnew[i]);
62*fb1b10abSAndroid Build Coastguard Worker old_b += vp8_cost_branch(bct[i], Pcur[i]);
63*fb1b10abSAndroid Build Coastguard Worker } while (++i < n);
64*fb1b10abSAndroid Build Coastguard Worker
65*fb1b10abSAndroid Build Coastguard Worker if (new_b + (n << 8) < old_b) {
66*fb1b10abSAndroid Build Coastguard Worker int j = 0;
67*fb1b10abSAndroid Build Coastguard Worker
68*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(w, 1);
69*fb1b10abSAndroid Build Coastguard Worker
70*fb1b10abSAndroid Build Coastguard Worker do {
71*fb1b10abSAndroid Build Coastguard Worker const vp8_prob p = Pnew[j];
72*fb1b10abSAndroid Build Coastguard Worker
73*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, Pcur[j] = p ? p : 1, 8);
74*fb1b10abSAndroid Build Coastguard Worker } while (++j < n);
75*fb1b10abSAndroid Build Coastguard Worker } else
76*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(w, 0);
77*fb1b10abSAndroid Build Coastguard Worker }
78*fb1b10abSAndroid Build Coastguard Worker
update_mbintra_mode_probs(VP8_COMP * cpi)79*fb1b10abSAndroid Build Coastguard Worker static void update_mbintra_mode_probs(VP8_COMP *cpi) {
80*fb1b10abSAndroid Build Coastguard Worker VP8_COMMON *const x = &cpi->common;
81*fb1b10abSAndroid Build Coastguard Worker
82*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const w = cpi->bc;
83*fb1b10abSAndroid Build Coastguard Worker
84*fb1b10abSAndroid Build Coastguard Worker {
85*fb1b10abSAndroid Build Coastguard Worker vp8_prob Pnew[VP8_YMODES - 1];
86*fb1b10abSAndroid Build Coastguard Worker unsigned int bct[VP8_YMODES - 1][2];
87*fb1b10abSAndroid Build Coastguard Worker
88*fb1b10abSAndroid Build Coastguard Worker update_mode(w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree, Pnew,
89*fb1b10abSAndroid Build Coastguard Worker x->fc.ymode_prob, bct, (unsigned int *)cpi->mb.ymode_count);
90*fb1b10abSAndroid Build Coastguard Worker }
91*fb1b10abSAndroid Build Coastguard Worker {
92*fb1b10abSAndroid Build Coastguard Worker vp8_prob Pnew[VP8_UV_MODES - 1];
93*fb1b10abSAndroid Build Coastguard Worker unsigned int bct[VP8_UV_MODES - 1][2];
94*fb1b10abSAndroid Build Coastguard Worker
95*fb1b10abSAndroid Build Coastguard Worker update_mode(w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree, Pnew,
96*fb1b10abSAndroid Build Coastguard Worker x->fc.uv_mode_prob, bct, (unsigned int *)cpi->mb.uv_mode_count);
97*fb1b10abSAndroid Build Coastguard Worker }
98*fb1b10abSAndroid Build Coastguard Worker }
99*fb1b10abSAndroid Build Coastguard Worker
write_ymode(vp8_writer * bc,int m,const vp8_prob * p)100*fb1b10abSAndroid Build Coastguard Worker static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
101*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
102*fb1b10abSAndroid Build Coastguard Worker }
103*fb1b10abSAndroid Build Coastguard Worker
kfwrite_ymode(vp8_writer * bc,int m,const vp8_prob * p)104*fb1b10abSAndroid Build Coastguard Worker static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p) {
105*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
106*fb1b10abSAndroid Build Coastguard Worker }
107*fb1b10abSAndroid Build Coastguard Worker
write_uv_mode(vp8_writer * bc,int m,const vp8_prob * p)108*fb1b10abSAndroid Build Coastguard Worker static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p) {
109*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
110*fb1b10abSAndroid Build Coastguard Worker }
111*fb1b10abSAndroid Build Coastguard Worker
write_bmode(vp8_writer * bc,int m,const vp8_prob * p)112*fb1b10abSAndroid Build Coastguard Worker static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p) {
113*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);
114*fb1b10abSAndroid Build Coastguard Worker }
115*fb1b10abSAndroid Build Coastguard Worker
write_split(vp8_writer * bc,int x)116*fb1b10abSAndroid Build Coastguard Worker static void write_split(vp8_writer *bc, int x) {
117*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(bc, vp8_mbsplit_tree, vp8_mbsplit_probs,
118*fb1b10abSAndroid Build Coastguard Worker vp8_mbsplit_encodings + x);
119*fb1b10abSAndroid Build Coastguard Worker }
120*fb1b10abSAndroid Build Coastguard Worker
vp8_pack_tokens(vp8_writer * w,const TOKENEXTRA * p,int xcount)121*fb1b10abSAndroid Build Coastguard Worker void VPX_NO_UNSIGNED_SHIFT_CHECK vp8_pack_tokens(vp8_writer *w,
122*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *p,
123*fb1b10abSAndroid Build Coastguard Worker int xcount) {
124*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *stop = p + xcount;
125*fb1b10abSAndroid Build Coastguard Worker unsigned int split;
126*fb1b10abSAndroid Build Coastguard Worker int shift;
127*fb1b10abSAndroid Build Coastguard Worker int count = w->count;
128*fb1b10abSAndroid Build Coastguard Worker unsigned int range = w->range;
129*fb1b10abSAndroid Build Coastguard Worker unsigned int lowvalue = w->lowvalue;
130*fb1b10abSAndroid Build Coastguard Worker
131*fb1b10abSAndroid Build Coastguard Worker while (p < stop) {
132*fb1b10abSAndroid Build Coastguard Worker const int t = p->Token;
133*fb1b10abSAndroid Build Coastguard Worker vp8_token *a = vp8_coef_encodings + t;
134*fb1b10abSAndroid Build Coastguard Worker const vp8_extra_bit_struct *b = vp8_extra_bits + t;
135*fb1b10abSAndroid Build Coastguard Worker int i = 0;
136*fb1b10abSAndroid Build Coastguard Worker const unsigned char *pp = p->context_tree;
137*fb1b10abSAndroid Build Coastguard Worker int v = a->value;
138*fb1b10abSAndroid Build Coastguard Worker int n = a->Len;
139*fb1b10abSAndroid Build Coastguard Worker
140*fb1b10abSAndroid Build Coastguard Worker if (p->skip_eob_node) {
141*fb1b10abSAndroid Build Coastguard Worker n--;
142*fb1b10abSAndroid Build Coastguard Worker i = 2;
143*fb1b10abSAndroid Build Coastguard Worker }
144*fb1b10abSAndroid Build Coastguard Worker
145*fb1b10abSAndroid Build Coastguard Worker do {
146*fb1b10abSAndroid Build Coastguard Worker const int bb = (v >> --n) & 1;
147*fb1b10abSAndroid Build Coastguard Worker split = 1 + (((range - 1) * pp[i >> 1]) >> 8);
148*fb1b10abSAndroid Build Coastguard Worker i = vp8_coef_tree[i + bb];
149*fb1b10abSAndroid Build Coastguard Worker
150*fb1b10abSAndroid Build Coastguard Worker if (bb) {
151*fb1b10abSAndroid Build Coastguard Worker lowvalue += split;
152*fb1b10abSAndroid Build Coastguard Worker range = range - split;
153*fb1b10abSAndroid Build Coastguard Worker } else {
154*fb1b10abSAndroid Build Coastguard Worker range = split;
155*fb1b10abSAndroid Build Coastguard Worker }
156*fb1b10abSAndroid Build Coastguard Worker
157*fb1b10abSAndroid Build Coastguard Worker shift = vp8_norm[range];
158*fb1b10abSAndroid Build Coastguard Worker range <<= shift;
159*fb1b10abSAndroid Build Coastguard Worker count += shift;
160*fb1b10abSAndroid Build Coastguard Worker
161*fb1b10abSAndroid Build Coastguard Worker if (count >= 0) {
162*fb1b10abSAndroid Build Coastguard Worker int offset = shift - count;
163*fb1b10abSAndroid Build Coastguard Worker
164*fb1b10abSAndroid Build Coastguard Worker if ((lowvalue << (offset - 1)) & 0x80000000) {
165*fb1b10abSAndroid Build Coastguard Worker int x = w->pos - 1;
166*fb1b10abSAndroid Build Coastguard Worker
167*fb1b10abSAndroid Build Coastguard Worker while (x >= 0 && w->buffer[x] == 0xff) {
168*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] = (unsigned char)0;
169*fb1b10abSAndroid Build Coastguard Worker x--;
170*fb1b10abSAndroid Build Coastguard Worker }
171*fb1b10abSAndroid Build Coastguard Worker
172*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] += 1;
173*fb1b10abSAndroid Build Coastguard Worker }
174*fb1b10abSAndroid Build Coastguard Worker
175*fb1b10abSAndroid Build Coastguard Worker validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
176*fb1b10abSAndroid Build Coastguard Worker
177*fb1b10abSAndroid Build Coastguard Worker w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff;
178*fb1b10abSAndroid Build Coastguard Worker shift = count;
179*fb1b10abSAndroid Build Coastguard Worker lowvalue = (int)(((uint64_t)lowvalue << offset) & 0xffffff);
180*fb1b10abSAndroid Build Coastguard Worker count -= 8;
181*fb1b10abSAndroid Build Coastguard Worker }
182*fb1b10abSAndroid Build Coastguard Worker
183*fb1b10abSAndroid Build Coastguard Worker lowvalue <<= shift;
184*fb1b10abSAndroid Build Coastguard Worker } while (n);
185*fb1b10abSAndroid Build Coastguard Worker
186*fb1b10abSAndroid Build Coastguard Worker if (b->base_val) {
187*fb1b10abSAndroid Build Coastguard Worker const int e = p->Extra, L = b->Len;
188*fb1b10abSAndroid Build Coastguard Worker
189*fb1b10abSAndroid Build Coastguard Worker if (L) {
190*fb1b10abSAndroid Build Coastguard Worker const unsigned char *proba = b->prob;
191*fb1b10abSAndroid Build Coastguard Worker const int v2 = e >> 1;
192*fb1b10abSAndroid Build Coastguard Worker int n2 = L; /* number of bits in v2, assumed nonzero */
193*fb1b10abSAndroid Build Coastguard Worker i = 0;
194*fb1b10abSAndroid Build Coastguard Worker
195*fb1b10abSAndroid Build Coastguard Worker do {
196*fb1b10abSAndroid Build Coastguard Worker const int bb = (v2 >> --n2) & 1;
197*fb1b10abSAndroid Build Coastguard Worker split = 1 + (((range - 1) * proba[i >> 1]) >> 8);
198*fb1b10abSAndroid Build Coastguard Worker i = b->tree[i + bb];
199*fb1b10abSAndroid Build Coastguard Worker
200*fb1b10abSAndroid Build Coastguard Worker if (bb) {
201*fb1b10abSAndroid Build Coastguard Worker lowvalue += split;
202*fb1b10abSAndroid Build Coastguard Worker range = range - split;
203*fb1b10abSAndroid Build Coastguard Worker } else {
204*fb1b10abSAndroid Build Coastguard Worker range = split;
205*fb1b10abSAndroid Build Coastguard Worker }
206*fb1b10abSAndroid Build Coastguard Worker
207*fb1b10abSAndroid Build Coastguard Worker shift = vp8_norm[range];
208*fb1b10abSAndroid Build Coastguard Worker range <<= shift;
209*fb1b10abSAndroid Build Coastguard Worker count += shift;
210*fb1b10abSAndroid Build Coastguard Worker
211*fb1b10abSAndroid Build Coastguard Worker if (count >= 0) {
212*fb1b10abSAndroid Build Coastguard Worker int offset = shift - count;
213*fb1b10abSAndroid Build Coastguard Worker
214*fb1b10abSAndroid Build Coastguard Worker if ((lowvalue << (offset - 1)) & 0x80000000) {
215*fb1b10abSAndroid Build Coastguard Worker int x = w->pos - 1;
216*fb1b10abSAndroid Build Coastguard Worker
217*fb1b10abSAndroid Build Coastguard Worker while (x >= 0 && w->buffer[x] == 0xff) {
218*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] = (unsigned char)0;
219*fb1b10abSAndroid Build Coastguard Worker x--;
220*fb1b10abSAndroid Build Coastguard Worker }
221*fb1b10abSAndroid Build Coastguard Worker
222*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] += 1;
223*fb1b10abSAndroid Build Coastguard Worker }
224*fb1b10abSAndroid Build Coastguard Worker
225*fb1b10abSAndroid Build Coastguard Worker validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
226*fb1b10abSAndroid Build Coastguard Worker
227*fb1b10abSAndroid Build Coastguard Worker w->buffer[w->pos++] = (lowvalue >> (24 - offset)) & 0xff;
228*fb1b10abSAndroid Build Coastguard Worker shift = count;
229*fb1b10abSAndroid Build Coastguard Worker lowvalue = (int)(((uint64_t)lowvalue << offset) & 0xffffff);
230*fb1b10abSAndroid Build Coastguard Worker count -= 8;
231*fb1b10abSAndroid Build Coastguard Worker }
232*fb1b10abSAndroid Build Coastguard Worker
233*fb1b10abSAndroid Build Coastguard Worker lowvalue <<= shift;
234*fb1b10abSAndroid Build Coastguard Worker } while (n2);
235*fb1b10abSAndroid Build Coastguard Worker }
236*fb1b10abSAndroid Build Coastguard Worker
237*fb1b10abSAndroid Build Coastguard Worker {
238*fb1b10abSAndroid Build Coastguard Worker split = (range + 1) >> 1;
239*fb1b10abSAndroid Build Coastguard Worker
240*fb1b10abSAndroid Build Coastguard Worker if (e & 1) {
241*fb1b10abSAndroid Build Coastguard Worker lowvalue += split;
242*fb1b10abSAndroid Build Coastguard Worker range = range - split;
243*fb1b10abSAndroid Build Coastguard Worker } else {
244*fb1b10abSAndroid Build Coastguard Worker range = split;
245*fb1b10abSAndroid Build Coastguard Worker }
246*fb1b10abSAndroid Build Coastguard Worker
247*fb1b10abSAndroid Build Coastguard Worker range <<= 1;
248*fb1b10abSAndroid Build Coastguard Worker
249*fb1b10abSAndroid Build Coastguard Worker if ((lowvalue & 0x80000000)) {
250*fb1b10abSAndroid Build Coastguard Worker int x = w->pos - 1;
251*fb1b10abSAndroid Build Coastguard Worker
252*fb1b10abSAndroid Build Coastguard Worker while (x >= 0 && w->buffer[x] == 0xff) {
253*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] = (unsigned char)0;
254*fb1b10abSAndroid Build Coastguard Worker x--;
255*fb1b10abSAndroid Build Coastguard Worker }
256*fb1b10abSAndroid Build Coastguard Worker
257*fb1b10abSAndroid Build Coastguard Worker w->buffer[x] += 1;
258*fb1b10abSAndroid Build Coastguard Worker }
259*fb1b10abSAndroid Build Coastguard Worker
260*fb1b10abSAndroid Build Coastguard Worker lowvalue <<= 1;
261*fb1b10abSAndroid Build Coastguard Worker
262*fb1b10abSAndroid Build Coastguard Worker if (!++count) {
263*fb1b10abSAndroid Build Coastguard Worker count = -8;
264*fb1b10abSAndroid Build Coastguard Worker
265*fb1b10abSAndroid Build Coastguard Worker validate_buffer(w->buffer + w->pos, 1, w->buffer_end, w->error);
266*fb1b10abSAndroid Build Coastguard Worker
267*fb1b10abSAndroid Build Coastguard Worker w->buffer[w->pos++] = (lowvalue >> 24);
268*fb1b10abSAndroid Build Coastguard Worker lowvalue &= 0xffffff;
269*fb1b10abSAndroid Build Coastguard Worker }
270*fb1b10abSAndroid Build Coastguard Worker }
271*fb1b10abSAndroid Build Coastguard Worker }
272*fb1b10abSAndroid Build Coastguard Worker
273*fb1b10abSAndroid Build Coastguard Worker ++p;
274*fb1b10abSAndroid Build Coastguard Worker }
275*fb1b10abSAndroid Build Coastguard Worker
276*fb1b10abSAndroid Build Coastguard Worker w->count = count;
277*fb1b10abSAndroid Build Coastguard Worker w->lowvalue = lowvalue;
278*fb1b10abSAndroid Build Coastguard Worker w->range = range;
279*fb1b10abSAndroid Build Coastguard Worker }
280*fb1b10abSAndroid Build Coastguard Worker
write_partition_size(unsigned char * cx_data,int size)281*fb1b10abSAndroid Build Coastguard Worker static void write_partition_size(unsigned char *cx_data, int size) {
282*fb1b10abSAndroid Build Coastguard Worker signed char csize;
283*fb1b10abSAndroid Build Coastguard Worker
284*fb1b10abSAndroid Build Coastguard Worker csize = size & 0xff;
285*fb1b10abSAndroid Build Coastguard Worker *cx_data = csize;
286*fb1b10abSAndroid Build Coastguard Worker csize = (size >> 8) & 0xff;
287*fb1b10abSAndroid Build Coastguard Worker *(cx_data + 1) = csize;
288*fb1b10abSAndroid Build Coastguard Worker csize = (size >> 16) & 0xff;
289*fb1b10abSAndroid Build Coastguard Worker *(cx_data + 2) = csize;
290*fb1b10abSAndroid Build Coastguard Worker }
291*fb1b10abSAndroid Build Coastguard Worker
pack_tokens_into_partitions(VP8_COMP * cpi,unsigned char * cx_data,unsigned char * cx_data_end,int num_part)292*fb1b10abSAndroid Build Coastguard Worker static void pack_tokens_into_partitions(VP8_COMP *cpi, unsigned char *cx_data,
293*fb1b10abSAndroid Build Coastguard Worker unsigned char *cx_data_end,
294*fb1b10abSAndroid Build Coastguard Worker int num_part) {
295*fb1b10abSAndroid Build Coastguard Worker int i;
296*fb1b10abSAndroid Build Coastguard Worker unsigned char *ptr = cx_data;
297*fb1b10abSAndroid Build Coastguard Worker unsigned char *ptr_end = cx_data_end;
298*fb1b10abSAndroid Build Coastguard Worker vp8_writer *w;
299*fb1b10abSAndroid Build Coastguard Worker
300*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_part; ++i) {
301*fb1b10abSAndroid Build Coastguard Worker int mb_row;
302*fb1b10abSAndroid Build Coastguard Worker
303*fb1b10abSAndroid Build Coastguard Worker w = cpi->bc + i + 1;
304*fb1b10abSAndroid Build Coastguard Worker
305*fb1b10abSAndroid Build Coastguard Worker vp8_start_encode(w, ptr, ptr_end);
306*fb1b10abSAndroid Build Coastguard Worker
307*fb1b10abSAndroid Build Coastguard Worker for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part) {
308*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *p = cpi->tplist[mb_row].start;
309*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
310*fb1b10abSAndroid Build Coastguard Worker int tokens = (int)(stop - p);
311*fb1b10abSAndroid Build Coastguard Worker
312*fb1b10abSAndroid Build Coastguard Worker vp8_pack_tokens(w, p, tokens);
313*fb1b10abSAndroid Build Coastguard Worker }
314*fb1b10abSAndroid Build Coastguard Worker
315*fb1b10abSAndroid Build Coastguard Worker vp8_stop_encode(w);
316*fb1b10abSAndroid Build Coastguard Worker ptr += w->pos;
317*fb1b10abSAndroid Build Coastguard Worker }
318*fb1b10abSAndroid Build Coastguard Worker }
319*fb1b10abSAndroid Build Coastguard Worker
320*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
pack_mb_row_tokens(VP8_COMP * cpi,vp8_writer * w)321*fb1b10abSAndroid Build Coastguard Worker static void pack_mb_row_tokens(VP8_COMP *cpi, vp8_writer *w) {
322*fb1b10abSAndroid Build Coastguard Worker int mb_row;
323*fb1b10abSAndroid Build Coastguard Worker
324*fb1b10abSAndroid Build Coastguard Worker for (mb_row = 0; mb_row < cpi->common.mb_rows; ++mb_row) {
325*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *p = cpi->tplist[mb_row].start;
326*fb1b10abSAndroid Build Coastguard Worker const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
327*fb1b10abSAndroid Build Coastguard Worker int tokens = (int)(stop - p);
328*fb1b10abSAndroid Build Coastguard Worker
329*fb1b10abSAndroid Build Coastguard Worker vp8_pack_tokens(w, p, tokens);
330*fb1b10abSAndroid Build Coastguard Worker }
331*fb1b10abSAndroid Build Coastguard Worker }
332*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_MULTITHREAD
333*fb1b10abSAndroid Build Coastguard Worker
write_mv_ref(vp8_writer * w,MB_PREDICTION_MODE m,const vp8_prob * p)334*fb1b10abSAndroid Build Coastguard Worker static void write_mv_ref(vp8_writer *w, MB_PREDICTION_MODE m,
335*fb1b10abSAndroid Build Coastguard Worker const vp8_prob *p) {
336*fb1b10abSAndroid Build Coastguard Worker assert(NEARESTMV <= m && m <= SPLITMV);
337*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(w, vp8_mv_ref_tree, p,
338*fb1b10abSAndroid Build Coastguard Worker vp8_mv_ref_encoding_array + (m - NEARESTMV));
339*fb1b10abSAndroid Build Coastguard Worker }
340*fb1b10abSAndroid Build Coastguard Worker
write_sub_mv_ref(vp8_writer * w,B_PREDICTION_MODE m,const vp8_prob * p)341*fb1b10abSAndroid Build Coastguard Worker static void write_sub_mv_ref(vp8_writer *w, B_PREDICTION_MODE m,
342*fb1b10abSAndroid Build Coastguard Worker const vp8_prob *p) {
343*fb1b10abSAndroid Build Coastguard Worker assert(LEFT4X4 <= m && m <= NEW4X4);
344*fb1b10abSAndroid Build Coastguard Worker vp8_write_token(w, vp8_sub_mv_ref_tree, p,
345*fb1b10abSAndroid Build Coastguard Worker vp8_sub_mv_ref_encoding_array + (m - LEFT4X4));
346*fb1b10abSAndroid Build Coastguard Worker }
347*fb1b10abSAndroid Build Coastguard Worker
write_mv(vp8_writer * w,const MV * mv,const int_mv * ref,const MV_CONTEXT * mvc)348*fb1b10abSAndroid Build Coastguard Worker static void write_mv(vp8_writer *w, const MV *mv, const int_mv *ref,
349*fb1b10abSAndroid Build Coastguard Worker const MV_CONTEXT *mvc) {
350*fb1b10abSAndroid Build Coastguard Worker MV e;
351*fb1b10abSAndroid Build Coastguard Worker e.row = mv->row - ref->as_mv.row;
352*fb1b10abSAndroid Build Coastguard Worker e.col = mv->col - ref->as_mv.col;
353*fb1b10abSAndroid Build Coastguard Worker
354*fb1b10abSAndroid Build Coastguard Worker vp8_encode_motion_vector(w, &e, mvc);
355*fb1b10abSAndroid Build Coastguard Worker }
356*fb1b10abSAndroid Build Coastguard Worker
write_mb_features(vp8_writer * w,const MB_MODE_INFO * mi,const MACROBLOCKD * x)357*fb1b10abSAndroid Build Coastguard Worker static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi,
358*fb1b10abSAndroid Build Coastguard Worker const MACROBLOCKD *x) {
359*fb1b10abSAndroid Build Coastguard Worker /* Encode the MB segment id. */
360*fb1b10abSAndroid Build Coastguard Worker if (x->segmentation_enabled && x->update_mb_segmentation_map) {
361*fb1b10abSAndroid Build Coastguard Worker switch (mi->segment_id) {
362*fb1b10abSAndroid Build Coastguard Worker case 0:
363*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[0]);
364*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[1]);
365*fb1b10abSAndroid Build Coastguard Worker break;
366*fb1b10abSAndroid Build Coastguard Worker case 1:
367*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[0]);
368*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, x->mb_segment_tree_probs[1]);
369*fb1b10abSAndroid Build Coastguard Worker break;
370*fb1b10abSAndroid Build Coastguard Worker case 2:
371*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, x->mb_segment_tree_probs[0]);
372*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[2]);
373*fb1b10abSAndroid Build Coastguard Worker break;
374*fb1b10abSAndroid Build Coastguard Worker case 3:
375*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, x->mb_segment_tree_probs[0]);
376*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, x->mb_segment_tree_probs[2]);
377*fb1b10abSAndroid Build Coastguard Worker break;
378*fb1b10abSAndroid Build Coastguard Worker
379*fb1b10abSAndroid Build Coastguard Worker /* TRAP.. This should not happen */
380*fb1b10abSAndroid Build Coastguard Worker default:
381*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[0]);
382*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, x->mb_segment_tree_probs[1]);
383*fb1b10abSAndroid Build Coastguard Worker break;
384*fb1b10abSAndroid Build Coastguard Worker }
385*fb1b10abSAndroid Build Coastguard Worker }
386*fb1b10abSAndroid Build Coastguard Worker }
vp8_convert_rfct_to_prob(VP8_COMP * const cpi)387*fb1b10abSAndroid Build Coastguard Worker void vp8_convert_rfct_to_prob(VP8_COMP *const cpi) {
388*fb1b10abSAndroid Build Coastguard Worker const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
389*fb1b10abSAndroid Build Coastguard Worker const int rf_intra = rfct[INTRA_FRAME];
390*fb1b10abSAndroid Build Coastguard Worker const int rf_inter =
391*fb1b10abSAndroid Build Coastguard Worker rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
392*fb1b10abSAndroid Build Coastguard Worker
393*fb1b10abSAndroid Build Coastguard Worker /* Calculate the probabilities used to code the ref frame based on usage */
394*fb1b10abSAndroid Build Coastguard Worker if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) {
395*fb1b10abSAndroid Build Coastguard Worker cpi->prob_intra_coded = 1;
396*fb1b10abSAndroid Build Coastguard Worker }
397*fb1b10abSAndroid Build Coastguard Worker
398*fb1b10abSAndroid Build Coastguard Worker cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
399*fb1b10abSAndroid Build Coastguard Worker
400*fb1b10abSAndroid Build Coastguard Worker if (!cpi->prob_last_coded) cpi->prob_last_coded = 1;
401*fb1b10abSAndroid Build Coastguard Worker
402*fb1b10abSAndroid Build Coastguard Worker cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
403*fb1b10abSAndroid Build Coastguard Worker ? (rfct[GOLDEN_FRAME] * 255) /
404*fb1b10abSAndroid Build Coastguard Worker (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
405*fb1b10abSAndroid Build Coastguard Worker : 128;
406*fb1b10abSAndroid Build Coastguard Worker
407*fb1b10abSAndroid Build Coastguard Worker if (!cpi->prob_gf_coded) cpi->prob_gf_coded = 1;
408*fb1b10abSAndroid Build Coastguard Worker }
409*fb1b10abSAndroid Build Coastguard Worker
pack_inter_mode_mvs(VP8_COMP * const cpi)410*fb1b10abSAndroid Build Coastguard Worker static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
411*fb1b10abSAndroid Build Coastguard Worker VP8_COMMON *const pc = &cpi->common;
412*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const w = cpi->bc;
413*fb1b10abSAndroid Build Coastguard Worker const MV_CONTEXT *mvc = pc->fc.mvc;
414*fb1b10abSAndroid Build Coastguard Worker
415*fb1b10abSAndroid Build Coastguard Worker MODE_INFO *m = pc->mi;
416*fb1b10abSAndroid Build Coastguard Worker const int mis = pc->mode_info_stride;
417*fb1b10abSAndroid Build Coastguard Worker int mb_row = -1;
418*fb1b10abSAndroid Build Coastguard Worker
419*fb1b10abSAndroid Build Coastguard Worker int prob_skip_false = 0;
420*fb1b10abSAndroid Build Coastguard Worker
421*fb1b10abSAndroid Build Coastguard Worker cpi->mb.partition_info = cpi->mb.pi;
422*fb1b10abSAndroid Build Coastguard Worker
423*fb1b10abSAndroid Build Coastguard Worker vp8_convert_rfct_to_prob(cpi);
424*fb1b10abSAndroid Build Coastguard Worker
425*fb1b10abSAndroid Build Coastguard Worker if (pc->mb_no_coeff_skip) {
426*fb1b10abSAndroid Build Coastguard Worker int total_mbs = pc->mb_rows * pc->mb_cols;
427*fb1b10abSAndroid Build Coastguard Worker
428*fb1b10abSAndroid Build Coastguard Worker prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;
429*fb1b10abSAndroid Build Coastguard Worker
430*fb1b10abSAndroid Build Coastguard Worker if (prob_skip_false <= 1) prob_skip_false = 1;
431*fb1b10abSAndroid Build Coastguard Worker
432*fb1b10abSAndroid Build Coastguard Worker if (prob_skip_false > 255) prob_skip_false = 255;
433*fb1b10abSAndroid Build Coastguard Worker
434*fb1b10abSAndroid Build Coastguard Worker cpi->prob_skip_false = prob_skip_false;
435*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, prob_skip_false, 8);
436*fb1b10abSAndroid Build Coastguard Worker }
437*fb1b10abSAndroid Build Coastguard Worker
438*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, cpi->prob_intra_coded, 8);
439*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, cpi->prob_last_coded, 8);
440*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, cpi->prob_gf_coded, 8);
441*fb1b10abSAndroid Build Coastguard Worker
442*fb1b10abSAndroid Build Coastguard Worker update_mbintra_mode_probs(cpi);
443*fb1b10abSAndroid Build Coastguard Worker
444*fb1b10abSAndroid Build Coastguard Worker vp8_write_mvprobs(cpi);
445*fb1b10abSAndroid Build Coastguard Worker
446*fb1b10abSAndroid Build Coastguard Worker while (++mb_row < pc->mb_rows) {
447*fb1b10abSAndroid Build Coastguard Worker int mb_col = -1;
448*fb1b10abSAndroid Build Coastguard Worker
449*fb1b10abSAndroid Build Coastguard Worker while (++mb_col < pc->mb_cols) {
450*fb1b10abSAndroid Build Coastguard Worker const MB_MODE_INFO *const mi = &m->mbmi;
451*fb1b10abSAndroid Build Coastguard Worker const MV_REFERENCE_FRAME rf = mi->ref_frame;
452*fb1b10abSAndroid Build Coastguard Worker const MB_PREDICTION_MODE mode = mi->mode;
453*fb1b10abSAndroid Build Coastguard Worker
454*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *xd = &cpi->mb.e_mbd;
455*fb1b10abSAndroid Build Coastguard Worker
456*fb1b10abSAndroid Build Coastguard Worker /* Distance of Mb to the various image edges.
457*fb1b10abSAndroid Build Coastguard Worker * These specified to 8th pel as they are always compared to MV
458*fb1b10abSAndroid Build Coastguard Worker * values that are in 1/8th pel units
459*fb1b10abSAndroid Build Coastguard Worker */
460*fb1b10abSAndroid Build Coastguard Worker xd->mb_to_left_edge = -((mb_col * 16) << 3);
461*fb1b10abSAndroid Build Coastguard Worker xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
462*fb1b10abSAndroid Build Coastguard Worker xd->mb_to_top_edge = -((mb_row * 16) << 3);
463*fb1b10abSAndroid Build Coastguard Worker xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
464*fb1b10abSAndroid Build Coastguard Worker
465*fb1b10abSAndroid Build Coastguard Worker if (cpi->mb.e_mbd.update_mb_segmentation_map) {
466*fb1b10abSAndroid Build Coastguard Worker write_mb_features(w, mi, &cpi->mb.e_mbd);
467*fb1b10abSAndroid Build Coastguard Worker }
468*fb1b10abSAndroid Build Coastguard Worker
469*fb1b10abSAndroid Build Coastguard Worker if (pc->mb_no_coeff_skip) {
470*fb1b10abSAndroid Build Coastguard Worker vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
471*fb1b10abSAndroid Build Coastguard Worker }
472*fb1b10abSAndroid Build Coastguard Worker
473*fb1b10abSAndroid Build Coastguard Worker if (rf == INTRA_FRAME) {
474*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, cpi->prob_intra_coded);
475*fb1b10abSAndroid Build Coastguard Worker write_ymode(w, mode, pc->fc.ymode_prob);
476*fb1b10abSAndroid Build Coastguard Worker
477*fb1b10abSAndroid Build Coastguard Worker if (mode == B_PRED) {
478*fb1b10abSAndroid Build Coastguard Worker int j = 0;
479*fb1b10abSAndroid Build Coastguard Worker
480*fb1b10abSAndroid Build Coastguard Worker do {
481*fb1b10abSAndroid Build Coastguard Worker write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob);
482*fb1b10abSAndroid Build Coastguard Worker } while (++j < 16);
483*fb1b10abSAndroid Build Coastguard Worker }
484*fb1b10abSAndroid Build Coastguard Worker
485*fb1b10abSAndroid Build Coastguard Worker write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
486*fb1b10abSAndroid Build Coastguard Worker } else { /* inter coded */
487*fb1b10abSAndroid Build Coastguard Worker int_mv best_mv;
488*fb1b10abSAndroid Build Coastguard Worker vp8_prob mv_ref_p[VP8_MVREFS - 1];
489*fb1b10abSAndroid Build Coastguard Worker
490*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, cpi->prob_intra_coded);
491*fb1b10abSAndroid Build Coastguard Worker
492*fb1b10abSAndroid Build Coastguard Worker if (rf == LAST_FRAME)
493*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 0, cpi->prob_last_coded);
494*fb1b10abSAndroid Build Coastguard Worker else {
495*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, 1, cpi->prob_last_coded);
496*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cpi->prob_gf_coded);
497*fb1b10abSAndroid Build Coastguard Worker }
498*fb1b10abSAndroid Build Coastguard Worker
499*fb1b10abSAndroid Build Coastguard Worker {
500*fb1b10abSAndroid Build Coastguard Worker int_mv n1, n2;
501*fb1b10abSAndroid Build Coastguard Worker int ct[4];
502*fb1b10abSAndroid Build Coastguard Worker
503*fb1b10abSAndroid Build Coastguard Worker vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf,
504*fb1b10abSAndroid Build Coastguard Worker pc->ref_frame_sign_bias);
505*fb1b10abSAndroid Build Coastguard Worker vp8_clamp_mv2(&best_mv, xd);
506*fb1b10abSAndroid Build Coastguard Worker
507*fb1b10abSAndroid Build Coastguard Worker vp8_mv_ref_probs(mv_ref_p, ct);
508*fb1b10abSAndroid Build Coastguard Worker }
509*fb1b10abSAndroid Build Coastguard Worker
510*fb1b10abSAndroid Build Coastguard Worker write_mv_ref(w, mode, mv_ref_p);
511*fb1b10abSAndroid Build Coastguard Worker
512*fb1b10abSAndroid Build Coastguard Worker switch (mode) /* new, split require MVs */
513*fb1b10abSAndroid Build Coastguard Worker {
514*fb1b10abSAndroid Build Coastguard Worker case NEWMV: write_mv(w, &mi->mv.as_mv, &best_mv, mvc); break;
515*fb1b10abSAndroid Build Coastguard Worker
516*fb1b10abSAndroid Build Coastguard Worker case SPLITMV: {
517*fb1b10abSAndroid Build Coastguard Worker int j = 0;
518*fb1b10abSAndroid Build Coastguard Worker
519*fb1b10abSAndroid Build Coastguard Worker #ifdef MODE_STATS
520*fb1b10abSAndroid Build Coastguard Worker ++count_mb_seg[mi->partitioning];
521*fb1b10abSAndroid Build Coastguard Worker #endif
522*fb1b10abSAndroid Build Coastguard Worker
523*fb1b10abSAndroid Build Coastguard Worker write_split(w, mi->partitioning);
524*fb1b10abSAndroid Build Coastguard Worker
525*fb1b10abSAndroid Build Coastguard Worker do {
526*fb1b10abSAndroid Build Coastguard Worker B_PREDICTION_MODE blockmode;
527*fb1b10abSAndroid Build Coastguard Worker int_mv blockmv;
528*fb1b10abSAndroid Build Coastguard Worker const int *const L = vp8_mbsplits[mi->partitioning];
529*fb1b10abSAndroid Build Coastguard Worker int k = -1; /* first block in subset j */
530*fb1b10abSAndroid Build Coastguard Worker int mv_contz;
531*fb1b10abSAndroid Build Coastguard Worker int_mv leftmv, abovemv;
532*fb1b10abSAndroid Build Coastguard Worker
533*fb1b10abSAndroid Build Coastguard Worker blockmode = cpi->mb.partition_info->bmi[j].mode;
534*fb1b10abSAndroid Build Coastguard Worker blockmv = cpi->mb.partition_info->bmi[j].mv;
535*fb1b10abSAndroid Build Coastguard Worker while (j != L[++k]) {
536*fb1b10abSAndroid Build Coastguard Worker assert(k < 16);
537*fb1b10abSAndroid Build Coastguard Worker }
538*fb1b10abSAndroid Build Coastguard Worker leftmv.as_int = left_block_mv(m, k);
539*fb1b10abSAndroid Build Coastguard Worker abovemv.as_int = above_block_mv(m, k, mis);
540*fb1b10abSAndroid Build Coastguard Worker mv_contz = vp8_mv_cont(&leftmv, &abovemv);
541*fb1b10abSAndroid Build Coastguard Worker
542*fb1b10abSAndroid Build Coastguard Worker write_sub_mv_ref(w, blockmode, vp8_sub_mv_ref_prob2[mv_contz]);
543*fb1b10abSAndroid Build Coastguard Worker
544*fb1b10abSAndroid Build Coastguard Worker if (blockmode == NEW4X4) {
545*fb1b10abSAndroid Build Coastguard Worker write_mv(w, &blockmv.as_mv, &best_mv, (const MV_CONTEXT *)mvc);
546*fb1b10abSAndroid Build Coastguard Worker }
547*fb1b10abSAndroid Build Coastguard Worker } while (++j < cpi->mb.partition_info->count);
548*fb1b10abSAndroid Build Coastguard Worker break;
549*fb1b10abSAndroid Build Coastguard Worker }
550*fb1b10abSAndroid Build Coastguard Worker default: break;
551*fb1b10abSAndroid Build Coastguard Worker }
552*fb1b10abSAndroid Build Coastguard Worker }
553*fb1b10abSAndroid Build Coastguard Worker
554*fb1b10abSAndroid Build Coastguard Worker ++m;
555*fb1b10abSAndroid Build Coastguard Worker cpi->mb.partition_info++;
556*fb1b10abSAndroid Build Coastguard Worker }
557*fb1b10abSAndroid Build Coastguard Worker
558*fb1b10abSAndroid Build Coastguard Worker ++m; /* skip L prediction border */
559*fb1b10abSAndroid Build Coastguard Worker cpi->mb.partition_info++;
560*fb1b10abSAndroid Build Coastguard Worker }
561*fb1b10abSAndroid Build Coastguard Worker }
562*fb1b10abSAndroid Build Coastguard Worker
write_kfmodes(VP8_COMP * cpi)563*fb1b10abSAndroid Build Coastguard Worker static void write_kfmodes(VP8_COMP *cpi) {
564*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const bc = cpi->bc;
565*fb1b10abSAndroid Build Coastguard Worker const VP8_COMMON *const c = &cpi->common;
566*fb1b10abSAndroid Build Coastguard Worker /* const */
567*fb1b10abSAndroid Build Coastguard Worker MODE_INFO *m = c->mi;
568*fb1b10abSAndroid Build Coastguard Worker
569*fb1b10abSAndroid Build Coastguard Worker int mb_row = -1;
570*fb1b10abSAndroid Build Coastguard Worker int prob_skip_false = 0;
571*fb1b10abSAndroid Build Coastguard Worker
572*fb1b10abSAndroid Build Coastguard Worker if (c->mb_no_coeff_skip) {
573*fb1b10abSAndroid Build Coastguard Worker int total_mbs = c->mb_rows * c->mb_cols;
574*fb1b10abSAndroid Build Coastguard Worker
575*fb1b10abSAndroid Build Coastguard Worker prob_skip_false = (total_mbs - cpi->mb.skip_true_count) * 256 / total_mbs;
576*fb1b10abSAndroid Build Coastguard Worker
577*fb1b10abSAndroid Build Coastguard Worker if (prob_skip_false <= 1) prob_skip_false = 1;
578*fb1b10abSAndroid Build Coastguard Worker
579*fb1b10abSAndroid Build Coastguard Worker if (prob_skip_false >= 255) prob_skip_false = 255;
580*fb1b10abSAndroid Build Coastguard Worker
581*fb1b10abSAndroid Build Coastguard Worker cpi->prob_skip_false = prob_skip_false;
582*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, prob_skip_false, 8);
583*fb1b10abSAndroid Build Coastguard Worker }
584*fb1b10abSAndroid Build Coastguard Worker
585*fb1b10abSAndroid Build Coastguard Worker while (++mb_row < c->mb_rows) {
586*fb1b10abSAndroid Build Coastguard Worker int mb_col = -1;
587*fb1b10abSAndroid Build Coastguard Worker
588*fb1b10abSAndroid Build Coastguard Worker while (++mb_col < c->mb_cols) {
589*fb1b10abSAndroid Build Coastguard Worker const int ym = m->mbmi.mode;
590*fb1b10abSAndroid Build Coastguard Worker
591*fb1b10abSAndroid Build Coastguard Worker if (cpi->mb.e_mbd.update_mb_segmentation_map) {
592*fb1b10abSAndroid Build Coastguard Worker write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
593*fb1b10abSAndroid Build Coastguard Worker }
594*fb1b10abSAndroid Build Coastguard Worker
595*fb1b10abSAndroid Build Coastguard Worker if (c->mb_no_coeff_skip) {
596*fb1b10abSAndroid Build Coastguard Worker vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
597*fb1b10abSAndroid Build Coastguard Worker }
598*fb1b10abSAndroid Build Coastguard Worker
599*fb1b10abSAndroid Build Coastguard Worker kfwrite_ymode(bc, ym, vp8_kf_ymode_prob);
600*fb1b10abSAndroid Build Coastguard Worker
601*fb1b10abSAndroid Build Coastguard Worker if (ym == B_PRED) {
602*fb1b10abSAndroid Build Coastguard Worker const int mis = c->mode_info_stride;
603*fb1b10abSAndroid Build Coastguard Worker int i = 0;
604*fb1b10abSAndroid Build Coastguard Worker
605*fb1b10abSAndroid Build Coastguard Worker do {
606*fb1b10abSAndroid Build Coastguard Worker const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
607*fb1b10abSAndroid Build Coastguard Worker const B_PREDICTION_MODE L = left_block_mode(m, i);
608*fb1b10abSAndroid Build Coastguard Worker const int bm = m->bmi[i].as_mode;
609*fb1b10abSAndroid Build Coastguard Worker
610*fb1b10abSAndroid Build Coastguard Worker write_bmode(bc, bm, vp8_kf_bmode_prob[A][L]);
611*fb1b10abSAndroid Build Coastguard Worker } while (++i < 16);
612*fb1b10abSAndroid Build Coastguard Worker }
613*fb1b10abSAndroid Build Coastguard Worker
614*fb1b10abSAndroid Build Coastguard Worker write_uv_mode(bc, (m++)->mbmi.uv_mode, vp8_kf_uv_mode_prob);
615*fb1b10abSAndroid Build Coastguard Worker }
616*fb1b10abSAndroid Build Coastguard Worker
617*fb1b10abSAndroid Build Coastguard Worker m++; /* skip L prediction border */
618*fb1b10abSAndroid Build Coastguard Worker }
619*fb1b10abSAndroid Build Coastguard Worker }
620*fb1b10abSAndroid Build Coastguard Worker
621*fb1b10abSAndroid Build Coastguard Worker #if 0
622*fb1b10abSAndroid Build Coastguard Worker /* This function is used for debugging probability trees. */
623*fb1b10abSAndroid Build Coastguard Worker static void print_prob_tree(vp8_prob
624*fb1b10abSAndroid Build Coastguard Worker coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES])
625*fb1b10abSAndroid Build Coastguard Worker {
626*fb1b10abSAndroid Build Coastguard Worker /* print coef probability tree */
627*fb1b10abSAndroid Build Coastguard Worker int i,j,k,l;
628*fb1b10abSAndroid Build Coastguard Worker FILE* f = fopen("enc_tree_probs.txt", "a");
629*fb1b10abSAndroid Build Coastguard Worker fprintf(f, "{\n");
630*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < BLOCK_TYPES; ++i)
631*fb1b10abSAndroid Build Coastguard Worker {
632*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " {\n");
633*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < COEF_BANDS; ++j)
634*fb1b10abSAndroid Build Coastguard Worker {
635*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " {\n");
636*fb1b10abSAndroid Build Coastguard Worker for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
637*fb1b10abSAndroid Build Coastguard Worker {
638*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " {");
639*fb1b10abSAndroid Build Coastguard Worker for (l = 0; l < ENTROPY_NODES; ++l)
640*fb1b10abSAndroid Build Coastguard Worker {
641*fb1b10abSAndroid Build Coastguard Worker fprintf(f, "%3u, ",
642*fb1b10abSAndroid Build Coastguard Worker (unsigned int)(coef_probs [i][j][k][l]));
643*fb1b10abSAndroid Build Coastguard Worker }
644*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " }\n");
645*fb1b10abSAndroid Build Coastguard Worker }
646*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " }\n");
647*fb1b10abSAndroid Build Coastguard Worker }
648*fb1b10abSAndroid Build Coastguard Worker fprintf(f, " }\n");
649*fb1b10abSAndroid Build Coastguard Worker }
650*fb1b10abSAndroid Build Coastguard Worker fprintf(f, "}\n");
651*fb1b10abSAndroid Build Coastguard Worker fclose(f);
652*fb1b10abSAndroid Build Coastguard Worker }
653*fb1b10abSAndroid Build Coastguard Worker #endif
654*fb1b10abSAndroid Build Coastguard Worker
sum_probs_over_prev_coef_context(const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],unsigned int * out)655*fb1b10abSAndroid Build Coastguard Worker static void sum_probs_over_prev_coef_context(
656*fb1b10abSAndroid Build Coastguard Worker const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],
657*fb1b10abSAndroid Build Coastguard Worker unsigned int *out) {
658*fb1b10abSAndroid Build Coastguard Worker int i, j;
659*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_ENTROPY_TOKENS; ++i) {
660*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < PREV_COEF_CONTEXTS; ++j) {
661*fb1b10abSAndroid Build Coastguard Worker const unsigned int tmp = out[i];
662*fb1b10abSAndroid Build Coastguard Worker out[i] += probs[j][i];
663*fb1b10abSAndroid Build Coastguard Worker /* check for wrap */
664*fb1b10abSAndroid Build Coastguard Worker if (out[i] < tmp) out[i] = UINT_MAX;
665*fb1b10abSAndroid Build Coastguard Worker }
666*fb1b10abSAndroid Build Coastguard Worker }
667*fb1b10abSAndroid Build Coastguard Worker }
668*fb1b10abSAndroid Build Coastguard Worker
prob_update_savings(const unsigned int * ct,const vp8_prob oldp,const vp8_prob newp,const vp8_prob upd)669*fb1b10abSAndroid Build Coastguard Worker static int prob_update_savings(const unsigned int *ct, const vp8_prob oldp,
670*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp, const vp8_prob upd) {
671*fb1b10abSAndroid Build Coastguard Worker const int old_b = vp8_cost_branch(ct, oldp);
672*fb1b10abSAndroid Build Coastguard Worker const int new_b = vp8_cost_branch(ct, newp);
673*fb1b10abSAndroid Build Coastguard Worker const int update_b = 8 + ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
674*fb1b10abSAndroid Build Coastguard Worker
675*fb1b10abSAndroid Build Coastguard Worker return old_b - new_b - update_b;
676*fb1b10abSAndroid Build Coastguard Worker }
677*fb1b10abSAndroid Build Coastguard Worker
independent_coef_context_savings(VP8_COMP * cpi)678*fb1b10abSAndroid Build Coastguard Worker static int independent_coef_context_savings(VP8_COMP *cpi) {
679*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = &cpi->mb;
680*fb1b10abSAndroid Build Coastguard Worker int savings = 0;
681*fb1b10abSAndroid Build Coastguard Worker int i = 0;
682*fb1b10abSAndroid Build Coastguard Worker do {
683*fb1b10abSAndroid Build Coastguard Worker int j = 0;
684*fb1b10abSAndroid Build Coastguard Worker do {
685*fb1b10abSAndroid Build Coastguard Worker int k = 0;
686*fb1b10abSAndroid Build Coastguard Worker unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = { 0 };
687*fb1b10abSAndroid Build Coastguard Worker int prev_coef_savings[MAX_ENTROPY_TOKENS] = { 0 };
688*fb1b10abSAndroid Build Coastguard Worker const unsigned int(*probs)[MAX_ENTROPY_TOKENS];
689*fb1b10abSAndroid Build Coastguard Worker /* Calculate new probabilities given the constraint that
690*fb1b10abSAndroid Build Coastguard Worker * they must be equal over the prev coef contexts
691*fb1b10abSAndroid Build Coastguard Worker */
692*fb1b10abSAndroid Build Coastguard Worker
693*fb1b10abSAndroid Build Coastguard Worker probs = (const unsigned int(*)[MAX_ENTROPY_TOKENS])x->coef_counts[i][j];
694*fb1b10abSAndroid Build Coastguard Worker
695*fb1b10abSAndroid Build Coastguard Worker /* Reset to default probabilities at key frames */
696*fb1b10abSAndroid Build Coastguard Worker if (cpi->common.frame_type == KEY_FRAME) {
697*fb1b10abSAndroid Build Coastguard Worker probs = default_coef_counts[i][j];
698*fb1b10abSAndroid Build Coastguard Worker }
699*fb1b10abSAndroid Build Coastguard Worker
700*fb1b10abSAndroid Build Coastguard Worker sum_probs_over_prev_coef_context(probs, prev_coef_count_sum);
701*fb1b10abSAndroid Build Coastguard Worker
702*fb1b10abSAndroid Build Coastguard Worker do {
703*fb1b10abSAndroid Build Coastguard Worker /* at every context */
704*fb1b10abSAndroid Build Coastguard Worker
705*fb1b10abSAndroid Build Coastguard Worker /* calc probs and branch cts for this frame only */
706*fb1b10abSAndroid Build Coastguard Worker int t = 0; /* token/prob index */
707*fb1b10abSAndroid Build Coastguard Worker
708*fb1b10abSAndroid Build Coastguard Worker vp8_tree_probs_from_distribution(
709*fb1b10abSAndroid Build Coastguard Worker MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
710*fb1b10abSAndroid Build Coastguard Worker cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
711*fb1b10abSAndroid Build Coastguard Worker prev_coef_count_sum, 256, 1);
712*fb1b10abSAndroid Build Coastguard Worker
713*fb1b10abSAndroid Build Coastguard Worker do {
714*fb1b10abSAndroid Build Coastguard Worker const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
715*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
716*fb1b10abSAndroid Build Coastguard Worker const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
717*fb1b10abSAndroid Build Coastguard Worker const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
718*fb1b10abSAndroid Build Coastguard Worker const int s = prob_update_savings(ct, oldp, newp, upd);
719*fb1b10abSAndroid Build Coastguard Worker
720*fb1b10abSAndroid Build Coastguard Worker if (cpi->common.frame_type != KEY_FRAME ||
721*fb1b10abSAndroid Build Coastguard Worker (cpi->common.frame_type == KEY_FRAME && newp != oldp)) {
722*fb1b10abSAndroid Build Coastguard Worker prev_coef_savings[t] += s;
723*fb1b10abSAndroid Build Coastguard Worker }
724*fb1b10abSAndroid Build Coastguard Worker } while (++t < ENTROPY_NODES);
725*fb1b10abSAndroid Build Coastguard Worker } while (++k < PREV_COEF_CONTEXTS);
726*fb1b10abSAndroid Build Coastguard Worker k = 0;
727*fb1b10abSAndroid Build Coastguard Worker do {
728*fb1b10abSAndroid Build Coastguard Worker /* We only update probabilities if we can save bits, except
729*fb1b10abSAndroid Build Coastguard Worker * for key frames where we have to update all probabilities
730*fb1b10abSAndroid Build Coastguard Worker * to get the equal probabilities across the prev coef
731*fb1b10abSAndroid Build Coastguard Worker * contexts.
732*fb1b10abSAndroid Build Coastguard Worker */
733*fb1b10abSAndroid Build Coastguard Worker if (prev_coef_savings[k] > 0 || cpi->common.frame_type == KEY_FRAME) {
734*fb1b10abSAndroid Build Coastguard Worker savings += prev_coef_savings[k];
735*fb1b10abSAndroid Build Coastguard Worker }
736*fb1b10abSAndroid Build Coastguard Worker } while (++k < ENTROPY_NODES);
737*fb1b10abSAndroid Build Coastguard Worker } while (++j < COEF_BANDS);
738*fb1b10abSAndroid Build Coastguard Worker } while (++i < BLOCK_TYPES);
739*fb1b10abSAndroid Build Coastguard Worker return savings;
740*fb1b10abSAndroid Build Coastguard Worker }
741*fb1b10abSAndroid Build Coastguard Worker
default_coef_context_savings(VP8_COMP * cpi)742*fb1b10abSAndroid Build Coastguard Worker static int default_coef_context_savings(VP8_COMP *cpi) {
743*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = &cpi->mb;
744*fb1b10abSAndroid Build Coastguard Worker int savings = 0;
745*fb1b10abSAndroid Build Coastguard Worker int i = 0;
746*fb1b10abSAndroid Build Coastguard Worker do {
747*fb1b10abSAndroid Build Coastguard Worker int j = 0;
748*fb1b10abSAndroid Build Coastguard Worker do {
749*fb1b10abSAndroid Build Coastguard Worker int k = 0;
750*fb1b10abSAndroid Build Coastguard Worker do {
751*fb1b10abSAndroid Build Coastguard Worker /* at every context */
752*fb1b10abSAndroid Build Coastguard Worker
753*fb1b10abSAndroid Build Coastguard Worker /* calc probs and branch cts for this frame only */
754*fb1b10abSAndroid Build Coastguard Worker int t = 0; /* token/prob index */
755*fb1b10abSAndroid Build Coastguard Worker
756*fb1b10abSAndroid Build Coastguard Worker vp8_tree_probs_from_distribution(
757*fb1b10abSAndroid Build Coastguard Worker MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
758*fb1b10abSAndroid Build Coastguard Worker cpi->frame_coef_probs[i][j][k], cpi->frame_branch_ct[i][j][k],
759*fb1b10abSAndroid Build Coastguard Worker x->coef_counts[i][j][k], 256, 1);
760*fb1b10abSAndroid Build Coastguard Worker
761*fb1b10abSAndroid Build Coastguard Worker do {
762*fb1b10abSAndroid Build Coastguard Worker const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
763*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
764*fb1b10abSAndroid Build Coastguard Worker const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
765*fb1b10abSAndroid Build Coastguard Worker const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
766*fb1b10abSAndroid Build Coastguard Worker const int s = prob_update_savings(ct, oldp, newp, upd);
767*fb1b10abSAndroid Build Coastguard Worker
768*fb1b10abSAndroid Build Coastguard Worker if (s > 0) {
769*fb1b10abSAndroid Build Coastguard Worker savings += s;
770*fb1b10abSAndroid Build Coastguard Worker }
771*fb1b10abSAndroid Build Coastguard Worker } while (++t < ENTROPY_NODES);
772*fb1b10abSAndroid Build Coastguard Worker } while (++k < PREV_COEF_CONTEXTS);
773*fb1b10abSAndroid Build Coastguard Worker } while (++j < COEF_BANDS);
774*fb1b10abSAndroid Build Coastguard Worker } while (++i < BLOCK_TYPES);
775*fb1b10abSAndroid Build Coastguard Worker return savings;
776*fb1b10abSAndroid Build Coastguard Worker }
777*fb1b10abSAndroid Build Coastguard Worker
vp8_calc_ref_frame_costs(int * ref_frame_cost,int prob_intra,int prob_last,int prob_garf)778*fb1b10abSAndroid Build Coastguard Worker void vp8_calc_ref_frame_costs(int *ref_frame_cost, int prob_intra,
779*fb1b10abSAndroid Build Coastguard Worker int prob_last, int prob_garf) {
780*fb1b10abSAndroid Build Coastguard Worker assert(prob_intra >= 0);
781*fb1b10abSAndroid Build Coastguard Worker assert(prob_intra <= 255);
782*fb1b10abSAndroid Build Coastguard Worker assert(prob_last >= 0);
783*fb1b10abSAndroid Build Coastguard Worker assert(prob_last <= 255);
784*fb1b10abSAndroid Build Coastguard Worker assert(prob_garf >= 0);
785*fb1b10abSAndroid Build Coastguard Worker assert(prob_garf <= 255);
786*fb1b10abSAndroid Build Coastguard Worker ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(prob_intra);
787*fb1b10abSAndroid Build Coastguard Worker ref_frame_cost[LAST_FRAME] =
788*fb1b10abSAndroid Build Coastguard Worker vp8_cost_one(prob_intra) + vp8_cost_zero(prob_last);
789*fb1b10abSAndroid Build Coastguard Worker ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(prob_intra) +
790*fb1b10abSAndroid Build Coastguard Worker vp8_cost_one(prob_last) +
791*fb1b10abSAndroid Build Coastguard Worker vp8_cost_zero(prob_garf);
792*fb1b10abSAndroid Build Coastguard Worker ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(prob_intra) +
793*fb1b10abSAndroid Build Coastguard Worker vp8_cost_one(prob_last) +
794*fb1b10abSAndroid Build Coastguard Worker vp8_cost_one(prob_garf);
795*fb1b10abSAndroid Build Coastguard Worker }
796*fb1b10abSAndroid Build Coastguard Worker
vp8_estimate_entropy_savings(VP8_COMP * cpi)797*fb1b10abSAndroid Build Coastguard Worker int vp8_estimate_entropy_savings(VP8_COMP *cpi) {
798*fb1b10abSAndroid Build Coastguard Worker int savings = 0;
799*fb1b10abSAndroid Build Coastguard Worker
800*fb1b10abSAndroid Build Coastguard Worker const int *const rfct = cpi->mb.count_mb_ref_frame_usage;
801*fb1b10abSAndroid Build Coastguard Worker const int rf_intra = rfct[INTRA_FRAME];
802*fb1b10abSAndroid Build Coastguard Worker const int rf_inter =
803*fb1b10abSAndroid Build Coastguard Worker rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
804*fb1b10abSAndroid Build Coastguard Worker int new_intra, new_last, new_garf, oldtotal, newtotal;
805*fb1b10abSAndroid Build Coastguard Worker int ref_frame_cost[MAX_REF_FRAMES];
806*fb1b10abSAndroid Build Coastguard Worker
807*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
808*fb1b10abSAndroid Build Coastguard Worker
809*fb1b10abSAndroid Build Coastguard Worker if (cpi->common.frame_type != KEY_FRAME) {
810*fb1b10abSAndroid Build Coastguard Worker if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter))) new_intra = 1;
811*fb1b10abSAndroid Build Coastguard Worker
812*fb1b10abSAndroid Build Coastguard Worker new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
813*fb1b10abSAndroid Build Coastguard Worker
814*fb1b10abSAndroid Build Coastguard Worker new_garf = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
815*fb1b10abSAndroid Build Coastguard Worker ? (rfct[GOLDEN_FRAME] * 255) /
816*fb1b10abSAndroid Build Coastguard Worker (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
817*fb1b10abSAndroid Build Coastguard Worker : 128;
818*fb1b10abSAndroid Build Coastguard Worker
819*fb1b10abSAndroid Build Coastguard Worker vp8_calc_ref_frame_costs(ref_frame_cost, new_intra, new_last, new_garf);
820*fb1b10abSAndroid Build Coastguard Worker
821*fb1b10abSAndroid Build Coastguard Worker newtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
822*fb1b10abSAndroid Build Coastguard Worker rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
823*fb1b10abSAndroid Build Coastguard Worker rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
824*fb1b10abSAndroid Build Coastguard Worker rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
825*fb1b10abSAndroid Build Coastguard Worker
826*fb1b10abSAndroid Build Coastguard Worker /* old costs */
827*fb1b10abSAndroid Build Coastguard Worker vp8_calc_ref_frame_costs(ref_frame_cost, cpi->prob_intra_coded,
828*fb1b10abSAndroid Build Coastguard Worker cpi->prob_last_coded, cpi->prob_gf_coded);
829*fb1b10abSAndroid Build Coastguard Worker
830*fb1b10abSAndroid Build Coastguard Worker oldtotal = rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
831*fb1b10abSAndroid Build Coastguard Worker rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
832*fb1b10abSAndroid Build Coastguard Worker rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
833*fb1b10abSAndroid Build Coastguard Worker rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
834*fb1b10abSAndroid Build Coastguard Worker
835*fb1b10abSAndroid Build Coastguard Worker savings += (oldtotal - newtotal) / 256;
836*fb1b10abSAndroid Build Coastguard Worker }
837*fb1b10abSAndroid Build Coastguard Worker
838*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
839*fb1b10abSAndroid Build Coastguard Worker savings += independent_coef_context_savings(cpi);
840*fb1b10abSAndroid Build Coastguard Worker } else {
841*fb1b10abSAndroid Build Coastguard Worker savings += default_coef_context_savings(cpi);
842*fb1b10abSAndroid Build Coastguard Worker }
843*fb1b10abSAndroid Build Coastguard Worker
844*fb1b10abSAndroid Build Coastguard Worker return savings;
845*fb1b10abSAndroid Build Coastguard Worker }
846*fb1b10abSAndroid Build Coastguard Worker
847*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
vp8_update_coef_context(VP8_COMP * cpi)848*fb1b10abSAndroid Build Coastguard Worker int vp8_update_coef_context(VP8_COMP *cpi) {
849*fb1b10abSAndroid Build Coastguard Worker int savings = 0;
850*fb1b10abSAndroid Build Coastguard Worker
851*fb1b10abSAndroid Build Coastguard Worker if (cpi->common.frame_type == KEY_FRAME) {
852*fb1b10abSAndroid Build Coastguard Worker /* Reset to default counts/probabilities at key frames */
853*fb1b10abSAndroid Build Coastguard Worker vp8_copy(cpi->mb.coef_counts, default_coef_counts);
854*fb1b10abSAndroid Build Coastguard Worker }
855*fb1b10abSAndroid Build Coastguard Worker
856*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
857*fb1b10abSAndroid Build Coastguard Worker savings += independent_coef_context_savings(cpi);
858*fb1b10abSAndroid Build Coastguard Worker else
859*fb1b10abSAndroid Build Coastguard Worker savings += default_coef_context_savings(cpi);
860*fb1b10abSAndroid Build Coastguard Worker
861*fb1b10abSAndroid Build Coastguard Worker return savings;
862*fb1b10abSAndroid Build Coastguard Worker }
863*fb1b10abSAndroid Build Coastguard Worker #endif
864*fb1b10abSAndroid Build Coastguard Worker
vp8_update_coef_probs(VP8_COMP * cpi)865*fb1b10abSAndroid Build Coastguard Worker void vp8_update_coef_probs(VP8_COMP *cpi) {
866*fb1b10abSAndroid Build Coastguard Worker int i = 0;
867*fb1b10abSAndroid Build Coastguard Worker #if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
868*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const w = cpi->bc;
869*fb1b10abSAndroid Build Coastguard Worker #endif
870*fb1b10abSAndroid Build Coastguard Worker
871*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
872*fb1b10abSAndroid Build Coastguard Worker
873*fb1b10abSAndroid Build Coastguard Worker do {
874*fb1b10abSAndroid Build Coastguard Worker int j = 0;
875*fb1b10abSAndroid Build Coastguard Worker
876*fb1b10abSAndroid Build Coastguard Worker do {
877*fb1b10abSAndroid Build Coastguard Worker int k = 0;
878*fb1b10abSAndroid Build Coastguard Worker int prev_coef_savings[ENTROPY_NODES] = { 0 };
879*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
880*fb1b10abSAndroid Build Coastguard Worker for (k = 0; k < PREV_COEF_CONTEXTS; ++k) {
881*fb1b10abSAndroid Build Coastguard Worker int t; /* token/prob index */
882*fb1b10abSAndroid Build Coastguard Worker for (t = 0; t < ENTROPY_NODES; ++t) {
883*fb1b10abSAndroid Build Coastguard Worker const unsigned int *ct = cpi->frame_branch_ct[i][j][k][t];
884*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
885*fb1b10abSAndroid Build Coastguard Worker const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t];
886*fb1b10abSAndroid Build Coastguard Worker const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
887*fb1b10abSAndroid Build Coastguard Worker
888*fb1b10abSAndroid Build Coastguard Worker prev_coef_savings[t] += prob_update_savings(ct, oldp, newp, upd);
889*fb1b10abSAndroid Build Coastguard Worker }
890*fb1b10abSAndroid Build Coastguard Worker }
891*fb1b10abSAndroid Build Coastguard Worker k = 0;
892*fb1b10abSAndroid Build Coastguard Worker }
893*fb1b10abSAndroid Build Coastguard Worker do {
894*fb1b10abSAndroid Build Coastguard Worker /* note: use result from vp8_estimate_entropy_savings, so no
895*fb1b10abSAndroid Build Coastguard Worker * need to call vp8_tree_probs_from_distribution here.
896*fb1b10abSAndroid Build Coastguard Worker */
897*fb1b10abSAndroid Build Coastguard Worker
898*fb1b10abSAndroid Build Coastguard Worker /* at every context */
899*fb1b10abSAndroid Build Coastguard Worker
900*fb1b10abSAndroid Build Coastguard Worker /* calc probs and branch cts for this frame only */
901*fb1b10abSAndroid Build Coastguard Worker int t = 0; /* token/prob index */
902*fb1b10abSAndroid Build Coastguard Worker
903*fb1b10abSAndroid Build Coastguard Worker do {
904*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
905*fb1b10abSAndroid Build Coastguard Worker
906*fb1b10abSAndroid Build Coastguard Worker vp8_prob *Pold = cpi->common.fc.coef_probs[i][j][k] + t;
907*fb1b10abSAndroid Build Coastguard Worker const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
908*fb1b10abSAndroid Build Coastguard Worker
909*fb1b10abSAndroid Build Coastguard Worker int s = prev_coef_savings[t];
910*fb1b10abSAndroid Build Coastguard Worker int u = 0;
911*fb1b10abSAndroid Build Coastguard Worker
912*fb1b10abSAndroid Build Coastguard Worker if (!(cpi->oxcf.error_resilient_mode &
913*fb1b10abSAndroid Build Coastguard Worker VPX_ERROR_RESILIENT_PARTITIONS)) {
914*fb1b10abSAndroid Build Coastguard Worker s = prob_update_savings(cpi->frame_branch_ct[i][j][k][t], *Pold,
915*fb1b10abSAndroid Build Coastguard Worker newp, upd);
916*fb1b10abSAndroid Build Coastguard Worker }
917*fb1b10abSAndroid Build Coastguard Worker
918*fb1b10abSAndroid Build Coastguard Worker if (s > 0) u = 1;
919*fb1b10abSAndroid Build Coastguard Worker
920*fb1b10abSAndroid Build Coastguard Worker /* Force updates on key frames if the new is different,
921*fb1b10abSAndroid Build Coastguard Worker * so that we can be sure we end up with equal probabilities
922*fb1b10abSAndroid Build Coastguard Worker * over the prev coef contexts.
923*fb1b10abSAndroid Build Coastguard Worker */
924*fb1b10abSAndroid Build Coastguard Worker if ((cpi->oxcf.error_resilient_mode &
925*fb1b10abSAndroid Build Coastguard Worker VPX_ERROR_RESILIENT_PARTITIONS) &&
926*fb1b10abSAndroid Build Coastguard Worker cpi->common.frame_type == KEY_FRAME && newp != *Pold) {
927*fb1b10abSAndroid Build Coastguard Worker u = 1;
928*fb1b10abSAndroid Build Coastguard Worker }
929*fb1b10abSAndroid Build Coastguard Worker
930*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
931*fb1b10abSAndroid Build Coastguard Worker cpi->update_probs[i][j][k][t] = u;
932*fb1b10abSAndroid Build Coastguard Worker #else
933*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, u, upd);
934*fb1b10abSAndroid Build Coastguard Worker #endif
935*fb1b10abSAndroid Build Coastguard Worker
936*fb1b10abSAndroid Build Coastguard Worker if (u) {
937*fb1b10abSAndroid Build Coastguard Worker /* send/use new probability */
938*fb1b10abSAndroid Build Coastguard Worker
939*fb1b10abSAndroid Build Coastguard Worker *Pold = newp;
940*fb1b10abSAndroid Build Coastguard Worker #if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
941*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, newp, 8);
942*fb1b10abSAndroid Build Coastguard Worker #endif
943*fb1b10abSAndroid Build Coastguard Worker }
944*fb1b10abSAndroid Build Coastguard Worker
945*fb1b10abSAndroid Build Coastguard Worker } while (++t < ENTROPY_NODES);
946*fb1b10abSAndroid Build Coastguard Worker
947*fb1b10abSAndroid Build Coastguard Worker } while (++k < PREV_COEF_CONTEXTS);
948*fb1b10abSAndroid Build Coastguard Worker } while (++j < COEF_BANDS);
949*fb1b10abSAndroid Build Coastguard Worker } while (++i < BLOCK_TYPES);
950*fb1b10abSAndroid Build Coastguard Worker }
951*fb1b10abSAndroid Build Coastguard Worker
952*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
pack_coef_probs(VP8_COMP * cpi)953*fb1b10abSAndroid Build Coastguard Worker static void pack_coef_probs(VP8_COMP *cpi) {
954*fb1b10abSAndroid Build Coastguard Worker int i = 0;
955*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const w = cpi->bc;
956*fb1b10abSAndroid Build Coastguard Worker
957*fb1b10abSAndroid Build Coastguard Worker do {
958*fb1b10abSAndroid Build Coastguard Worker int j = 0;
959*fb1b10abSAndroid Build Coastguard Worker
960*fb1b10abSAndroid Build Coastguard Worker do {
961*fb1b10abSAndroid Build Coastguard Worker int k = 0;
962*fb1b10abSAndroid Build Coastguard Worker
963*fb1b10abSAndroid Build Coastguard Worker do {
964*fb1b10abSAndroid Build Coastguard Worker int t = 0; /* token/prob index */
965*fb1b10abSAndroid Build Coastguard Worker
966*fb1b10abSAndroid Build Coastguard Worker do {
967*fb1b10abSAndroid Build Coastguard Worker const vp8_prob newp = cpi->common.fc.coef_probs[i][j][k][t];
968*fb1b10abSAndroid Build Coastguard Worker const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
969*fb1b10abSAndroid Build Coastguard Worker
970*fb1b10abSAndroid Build Coastguard Worker const char u = cpi->update_probs[i][j][k][t];
971*fb1b10abSAndroid Build Coastguard Worker
972*fb1b10abSAndroid Build Coastguard Worker vp8_write(w, u, upd);
973*fb1b10abSAndroid Build Coastguard Worker
974*fb1b10abSAndroid Build Coastguard Worker if (u) {
975*fb1b10abSAndroid Build Coastguard Worker /* send/use new probability */
976*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(w, newp, 8);
977*fb1b10abSAndroid Build Coastguard Worker }
978*fb1b10abSAndroid Build Coastguard Worker } while (++t < ENTROPY_NODES);
979*fb1b10abSAndroid Build Coastguard Worker } while (++k < PREV_COEF_CONTEXTS);
980*fb1b10abSAndroid Build Coastguard Worker } while (++j < COEF_BANDS);
981*fb1b10abSAndroid Build Coastguard Worker } while (++i < BLOCK_TYPES);
982*fb1b10abSAndroid Build Coastguard Worker }
983*fb1b10abSAndroid Build Coastguard Worker #endif
984*fb1b10abSAndroid Build Coastguard Worker
985*fb1b10abSAndroid Build Coastguard Worker #ifdef PACKET_TESTING
986*fb1b10abSAndroid Build Coastguard Worker FILE *vpxlogc = 0;
987*fb1b10abSAndroid Build Coastguard Worker #endif
988*fb1b10abSAndroid Build Coastguard Worker
put_delta_q(vp8_writer * bc,int delta_q)989*fb1b10abSAndroid Build Coastguard Worker static void put_delta_q(vp8_writer *bc, int delta_q) {
990*fb1b10abSAndroid Build Coastguard Worker if (delta_q != 0) {
991*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
992*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, abs(delta_q), 4);
993*fb1b10abSAndroid Build Coastguard Worker
994*fb1b10abSAndroid Build Coastguard Worker if (delta_q < 0)
995*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
996*fb1b10abSAndroid Build Coastguard Worker else
997*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
998*fb1b10abSAndroid Build Coastguard Worker } else
999*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1000*fb1b10abSAndroid Build Coastguard Worker }
1001*fb1b10abSAndroid Build Coastguard Worker
vp8_pack_bitstream(VP8_COMP * cpi,unsigned char * dest,unsigned char * dest_end,size_t * size)1002*fb1b10abSAndroid Build Coastguard Worker void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest,
1003*fb1b10abSAndroid Build Coastguard Worker unsigned char *dest_end, size_t *size) {
1004*fb1b10abSAndroid Build Coastguard Worker int i, j;
1005*fb1b10abSAndroid Build Coastguard Worker VP8_HEADER oh;
1006*fb1b10abSAndroid Build Coastguard Worker VP8_COMMON *const pc = &cpi->common;
1007*fb1b10abSAndroid Build Coastguard Worker vp8_writer *const bc = cpi->bc;
1008*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &cpi->mb.e_mbd;
1009*fb1b10abSAndroid Build Coastguard Worker int extra_bytes_packed = 0;
1010*fb1b10abSAndroid Build Coastguard Worker
1011*fb1b10abSAndroid Build Coastguard Worker unsigned char *cx_data = dest;
1012*fb1b10abSAndroid Build Coastguard Worker unsigned char *cx_data_end = dest_end;
1013*fb1b10abSAndroid Build Coastguard Worker const int *mb_feature_data_bits;
1014*fb1b10abSAndroid Build Coastguard Worker
1015*fb1b10abSAndroid Build Coastguard Worker oh.show_frame = (int)pc->show_frame;
1016*fb1b10abSAndroid Build Coastguard Worker oh.type = (int)pc->frame_type;
1017*fb1b10abSAndroid Build Coastguard Worker oh.version = pc->version;
1018*fb1b10abSAndroid Build Coastguard Worker oh.first_partition_length_in_bytes = 0;
1019*fb1b10abSAndroid Build Coastguard Worker
1020*fb1b10abSAndroid Build Coastguard Worker mb_feature_data_bits = vp8_mb_feature_data_bits;
1021*fb1b10abSAndroid Build Coastguard Worker
1022*fb1b10abSAndroid Build Coastguard Worker bc[0].error = &pc->error;
1023*fb1b10abSAndroid Build Coastguard Worker
1024*fb1b10abSAndroid Build Coastguard Worker validate_buffer(cx_data, 3, cx_data_end, &pc->error);
1025*fb1b10abSAndroid Build Coastguard Worker cx_data += 3;
1026*fb1b10abSAndroid Build Coastguard Worker
1027*fb1b10abSAndroid Build Coastguard Worker #if defined(SECTIONBITS_OUTPUT)
1028*fb1b10abSAndroid Build Coastguard Worker Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
1029*fb1b10abSAndroid Build Coastguard Worker #endif
1030*fb1b10abSAndroid Build Coastguard Worker
1031*fb1b10abSAndroid Build Coastguard Worker /* every keyframe send startcode, width, height, scale factor, clamp
1032*fb1b10abSAndroid Build Coastguard Worker * and color type
1033*fb1b10abSAndroid Build Coastguard Worker */
1034*fb1b10abSAndroid Build Coastguard Worker if (oh.type == KEY_FRAME) {
1035*fb1b10abSAndroid Build Coastguard Worker int v;
1036*fb1b10abSAndroid Build Coastguard Worker
1037*fb1b10abSAndroid Build Coastguard Worker validate_buffer(cx_data, 7, cx_data_end, &pc->error);
1038*fb1b10abSAndroid Build Coastguard Worker
1039*fb1b10abSAndroid Build Coastguard Worker /* Start / synch code */
1040*fb1b10abSAndroid Build Coastguard Worker cx_data[0] = 0x9D;
1041*fb1b10abSAndroid Build Coastguard Worker cx_data[1] = 0x01;
1042*fb1b10abSAndroid Build Coastguard Worker cx_data[2] = 0x2a;
1043*fb1b10abSAndroid Build Coastguard Worker
1044*fb1b10abSAndroid Build Coastguard Worker /* Pack scale and frame size into 16 bits. Store it 8 bits at a time.
1045*fb1b10abSAndroid Build Coastguard Worker * https://tools.ietf.org/html/rfc6386
1046*fb1b10abSAndroid Build Coastguard Worker * 9.1. Uncompressed Data Chunk
1047*fb1b10abSAndroid Build Coastguard Worker * 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
1048*fb1b10abSAndroid Build Coastguard Worker * 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
1049*fb1b10abSAndroid Build Coastguard Worker */
1050*fb1b10abSAndroid Build Coastguard Worker v = (pc->horiz_scale << 14) | pc->Width;
1051*fb1b10abSAndroid Build Coastguard Worker cx_data[3] = v & 0xff;
1052*fb1b10abSAndroid Build Coastguard Worker cx_data[4] = v >> 8;
1053*fb1b10abSAndroid Build Coastguard Worker
1054*fb1b10abSAndroid Build Coastguard Worker v = (pc->vert_scale << 14) | pc->Height;
1055*fb1b10abSAndroid Build Coastguard Worker cx_data[5] = v & 0xff;
1056*fb1b10abSAndroid Build Coastguard Worker cx_data[6] = v >> 8;
1057*fb1b10abSAndroid Build Coastguard Worker
1058*fb1b10abSAndroid Build Coastguard Worker extra_bytes_packed = 7;
1059*fb1b10abSAndroid Build Coastguard Worker cx_data += extra_bytes_packed;
1060*fb1b10abSAndroid Build Coastguard Worker
1061*fb1b10abSAndroid Build Coastguard Worker vp8_start_encode(bc, cx_data, cx_data_end);
1062*fb1b10abSAndroid Build Coastguard Worker
1063*fb1b10abSAndroid Build Coastguard Worker /* signal clr type */
1064*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1065*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->clamp_type);
1066*fb1b10abSAndroid Build Coastguard Worker
1067*fb1b10abSAndroid Build Coastguard Worker } else {
1068*fb1b10abSAndroid Build Coastguard Worker vp8_start_encode(bc, cx_data, cx_data_end);
1069*fb1b10abSAndroid Build Coastguard Worker }
1070*fb1b10abSAndroid Build Coastguard Worker
1071*fb1b10abSAndroid Build Coastguard Worker /* Signal whether or not Segmentation is enabled */
1072*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, xd->segmentation_enabled);
1073*fb1b10abSAndroid Build Coastguard Worker
1074*fb1b10abSAndroid Build Coastguard Worker /* Indicate which features are enabled */
1075*fb1b10abSAndroid Build Coastguard Worker if (xd->segmentation_enabled) {
1076*fb1b10abSAndroid Build Coastguard Worker /* Signal whether or not the segmentation map is being updated. */
1077*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, xd->update_mb_segmentation_map);
1078*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, xd->update_mb_segmentation_data);
1079*fb1b10abSAndroid Build Coastguard Worker
1080*fb1b10abSAndroid Build Coastguard Worker if (xd->update_mb_segmentation_data) {
1081*fb1b10abSAndroid Build Coastguard Worker signed char Data;
1082*fb1b10abSAndroid Build Coastguard Worker
1083*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, xd->mb_segment_abs_delta);
1084*fb1b10abSAndroid Build Coastguard Worker
1085*fb1b10abSAndroid Build Coastguard Worker /* For each segmentation feature (Quant and loop filter level) */
1086*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MB_LVL_MAX; ++i) {
1087*fb1b10abSAndroid Build Coastguard Worker /* For each of the segments */
1088*fb1b10abSAndroid Build Coastguard Worker for (j = 0; j < MAX_MB_SEGMENTS; ++j) {
1089*fb1b10abSAndroid Build Coastguard Worker Data = xd->segment_feature_data[i][j];
1090*fb1b10abSAndroid Build Coastguard Worker
1091*fb1b10abSAndroid Build Coastguard Worker /* Frame level data */
1092*fb1b10abSAndroid Build Coastguard Worker if (Data) {
1093*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
1094*fb1b10abSAndroid Build Coastguard Worker
1095*fb1b10abSAndroid Build Coastguard Worker if (Data < 0) {
1096*fb1b10abSAndroid Build Coastguard Worker Data = -Data;
1097*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
1098*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
1099*fb1b10abSAndroid Build Coastguard Worker } else {
1100*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
1101*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1102*fb1b10abSAndroid Build Coastguard Worker }
1103*fb1b10abSAndroid Build Coastguard Worker } else
1104*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1105*fb1b10abSAndroid Build Coastguard Worker }
1106*fb1b10abSAndroid Build Coastguard Worker }
1107*fb1b10abSAndroid Build Coastguard Worker }
1108*fb1b10abSAndroid Build Coastguard Worker
1109*fb1b10abSAndroid Build Coastguard Worker if (xd->update_mb_segmentation_map) {
1110*fb1b10abSAndroid Build Coastguard Worker /* Write the probs used to decode the segment id for each mb */
1111*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) {
1112*fb1b10abSAndroid Build Coastguard Worker int Data = xd->mb_segment_tree_probs[i];
1113*fb1b10abSAndroid Build Coastguard Worker
1114*fb1b10abSAndroid Build Coastguard Worker if (Data != 255) {
1115*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
1116*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, Data, 8);
1117*fb1b10abSAndroid Build Coastguard Worker } else
1118*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1119*fb1b10abSAndroid Build Coastguard Worker }
1120*fb1b10abSAndroid Build Coastguard Worker }
1121*fb1b10abSAndroid Build Coastguard Worker }
1122*fb1b10abSAndroid Build Coastguard Worker
1123*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->filter_type);
1124*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->filter_level, 6);
1125*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->sharpness_level, 3);
1126*fb1b10abSAndroid Build Coastguard Worker
1127*fb1b10abSAndroid Build Coastguard Worker /* Write out loop filter deltas applied at the MB level based on mode
1128*fb1b10abSAndroid Build Coastguard Worker * or ref frame (if they are enabled).
1129*fb1b10abSAndroid Build Coastguard Worker */
1130*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled);
1131*fb1b10abSAndroid Build Coastguard Worker
1132*fb1b10abSAndroid Build Coastguard Worker if (xd->mode_ref_lf_delta_enabled) {
1133*fb1b10abSAndroid Build Coastguard Worker /* Do the deltas need to be updated */
1134*fb1b10abSAndroid Build Coastguard Worker int send_update =
1135*fb1b10abSAndroid Build Coastguard Worker xd->mode_ref_lf_delta_update || cpi->oxcf.error_resilient_mode;
1136*fb1b10abSAndroid Build Coastguard Worker
1137*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, send_update);
1138*fb1b10abSAndroid Build Coastguard Worker if (send_update) {
1139*fb1b10abSAndroid Build Coastguard Worker int Data;
1140*fb1b10abSAndroid Build Coastguard Worker
1141*fb1b10abSAndroid Build Coastguard Worker /* Send update */
1142*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_REF_LF_DELTAS; ++i) {
1143*fb1b10abSAndroid Build Coastguard Worker Data = xd->ref_lf_deltas[i];
1144*fb1b10abSAndroid Build Coastguard Worker
1145*fb1b10abSAndroid Build Coastguard Worker /* Frame level data */
1146*fb1b10abSAndroid Build Coastguard Worker if (xd->ref_lf_deltas[i] != xd->last_ref_lf_deltas[i] ||
1147*fb1b10abSAndroid Build Coastguard Worker cpi->oxcf.error_resilient_mode) {
1148*fb1b10abSAndroid Build Coastguard Worker xd->last_ref_lf_deltas[i] = xd->ref_lf_deltas[i];
1149*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
1150*fb1b10abSAndroid Build Coastguard Worker
1151*fb1b10abSAndroid Build Coastguard Worker if (Data > 0) {
1152*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, (Data & 0x3F), 6);
1153*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0); /* sign */
1154*fb1b10abSAndroid Build Coastguard Worker } else {
1155*fb1b10abSAndroid Build Coastguard Worker Data = -Data;
1156*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, (Data & 0x3F), 6);
1157*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1); /* sign */
1158*fb1b10abSAndroid Build Coastguard Worker }
1159*fb1b10abSAndroid Build Coastguard Worker } else
1160*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1161*fb1b10abSAndroid Build Coastguard Worker }
1162*fb1b10abSAndroid Build Coastguard Worker
1163*fb1b10abSAndroid Build Coastguard Worker /* Send update */
1164*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < MAX_MODE_LF_DELTAS; ++i) {
1165*fb1b10abSAndroid Build Coastguard Worker Data = xd->mode_lf_deltas[i];
1166*fb1b10abSAndroid Build Coastguard Worker
1167*fb1b10abSAndroid Build Coastguard Worker if (xd->mode_lf_deltas[i] != xd->last_mode_lf_deltas[i] ||
1168*fb1b10abSAndroid Build Coastguard Worker cpi->oxcf.error_resilient_mode) {
1169*fb1b10abSAndroid Build Coastguard Worker xd->last_mode_lf_deltas[i] = xd->mode_lf_deltas[i];
1170*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1);
1171*fb1b10abSAndroid Build Coastguard Worker
1172*fb1b10abSAndroid Build Coastguard Worker if (Data > 0) {
1173*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, (Data & 0x3F), 6);
1174*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0); /* sign */
1175*fb1b10abSAndroid Build Coastguard Worker } else {
1176*fb1b10abSAndroid Build Coastguard Worker Data = -Data;
1177*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, (Data & 0x3F), 6);
1178*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 1); /* sign */
1179*fb1b10abSAndroid Build Coastguard Worker }
1180*fb1b10abSAndroid Build Coastguard Worker } else
1181*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, 0);
1182*fb1b10abSAndroid Build Coastguard Worker }
1183*fb1b10abSAndroid Build Coastguard Worker }
1184*fb1b10abSAndroid Build Coastguard Worker }
1185*fb1b10abSAndroid Build Coastguard Worker
1186*fb1b10abSAndroid Build Coastguard Worker /* signal here is multi token partition is enabled */
1187*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->multi_token_partition, 2);
1188*fb1b10abSAndroid Build Coastguard Worker
1189*fb1b10abSAndroid Build Coastguard Worker /* Frame Qbaseline quantizer index */
1190*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->base_qindex, 7);
1191*fb1b10abSAndroid Build Coastguard Worker
1192*fb1b10abSAndroid Build Coastguard Worker /* Transmit Dc, Second order and Uv quantizer delta information */
1193*fb1b10abSAndroid Build Coastguard Worker put_delta_q(bc, pc->y1dc_delta_q);
1194*fb1b10abSAndroid Build Coastguard Worker put_delta_q(bc, pc->y2dc_delta_q);
1195*fb1b10abSAndroid Build Coastguard Worker put_delta_q(bc, pc->y2ac_delta_q);
1196*fb1b10abSAndroid Build Coastguard Worker put_delta_q(bc, pc->uvdc_delta_q);
1197*fb1b10abSAndroid Build Coastguard Worker put_delta_q(bc, pc->uvac_delta_q);
1198*fb1b10abSAndroid Build Coastguard Worker
1199*fb1b10abSAndroid Build Coastguard Worker /* When there is a key frame all reference buffers are updated using
1200*fb1b10abSAndroid Build Coastguard Worker * the new key frame
1201*fb1b10abSAndroid Build Coastguard Worker */
1202*fb1b10abSAndroid Build Coastguard Worker if (pc->frame_type != KEY_FRAME) {
1203*fb1b10abSAndroid Build Coastguard Worker /* Should the GF or ARF be updated using the transmitted frame
1204*fb1b10abSAndroid Build Coastguard Worker * or buffer
1205*fb1b10abSAndroid Build Coastguard Worker */
1206*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->refresh_golden_frame);
1207*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->refresh_alt_ref_frame);
1208*fb1b10abSAndroid Build Coastguard Worker
1209*fb1b10abSAndroid Build Coastguard Worker /* If not being updated from current frame should either GF or ARF
1210*fb1b10abSAndroid Build Coastguard Worker * be updated from another buffer
1211*fb1b10abSAndroid Build Coastguard Worker */
1212*fb1b10abSAndroid Build Coastguard Worker if (!pc->refresh_golden_frame)
1213*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
1214*fb1b10abSAndroid Build Coastguard Worker
1215*fb1b10abSAndroid Build Coastguard Worker if (!pc->refresh_alt_ref_frame)
1216*fb1b10abSAndroid Build Coastguard Worker vp8_write_literal(bc, pc->copy_buffer_to_arf, 2);
1217*fb1b10abSAndroid Build Coastguard Worker
1218*fb1b10abSAndroid Build Coastguard Worker /* Indicate reference frame sign bias for Golden and ARF frames
1219*fb1b10abSAndroid Build Coastguard Worker * (always 0 for last frame buffer)
1220*fb1b10abSAndroid Build Coastguard Worker */
1221*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
1222*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
1223*fb1b10abSAndroid Build Coastguard Worker }
1224*fb1b10abSAndroid Build Coastguard Worker
1225*fb1b10abSAndroid Build Coastguard Worker #if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
1226*fb1b10abSAndroid Build Coastguard Worker if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) {
1227*fb1b10abSAndroid Build Coastguard Worker if (pc->frame_type == KEY_FRAME) {
1228*fb1b10abSAndroid Build Coastguard Worker pc->refresh_entropy_probs = 1;
1229*fb1b10abSAndroid Build Coastguard Worker } else {
1230*fb1b10abSAndroid Build Coastguard Worker pc->refresh_entropy_probs = 0;
1231*fb1b10abSAndroid Build Coastguard Worker }
1232*fb1b10abSAndroid Build Coastguard Worker }
1233*fb1b10abSAndroid Build Coastguard Worker #endif
1234*fb1b10abSAndroid Build Coastguard Worker
1235*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->refresh_entropy_probs);
1236*fb1b10abSAndroid Build Coastguard Worker
1237*fb1b10abSAndroid Build Coastguard Worker if (pc->frame_type != KEY_FRAME) vp8_write_bit(bc, pc->refresh_last_frame);
1238*fb1b10abSAndroid Build Coastguard Worker
1239*fb1b10abSAndroid Build Coastguard Worker vpx_clear_system_state();
1240*fb1b10abSAndroid Build Coastguard Worker
1241*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
1242*fb1b10abSAndroid Build Coastguard Worker pack_coef_probs(cpi);
1243*fb1b10abSAndroid Build Coastguard Worker #else
1244*fb1b10abSAndroid Build Coastguard Worker if (pc->refresh_entropy_probs == 0) {
1245*fb1b10abSAndroid Build Coastguard Worker /* save a copy for later refresh */
1246*fb1b10abSAndroid Build Coastguard Worker pc->lfc = pc->fc;
1247*fb1b10abSAndroid Build Coastguard Worker }
1248*fb1b10abSAndroid Build Coastguard Worker
1249*fb1b10abSAndroid Build Coastguard Worker vp8_update_coef_probs(cpi);
1250*fb1b10abSAndroid Build Coastguard Worker #endif
1251*fb1b10abSAndroid Build Coastguard Worker
1252*fb1b10abSAndroid Build Coastguard Worker /* Write out the mb_no_coeff_skip flag */
1253*fb1b10abSAndroid Build Coastguard Worker vp8_write_bit(bc, pc->mb_no_coeff_skip);
1254*fb1b10abSAndroid Build Coastguard Worker
1255*fb1b10abSAndroid Build Coastguard Worker if (pc->frame_type == KEY_FRAME) {
1256*fb1b10abSAndroid Build Coastguard Worker write_kfmodes(cpi);
1257*fb1b10abSAndroid Build Coastguard Worker } else {
1258*fb1b10abSAndroid Build Coastguard Worker pack_inter_mode_mvs(cpi);
1259*fb1b10abSAndroid Build Coastguard Worker }
1260*fb1b10abSAndroid Build Coastguard Worker
1261*fb1b10abSAndroid Build Coastguard Worker vp8_stop_encode(bc);
1262*fb1b10abSAndroid Build Coastguard Worker
1263*fb1b10abSAndroid Build Coastguard Worker cx_data += bc->pos;
1264*fb1b10abSAndroid Build Coastguard Worker
1265*fb1b10abSAndroid Build Coastguard Worker oh.first_partition_length_in_bytes = cpi->bc->pos;
1266*fb1b10abSAndroid Build Coastguard Worker
1267*fb1b10abSAndroid Build Coastguard Worker /* update frame tag */
1268*fb1b10abSAndroid Build Coastguard Worker {
1269*fb1b10abSAndroid Build Coastguard Worker /* Pack partition size, show frame, version and frame type into to 24 bits.
1270*fb1b10abSAndroid Build Coastguard Worker * Store it 8 bits at a time.
1271*fb1b10abSAndroid Build Coastguard Worker * https://tools.ietf.org/html/rfc6386
1272*fb1b10abSAndroid Build Coastguard Worker * 9.1. Uncompressed Data Chunk
1273*fb1b10abSAndroid Build Coastguard Worker * The uncompressed data chunk comprises a common (for key frames and
1274*fb1b10abSAndroid Build Coastguard Worker * interframes) 3-byte frame tag that contains four fields, as follows:
1275*fb1b10abSAndroid Build Coastguard Worker *
1276*fb1b10abSAndroid Build Coastguard Worker * 1. A 1-bit frame type (0 for key frames, 1 for interframes).
1277*fb1b10abSAndroid Build Coastguard Worker *
1278*fb1b10abSAndroid Build Coastguard Worker * 2. A 3-bit version number (0 - 3 are defined as four different
1279*fb1b10abSAndroid Build Coastguard Worker * profiles with different decoding complexity; other values may be
1280*fb1b10abSAndroid Build Coastguard Worker * defined for future variants of the VP8 data format).
1281*fb1b10abSAndroid Build Coastguard Worker *
1282*fb1b10abSAndroid Build Coastguard Worker * 3. A 1-bit show_frame flag (0 when current frame is not for display,
1283*fb1b10abSAndroid Build Coastguard Worker * 1 when current frame is for display).
1284*fb1b10abSAndroid Build Coastguard Worker *
1285*fb1b10abSAndroid Build Coastguard Worker * 4. A 19-bit field containing the size of the first data partition in
1286*fb1b10abSAndroid Build Coastguard Worker * bytes
1287*fb1b10abSAndroid Build Coastguard Worker */
1288*fb1b10abSAndroid Build Coastguard Worker int v = (oh.first_partition_length_in_bytes << 5) | (oh.show_frame << 4) |
1289*fb1b10abSAndroid Build Coastguard Worker (oh.version << 1) | oh.type;
1290*fb1b10abSAndroid Build Coastguard Worker
1291*fb1b10abSAndroid Build Coastguard Worker dest[0] = v & 0xff;
1292*fb1b10abSAndroid Build Coastguard Worker dest[1] = (v >> 8) & 0xff;
1293*fb1b10abSAndroid Build Coastguard Worker dest[2] = v >> 16;
1294*fb1b10abSAndroid Build Coastguard Worker }
1295*fb1b10abSAndroid Build Coastguard Worker
1296*fb1b10abSAndroid Build Coastguard Worker *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc->pos;
1297*fb1b10abSAndroid Build Coastguard Worker
1298*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[0] = (unsigned int)*size;
1299*fb1b10abSAndroid Build Coastguard Worker
1300*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
1301*fb1b10abSAndroid Build Coastguard Worker {
1302*fb1b10abSAndroid Build Coastguard Worker const int num_part = (1 << pc->multi_token_partition);
1303*fb1b10abSAndroid Build Coastguard Worker unsigned char *dp = cpi->partition_d[0] + cpi->partition_sz[0];
1304*fb1b10abSAndroid Build Coastguard Worker
1305*fb1b10abSAndroid Build Coastguard Worker if (num_part > 1) {
1306*fb1b10abSAndroid Build Coastguard Worker /* write token part sizes (all but last) if more than 1 */
1307*fb1b10abSAndroid Build Coastguard Worker validate_buffer(dp, 3 * (num_part - 1), cpi->partition_d_end[0],
1308*fb1b10abSAndroid Build Coastguard Worker &pc->error);
1309*fb1b10abSAndroid Build Coastguard Worker
1310*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[0] += 3 * (num_part - 1);
1311*fb1b10abSAndroid Build Coastguard Worker
1312*fb1b10abSAndroid Build Coastguard Worker for (i = 1; i < num_part; ++i) {
1313*fb1b10abSAndroid Build Coastguard Worker write_partition_size(dp, cpi->partition_sz[i]);
1314*fb1b10abSAndroid Build Coastguard Worker dp += 3;
1315*fb1b10abSAndroid Build Coastguard Worker }
1316*fb1b10abSAndroid Build Coastguard Worker }
1317*fb1b10abSAndroid Build Coastguard Worker
1318*fb1b10abSAndroid Build Coastguard Worker if (!cpi->output_partition) {
1319*fb1b10abSAndroid Build Coastguard Worker /* concatenate partition buffers */
1320*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_part; ++i) {
1321*fb1b10abSAndroid Build Coastguard Worker memmove(dp, cpi->partition_d[i + 1], cpi->partition_sz[i + 1]);
1322*fb1b10abSAndroid Build Coastguard Worker cpi->partition_d[i + 1] = dp;
1323*fb1b10abSAndroid Build Coastguard Worker dp += cpi->partition_sz[i + 1];
1324*fb1b10abSAndroid Build Coastguard Worker }
1325*fb1b10abSAndroid Build Coastguard Worker }
1326*fb1b10abSAndroid Build Coastguard Worker
1327*fb1b10abSAndroid Build Coastguard Worker /* update total size */
1328*fb1b10abSAndroid Build Coastguard Worker *size = 0;
1329*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < num_part + 1; ++i) {
1330*fb1b10abSAndroid Build Coastguard Worker *size += cpi->partition_sz[i];
1331*fb1b10abSAndroid Build Coastguard Worker }
1332*fb1b10abSAndroid Build Coastguard Worker }
1333*fb1b10abSAndroid Build Coastguard Worker #else
1334*fb1b10abSAndroid Build Coastguard Worker if (pc->multi_token_partition != ONE_PARTITION) {
1335*fb1b10abSAndroid Build Coastguard Worker int num_part = 1 << pc->multi_token_partition;
1336*fb1b10abSAndroid Build Coastguard Worker
1337*fb1b10abSAndroid Build Coastguard Worker /* partition size table at the end of first partition */
1338*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[0] += 3 * (num_part - 1);
1339*fb1b10abSAndroid Build Coastguard Worker *size += 3 * (num_part - 1);
1340*fb1b10abSAndroid Build Coastguard Worker
1341*fb1b10abSAndroid Build Coastguard Worker validate_buffer(cx_data, 3 * (num_part - 1), cx_data_end, &pc->error);
1342*fb1b10abSAndroid Build Coastguard Worker
1343*fb1b10abSAndroid Build Coastguard Worker for (i = 1; i < num_part + 1; ++i) {
1344*fb1b10abSAndroid Build Coastguard Worker cpi->bc[i].error = &pc->error;
1345*fb1b10abSAndroid Build Coastguard Worker }
1346*fb1b10abSAndroid Build Coastguard Worker
1347*fb1b10abSAndroid Build Coastguard Worker pack_tokens_into_partitions(cpi, cx_data + 3 * (num_part - 1), cx_data_end,
1348*fb1b10abSAndroid Build Coastguard Worker num_part);
1349*fb1b10abSAndroid Build Coastguard Worker
1350*fb1b10abSAndroid Build Coastguard Worker for (i = 1; i < num_part; ++i) {
1351*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[i] = cpi->bc[i].pos;
1352*fb1b10abSAndroid Build Coastguard Worker write_partition_size(cx_data, cpi->partition_sz[i]);
1353*fb1b10abSAndroid Build Coastguard Worker cx_data += 3;
1354*fb1b10abSAndroid Build Coastguard Worker *size += cpi->partition_sz[i]; /* add to total */
1355*fb1b10abSAndroid Build Coastguard Worker }
1356*fb1b10abSAndroid Build Coastguard Worker
1357*fb1b10abSAndroid Build Coastguard Worker /* add last partition to total size */
1358*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[i] = cpi->bc[i].pos;
1359*fb1b10abSAndroid Build Coastguard Worker *size += cpi->partition_sz[i];
1360*fb1b10abSAndroid Build Coastguard Worker } else {
1361*fb1b10abSAndroid Build Coastguard Worker bc[1].error = &pc->error;
1362*fb1b10abSAndroid Build Coastguard Worker
1363*fb1b10abSAndroid Build Coastguard Worker vp8_start_encode(&cpi->bc[1], cx_data, cx_data_end);
1364*fb1b10abSAndroid Build Coastguard Worker
1365*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
1366*fb1b10abSAndroid Build Coastguard Worker if (vpx_atomic_load_acquire(&cpi->b_multi_threaded)) {
1367*fb1b10abSAndroid Build Coastguard Worker pack_mb_row_tokens(cpi, &cpi->bc[1]);
1368*fb1b10abSAndroid Build Coastguard Worker } else {
1369*fb1b10abSAndroid Build Coastguard Worker vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
1370*fb1b10abSAndroid Build Coastguard Worker }
1371*fb1b10abSAndroid Build Coastguard Worker #else
1372*fb1b10abSAndroid Build Coastguard Worker vp8_pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
1373*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_MULTITHREAD
1374*fb1b10abSAndroid Build Coastguard Worker
1375*fb1b10abSAndroid Build Coastguard Worker vp8_stop_encode(&cpi->bc[1]);
1376*fb1b10abSAndroid Build Coastguard Worker
1377*fb1b10abSAndroid Build Coastguard Worker *size += cpi->bc[1].pos;
1378*fb1b10abSAndroid Build Coastguard Worker cpi->partition_sz[1] = cpi->bc[1].pos;
1379*fb1b10abSAndroid Build Coastguard Worker }
1380*fb1b10abSAndroid Build Coastguard Worker #endif
1381*fb1b10abSAndroid Build Coastguard Worker }
1382