xref: /aosp_15_r20/external/libvpx/vp8/encoder/bitstream.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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