1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker *
5*abb65b4bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker *
8*abb65b4bSAndroid Build Coastguard Worker * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker *
11*abb65b4bSAndroid Build Coastguard Worker * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker *
15*abb65b4bSAndroid Build Coastguard Worker * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker * without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker *
19*abb65b4bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker */
31*abb65b4bSAndroid Build Coastguard Worker
32*abb65b4bSAndroid Build Coastguard Worker #include "oapv_def.h"
33*abb65b4bSAndroid Build Coastguard Worker
imgb_to_block(oapv_imgb_t * imgb,int c,int x_l,int y_l,int w_l,int h_l,s16 * block)34*abb65b4bSAndroid Build Coastguard Worker static void imgb_to_block(oapv_imgb_t *imgb, int c, int x_l, int y_l, int w_l, int h_l, s16 *block)
35*abb65b4bSAndroid Build Coastguard Worker {
36*abb65b4bSAndroid Build Coastguard Worker u8 *src, *dst;
37*abb65b4bSAndroid Build Coastguard Worker int i, sft_hor, sft_ver;
38*abb65b4bSAndroid Build Coastguard Worker int bd = OAPV_CS_GET_BYTE_DEPTH(imgb->cs);
39*abb65b4bSAndroid Build Coastguard Worker
40*abb65b4bSAndroid Build Coastguard Worker if(c == 0) {
41*abb65b4bSAndroid Build Coastguard Worker sft_hor = sft_ver = 0;
42*abb65b4bSAndroid Build Coastguard Worker }
43*abb65b4bSAndroid Build Coastguard Worker else {
44*abb65b4bSAndroid Build Coastguard Worker u8 cfi = color_format_to_chroma_format_idc(OAPV_CS_GET_FORMAT(imgb->cs));
45*abb65b4bSAndroid Build Coastguard Worker sft_hor = get_chroma_sft_w(cfi);
46*abb65b4bSAndroid Build Coastguard Worker sft_ver = get_chroma_sft_h(cfi);
47*abb65b4bSAndroid Build Coastguard Worker }
48*abb65b4bSAndroid Build Coastguard Worker
49*abb65b4bSAndroid Build Coastguard Worker src = ((u8 *)imgb->a[c]) + ((y_l >> sft_ver) * imgb->s[c]) + ((x_l * bd) >> sft_hor);
50*abb65b4bSAndroid Build Coastguard Worker dst = (u8 *)block;
51*abb65b4bSAndroid Build Coastguard Worker
52*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < (h_l); i++) {
53*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(dst, src, (w_l)*bd);
54*abb65b4bSAndroid Build Coastguard Worker
55*abb65b4bSAndroid Build Coastguard Worker src += imgb->s[c];
56*abb65b4bSAndroid Build Coastguard Worker dst += (w_l)*bd;
57*abb65b4bSAndroid Build Coastguard Worker }
58*abb65b4bSAndroid Build Coastguard Worker }
59*abb65b4bSAndroid Build Coastguard Worker
imgb_to_block_10bit(void * src,int blk_w,int blk_h,int s_src,int offset_src,int s_dst,void * dst)60*abb65b4bSAndroid Build Coastguard Worker static void imgb_to_block_10bit(void *src, int blk_w, int blk_h, int s_src, int offset_src, int s_dst, void *dst)
61*abb65b4bSAndroid Build Coastguard Worker {
62*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
63*abb65b4bSAndroid Build Coastguard Worker s16 *s = (s16 *)src;
64*abb65b4bSAndroid Build Coastguard Worker s16 *d = (s16 *)dst;
65*abb65b4bSAndroid Build Coastguard Worker
66*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
67*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
68*abb65b4bSAndroid Build Coastguard Worker d[w] = s[w] - mid_val;
69*abb65b4bSAndroid Build Coastguard Worker }
70*abb65b4bSAndroid Build Coastguard Worker s = (s16 *)(((u8 *)s) + s_src);
71*abb65b4bSAndroid Build Coastguard Worker d = (s16 *)(((u8 *)d) + s_dst);
72*abb65b4bSAndroid Build Coastguard Worker }
73*abb65b4bSAndroid Build Coastguard Worker }
74*abb65b4bSAndroid Build Coastguard Worker
imgb_to_block_p210_y(void * src,int blk_w,int blk_h,int s_src,int offset_src,int s_dst,void * dst)75*abb65b4bSAndroid Build Coastguard Worker static void imgb_to_block_p210_y(void *src, int blk_w, int blk_h, int s_src, int offset_src, int s_dst, void *dst)
76*abb65b4bSAndroid Build Coastguard Worker {
77*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
78*abb65b4bSAndroid Build Coastguard Worker u16 *s = (s16 *)src;
79*abb65b4bSAndroid Build Coastguard Worker s16 *d = (s16 *)dst;
80*abb65b4bSAndroid Build Coastguard Worker
81*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
82*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
83*abb65b4bSAndroid Build Coastguard Worker d[w] = (s16)(s[w] >> 6) - mid_val;
84*abb65b4bSAndroid Build Coastguard Worker }
85*abb65b4bSAndroid Build Coastguard Worker s = (u16 *)(((u8 *)s) + s_src);
86*abb65b4bSAndroid Build Coastguard Worker d = (s16 *)(((u8 *)d) + s_dst);
87*abb65b4bSAndroid Build Coastguard Worker }
88*abb65b4bSAndroid Build Coastguard Worker }
89*abb65b4bSAndroid Build Coastguard Worker
imgb_to_block_p210_uv(void * src,int blk_w,int blk_h,int s_src,int offset_src,int s_dst,void * dst)90*abb65b4bSAndroid Build Coastguard Worker static void imgb_to_block_p210_uv(void *src, int blk_w, int blk_h, int s_src, int offset_src, int s_dst, void *dst)
91*abb65b4bSAndroid Build Coastguard Worker {
92*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
93*abb65b4bSAndroid Build Coastguard Worker u16 *s = (u16 *)src + offset_src;
94*abb65b4bSAndroid Build Coastguard Worker s16 *d = (s16 *)dst;
95*abb65b4bSAndroid Build Coastguard Worker
96*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
97*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
98*abb65b4bSAndroid Build Coastguard Worker d[w] = (s16)(s[w * 2] >> 6) - mid_val;
99*abb65b4bSAndroid Build Coastguard Worker }
100*abb65b4bSAndroid Build Coastguard Worker s = (u16 *)(((u8 *)s) + s_src);
101*abb65b4bSAndroid Build Coastguard Worker d = (s16 *)(((u8 *)d) + s_dst);
102*abb65b4bSAndroid Build Coastguard Worker }
103*abb65b4bSAndroid Build Coastguard Worker }
104*abb65b4bSAndroid Build Coastguard Worker
imgb_to_block_p210(oapv_imgb_t * imgb,int c,int x_l,int y_l,int w_l,int h_l,s16 * block)105*abb65b4bSAndroid Build Coastguard Worker static void imgb_to_block_p210(oapv_imgb_t *imgb, int c, int x_l, int y_l, int w_l, int h_l, s16 *block)
106*abb65b4bSAndroid Build Coastguard Worker {
107*abb65b4bSAndroid Build Coastguard Worker u16 *src, *dst;
108*abb65b4bSAndroid Build Coastguard Worker int sft_hor, sft_ver, s_src;
109*abb65b4bSAndroid Build Coastguard Worker int bd = OAPV_CS_GET_BYTE_DEPTH(imgb->cs);
110*abb65b4bSAndroid Build Coastguard Worker int size_scale = 1;
111*abb65b4bSAndroid Build Coastguard Worker int tc = c;
112*abb65b4bSAndroid Build Coastguard Worker
113*abb65b4bSAndroid Build Coastguard Worker if(c == 0) {
114*abb65b4bSAndroid Build Coastguard Worker sft_hor = sft_ver = 0;
115*abb65b4bSAndroid Build Coastguard Worker }
116*abb65b4bSAndroid Build Coastguard Worker else {
117*abb65b4bSAndroid Build Coastguard Worker u8 cfi = color_format_to_chroma_format_idc(OAPV_CS_GET_FORMAT(imgb->cs));
118*abb65b4bSAndroid Build Coastguard Worker sft_hor = get_chroma_sft_w(cfi);
119*abb65b4bSAndroid Build Coastguard Worker sft_ver = get_chroma_sft_h(cfi);
120*abb65b4bSAndroid Build Coastguard Worker size_scale = 2;
121*abb65b4bSAndroid Build Coastguard Worker tc = 1;
122*abb65b4bSAndroid Build Coastguard Worker }
123*abb65b4bSAndroid Build Coastguard Worker
124*abb65b4bSAndroid Build Coastguard Worker s_src = imgb->s[tc] >> (bd > 1 ? 1 : 0);
125*abb65b4bSAndroid Build Coastguard Worker src = ((u16 *)imgb->a[tc]) + ((y_l >> sft_ver) * s_src) + ((x_l * size_scale) >> sft_hor);
126*abb65b4bSAndroid Build Coastguard Worker dst = (u16 *)block;
127*abb65b4bSAndroid Build Coastguard Worker
128*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < (h_l); i++) {
129*abb65b4bSAndroid Build Coastguard Worker for(int j = 0; j < (w_l); j++) {
130*abb65b4bSAndroid Build Coastguard Worker dst[j] = (src[j * size_scale + (c >> 1)] >> 6);
131*abb65b4bSAndroid Build Coastguard Worker }
132*abb65b4bSAndroid Build Coastguard Worker src += s_src;
133*abb65b4bSAndroid Build Coastguard Worker dst += w_l;
134*abb65b4bSAndroid Build Coastguard Worker }
135*abb65b4bSAndroid Build Coastguard Worker }
136*abb65b4bSAndroid Build Coastguard Worker
block_to_imgb_10bit(void * src,int blk_w,int blk_h,int s_src,int offset_dst,int s_dst,void * dst)137*abb65b4bSAndroid Build Coastguard Worker static void block_to_imgb_10bit(void *src, int blk_w, int blk_h, int s_src, int offset_dst, int s_dst, void *dst)
138*abb65b4bSAndroid Build Coastguard Worker {
139*abb65b4bSAndroid Build Coastguard Worker const int max_val = (1 << 10) - 1;
140*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
141*abb65b4bSAndroid Build Coastguard Worker s16 *s = (s16 *)src;
142*abb65b4bSAndroid Build Coastguard Worker u16 *d = (u16 *)dst;
143*abb65b4bSAndroid Build Coastguard Worker
144*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
145*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
146*abb65b4bSAndroid Build Coastguard Worker d[w] = oapv_clip3(0, max_val, s[w] + mid_val);
147*abb65b4bSAndroid Build Coastguard Worker }
148*abb65b4bSAndroid Build Coastguard Worker s = (s16 *)(((u8 *)s) + s_src);
149*abb65b4bSAndroid Build Coastguard Worker d = (u16 *)(((u8 *)d) + s_dst);
150*abb65b4bSAndroid Build Coastguard Worker }
151*abb65b4bSAndroid Build Coastguard Worker }
152*abb65b4bSAndroid Build Coastguard Worker
block_to_imgb_p210_y(void * src,int blk_w,int blk_h,int s_src,int offset_dst,int s_dst,void * dst)153*abb65b4bSAndroid Build Coastguard Worker static void block_to_imgb_p210_y(void *src, int blk_w, int blk_h, int s_src, int offset_dst, int s_dst, void *dst)
154*abb65b4bSAndroid Build Coastguard Worker {
155*abb65b4bSAndroid Build Coastguard Worker const int max_val = (1 << 10) - 1;
156*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
157*abb65b4bSAndroid Build Coastguard Worker s16 *s = (s16 *)src;
158*abb65b4bSAndroid Build Coastguard Worker u16 *d = (u16 *)dst;
159*abb65b4bSAndroid Build Coastguard Worker
160*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
161*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
162*abb65b4bSAndroid Build Coastguard Worker d[w] = oapv_clip3(0, max_val, s[w] + mid_val) << 6;
163*abb65b4bSAndroid Build Coastguard Worker }
164*abb65b4bSAndroid Build Coastguard Worker s = (s16 *)(((u8 *)s) + s_src);
165*abb65b4bSAndroid Build Coastguard Worker d = (u16 *)(((u8 *)d) + s_dst);
166*abb65b4bSAndroid Build Coastguard Worker }
167*abb65b4bSAndroid Build Coastguard Worker }
168*abb65b4bSAndroid Build Coastguard Worker
block_to_imgb_p210_uv(void * src,int blk_w,int blk_h,int s_src,int x_pel,int s_dst,void * dst)169*abb65b4bSAndroid Build Coastguard Worker static void block_to_imgb_p210_uv(void *src, int blk_w, int blk_h, int s_src, int x_pel, int s_dst, void *dst)
170*abb65b4bSAndroid Build Coastguard Worker {
171*abb65b4bSAndroid Build Coastguard Worker const int max_val = (1 << 10) - 1;
172*abb65b4bSAndroid Build Coastguard Worker const int mid_val = (1 << (10 - 1));
173*abb65b4bSAndroid Build Coastguard Worker s16 *s = (s16 *)src;
174*abb65b4bSAndroid Build Coastguard Worker
175*abb65b4bSAndroid Build Coastguard Worker // x_pel is x-offset value from left boundary of picture in unit of pixel.
176*abb65b4bSAndroid Build Coastguard Worker // the 'dst' address has calculated by
177*abb65b4bSAndroid Build Coastguard Worker // dst = (s16*)((u8*)origin + y_pel*s_dst) + x_pel;
178*abb65b4bSAndroid Build Coastguard Worker // in case of P210 color format,
179*abb65b4bSAndroid Build Coastguard Worker // since 's_dst' is byte size of stride including all U and V pixel values,
180*abb65b4bSAndroid Build Coastguard Worker // y-offset calculation is correct.
181*abb65b4bSAndroid Build Coastguard Worker // however, the adding only x_pel is not enough to address the correct pixel
182*abb65b4bSAndroid Build Coastguard Worker // position of U or V because U & V use the same buffer plane
183*abb65b4bSAndroid Build Coastguard Worker // in interleaved way,
184*abb65b4bSAndroid Build Coastguard Worker // so, the 'dst' address should be increased by 'x_pel' to address pixel
185*abb65b4bSAndroid Build Coastguard Worker // position correctly.
186*abb65b4bSAndroid Build Coastguard Worker u16 *d = (u16 *)dst + x_pel; // p210 pixel value needs 0~65535 range
187*abb65b4bSAndroid Build Coastguard Worker
188*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < blk_h; h++) {
189*abb65b4bSAndroid Build Coastguard Worker for(int w = 0; w < blk_w; w++) {
190*abb65b4bSAndroid Build Coastguard Worker d[w * 2] = ((u16)oapv_clip3(0, max_val, s[w] + mid_val)) << 6;
191*abb65b4bSAndroid Build Coastguard Worker }
192*abb65b4bSAndroid Build Coastguard Worker s = (s16 *)(((u8 *)s) + s_src);
193*abb65b4bSAndroid Build Coastguard Worker d = (u16 *)(((u8 *)d) + s_dst);
194*abb65b4bSAndroid Build Coastguard Worker }
195*abb65b4bSAndroid Build Coastguard Worker }
196*abb65b4bSAndroid Build Coastguard Worker
plus_mid_val(s16 * coef,int b_w,int b_h,int bit_depth)197*abb65b4bSAndroid Build Coastguard Worker static void plus_mid_val(s16 *coef, int b_w, int b_h, int bit_depth)
198*abb65b4bSAndroid Build Coastguard Worker {
199*abb65b4bSAndroid Build Coastguard Worker int mid_val = 1 << (bit_depth - 1);
200*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < b_h * b_w; i++) {
201*abb65b4bSAndroid Build Coastguard Worker coef[i] = oapv_clip3(0, (1 << bit_depth) - 1, coef[i] + mid_val);
202*abb65b4bSAndroid Build Coastguard Worker }
203*abb65b4bSAndroid Build Coastguard Worker }
204*abb65b4bSAndroid Build Coastguard Worker
copy_fi_to_finfo(oapv_fi_t * fi,int pbu_type,int group_id,oapv_frm_info_t * finfo)205*abb65b4bSAndroid Build Coastguard Worker static void copy_fi_to_finfo(oapv_fi_t *fi, int pbu_type, int group_id, oapv_frm_info_t *finfo)
206*abb65b4bSAndroid Build Coastguard Worker {
207*abb65b4bSAndroid Build Coastguard Worker finfo->w = (int)fi->frame_width; // casting to 'int' would be fine here
208*abb65b4bSAndroid Build Coastguard Worker finfo->h = (int)fi->frame_height; // casting to 'int' would be fine here
209*abb65b4bSAndroid Build Coastguard Worker finfo->cs = OAPV_CS_SET(chroma_format_idc_to_color_format(fi->chroma_format_idc), fi->bit_depth, 0);
210*abb65b4bSAndroid Build Coastguard Worker finfo->pbu_type = pbu_type;
211*abb65b4bSAndroid Build Coastguard Worker finfo->group_id = group_id;
212*abb65b4bSAndroid Build Coastguard Worker finfo->profile_idc = fi->profile_idc;
213*abb65b4bSAndroid Build Coastguard Worker finfo->level_idc = fi->level_idc;
214*abb65b4bSAndroid Build Coastguard Worker finfo->band_idc = fi->band_idc;
215*abb65b4bSAndroid Build Coastguard Worker finfo->chroma_format_idc = fi->chroma_format_idc;
216*abb65b4bSAndroid Build Coastguard Worker finfo->bit_depth = fi->bit_depth;
217*abb65b4bSAndroid Build Coastguard Worker finfo->capture_time_distance = fi->capture_time_distance;
218*abb65b4bSAndroid Build Coastguard Worker }
219*abb65b4bSAndroid Build Coastguard Worker
220*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
221*abb65b4bSAndroid Build Coastguard Worker // start of encoder code
222*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_ENCODER
223*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
224*abb65b4bSAndroid Build Coastguard Worker
enc_id_to_ctx(oapve_t id)225*abb65b4bSAndroid Build Coastguard Worker static oapve_ctx_t *enc_id_to_ctx(oapve_t id)
226*abb65b4bSAndroid Build Coastguard Worker {
227*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
228*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(id, NULL);
229*abb65b4bSAndroid Build Coastguard Worker ctx = (oapve_ctx_t *)id;
230*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv((ctx)->magic == OAPVE_MAGIC_CODE, NULL);
231*abb65b4bSAndroid Build Coastguard Worker return ctx;
232*abb65b4bSAndroid Build Coastguard Worker }
233*abb65b4bSAndroid Build Coastguard Worker
enc_ctx_alloc(void)234*abb65b4bSAndroid Build Coastguard Worker static oapve_ctx_t *enc_ctx_alloc(void)
235*abb65b4bSAndroid Build Coastguard Worker {
236*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
237*abb65b4bSAndroid Build Coastguard Worker ctx = (oapve_ctx_t *)oapv_malloc_fast(sizeof(oapve_ctx_t));
238*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx, NULL);
239*abb65b4bSAndroid Build Coastguard Worker oapv_mset_x64a(ctx, 0, sizeof(oapve_ctx_t));
240*abb65b4bSAndroid Build Coastguard Worker return ctx;
241*abb65b4bSAndroid Build Coastguard Worker }
242*abb65b4bSAndroid Build Coastguard Worker
enc_ctx_free(oapve_ctx_t * ctx)243*abb65b4bSAndroid Build Coastguard Worker static void enc_ctx_free(oapve_ctx_t *ctx)
244*abb65b4bSAndroid Build Coastguard Worker {
245*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(ctx);
246*abb65b4bSAndroid Build Coastguard Worker }
247*abb65b4bSAndroid Build Coastguard Worker
enc_core_alloc()248*abb65b4bSAndroid Build Coastguard Worker static oapve_core_t *enc_core_alloc()
249*abb65b4bSAndroid Build Coastguard Worker {
250*abb65b4bSAndroid Build Coastguard Worker oapve_core_t *core;
251*abb65b4bSAndroid Build Coastguard Worker core = (oapve_core_t *)oapv_malloc_fast(sizeof(oapve_core_t));
252*abb65b4bSAndroid Build Coastguard Worker
253*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(core, NULL);
254*abb65b4bSAndroid Build Coastguard Worker oapv_mset_x64a(core, 0, sizeof(oapve_core_t));
255*abb65b4bSAndroid Build Coastguard Worker
256*abb65b4bSAndroid Build Coastguard Worker return core;
257*abb65b4bSAndroid Build Coastguard Worker }
258*abb65b4bSAndroid Build Coastguard Worker
enc_core_free(oapve_core_t * core)259*abb65b4bSAndroid Build Coastguard Worker static void enc_core_free(oapve_core_t *core)
260*abb65b4bSAndroid Build Coastguard Worker {
261*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(core);
262*abb65b4bSAndroid Build Coastguard Worker }
263*abb65b4bSAndroid Build Coastguard Worker
enc_core_init(oapve_core_t * core,oapve_ctx_t * ctx,int tile_idx,int thread_idx)264*abb65b4bSAndroid Build Coastguard Worker static int enc_core_init(oapve_core_t *core, oapve_ctx_t *ctx, int tile_idx, int thread_idx)
265*abb65b4bSAndroid Build Coastguard Worker {
266*abb65b4bSAndroid Build Coastguard Worker core->tile_idx = tile_idx;
267*abb65b4bSAndroid Build Coastguard Worker core->ctx = ctx;
268*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
269*abb65b4bSAndroid Build Coastguard Worker }
270*abb65b4bSAndroid Build Coastguard Worker
enc_minus_mid_val(s16 * coef,int w_blk,int h_blk,int bit_depth)271*abb65b4bSAndroid Build Coastguard Worker static void enc_minus_mid_val(s16 *coef, int w_blk, int h_blk, int bit_depth)
272*abb65b4bSAndroid Build Coastguard Worker {
273*abb65b4bSAndroid Build Coastguard Worker int mid_val = 1 << (bit_depth - 1);
274*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < h_blk * w_blk; i++) {
275*abb65b4bSAndroid Build Coastguard Worker coef[i] -= mid_val;
276*abb65b4bSAndroid Build Coastguard Worker }
277*abb65b4bSAndroid Build Coastguard Worker }
278*abb65b4bSAndroid Build Coastguard Worker
enc_set_tile_info(oapve_tile_t * ti,int w_pel,int h_pel,int tile_w,int tile_h,int * num_tile_cols,int * num_tile_rows,int * num_tiles)279*abb65b4bSAndroid Build Coastguard Worker static int enc_set_tile_info(oapve_tile_t *ti, int w_pel, int h_pel, int tile_w,
280*abb65b4bSAndroid Build Coastguard Worker int tile_h, int *num_tile_cols, int *num_tile_rows, int *num_tiles)
281*abb65b4bSAndroid Build Coastguard Worker {
282*abb65b4bSAndroid Build Coastguard Worker (*num_tile_cols) = (w_pel + (tile_w - 1)) / tile_w;
283*abb65b4bSAndroid Build Coastguard Worker (*num_tile_rows) = (h_pel + (tile_h - 1)) / tile_h;
284*abb65b4bSAndroid Build Coastguard Worker (*num_tiles) = (*num_tile_cols) * (*num_tile_rows);
285*abb65b4bSAndroid Build Coastguard Worker
286*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < (*num_tiles); i++) {
287*abb65b4bSAndroid Build Coastguard Worker int tx = (i % (*num_tile_cols)) * tile_w;
288*abb65b4bSAndroid Build Coastguard Worker int ty = (i / (*num_tile_cols)) * tile_h;
289*abb65b4bSAndroid Build Coastguard Worker ti[i].x = tx;
290*abb65b4bSAndroid Build Coastguard Worker ti[i].y = ty;
291*abb65b4bSAndroid Build Coastguard Worker ti[i].w = tx + tile_w > w_pel ? w_pel - tx : tile_w;
292*abb65b4bSAndroid Build Coastguard Worker ti[i].h = ty + tile_h > h_pel ? h_pel - ty : tile_h;
293*abb65b4bSAndroid Build Coastguard Worker }
294*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
295*abb65b4bSAndroid Build Coastguard Worker }
296*abb65b4bSAndroid Build Coastguard Worker
enc_block(oapve_ctx_t * ctx,oapve_core_t * core,int log2_w,int log2_h,int c)297*abb65b4bSAndroid Build Coastguard Worker static double enc_block(oapve_ctx_t *ctx, oapve_core_t *core, int log2_w, int log2_h, int c)
298*abb65b4bSAndroid Build Coastguard Worker {
299*abb65b4bSAndroid Build Coastguard Worker int bit_depth = ctx->bit_depth;
300*abb65b4bSAndroid Build Coastguard Worker
301*abb65b4bSAndroid Build Coastguard Worker oapv_trans(ctx, core->coef, log2_w, log2_h, bit_depth);
302*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant[0](core->coef, core->qp[c], core->q_mat_enc[c], log2_w, log2_h, bit_depth, c ? 128 : 212);
303*abb65b4bSAndroid Build Coastguard Worker
304*abb65b4bSAndroid Build Coastguard Worker int prev_dc = core->prev_dc[c];
305*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = core->coef[0];
306*abb65b4bSAndroid Build Coastguard Worker core->coef[0] = core->coef[0] - prev_dc;
307*abb65b4bSAndroid Build Coastguard Worker
308*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
309*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(core->coef_rec, core->coef, sizeof(s16) * OAPV_BLK_D);
310*abb65b4bSAndroid Build Coastguard Worker core->coef_rec[0] = core->coef_rec[0] + prev_dc;
311*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](core->coef_rec, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
312*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](core->coef_rec, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
313*abb65b4bSAndroid Build Coastguard Worker }
314*abb65b4bSAndroid Build Coastguard Worker
315*abb65b4bSAndroid Build Coastguard Worker return 0;
316*abb65b4bSAndroid Build Coastguard Worker }
317*abb65b4bSAndroid Build Coastguard Worker
enc_block_rdo_slow(oapve_ctx_t * ctx,oapve_core_t * core,int log2_w,int log2_h,int c)318*abb65b4bSAndroid Build Coastguard Worker static double enc_block_rdo_slow(oapve_ctx_t *ctx, oapve_core_t *core, int log2_w, int log2_h, int c)
319*abb65b4bSAndroid Build Coastguard Worker {
320*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 recon[OAPV_BLK_D]) = { 0 };
321*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 coeff[OAPV_BLK_D]) = { 0 };
322*abb65b4bSAndroid Build Coastguard Worker int blk_w = 1 << log2_w;
323*abb65b4bSAndroid Build Coastguard Worker int blk_h = 1 << log2_h;
324*abb65b4bSAndroid Build Coastguard Worker int bit_depth = ctx->bit_depth;
325*abb65b4bSAndroid Build Coastguard Worker int qp = core->qp[c];
326*abb65b4bSAndroid Build Coastguard Worker s16 org[OAPV_BLK_D] = { 0 };
327*abb65b4bSAndroid Build Coastguard Worker s16 *best_coeff = core->coef;
328*abb65b4bSAndroid Build Coastguard Worker s16 *best_recon = core->coef_rec;
329*abb65b4bSAndroid Build Coastguard Worker int best_cost = INT_MAX;
330*abb65b4bSAndroid Build Coastguard Worker int zero_dist = 0;
331*abb65b4bSAndroid Build Coastguard Worker const u16 *scanp = oapv_tbl_scan;
332*abb65b4bSAndroid Build Coastguard Worker const int map_idx_diff[15] = { 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7 };
333*abb65b4bSAndroid Build Coastguard Worker
334*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(org, core->coef, sizeof(s16) * OAPV_BLK_D);
335*abb65b4bSAndroid Build Coastguard Worker oapv_trans(ctx, core->coef, log2_w, log2_h, bit_depth);
336*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(coeff, core->coef, sizeof(s16) * OAPV_BLK_D);
337*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant[0](coeff, qp, core->q_mat_enc[c], log2_w, log2_h, bit_depth, c ? 112 : 212);
338*abb65b4bSAndroid Build Coastguard Worker
339*abb65b4bSAndroid Build Coastguard Worker {
340*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(recon, coeff, sizeof(s16) * OAPV_BLK_D);
341*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
342*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](recon, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
343*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
344*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_coeff, coeff, sizeof(s16) * OAPV_BLK_D);
345*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
346*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, recon, sizeof(s16) * OAPV_BLK_D);
347*abb65b4bSAndroid Build Coastguard Worker }
348*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
349*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
350*abb65b4bSAndroid Build Coastguard Worker }
351*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
352*abb65b4bSAndroid Build Coastguard Worker }
353*abb65b4bSAndroid Build Coastguard Worker
354*abb65b4bSAndroid Build Coastguard Worker for(int itr = 0; itr < (c == 0 ? 2 : 1) && !zero_dist; itr++) {
355*abb65b4bSAndroid Build Coastguard Worker for(int j = 0; j < OAPV_BLK_D && !zero_dist; j++) {
356*abb65b4bSAndroid Build Coastguard Worker int best_idx = 0;
357*abb65b4bSAndroid Build Coastguard Worker s16 org_coef = coeff[scanp[j]];
358*abb65b4bSAndroid Build Coastguard Worker int adj_rng = c == 0 ? 13 : 5;
359*abb65b4bSAndroid Build Coastguard Worker if(org_coef == 0) {
360*abb65b4bSAndroid Build Coastguard Worker if(c == 0 && scanp[j] < 3) {
361*abb65b4bSAndroid Build Coastguard Worker adj_rng = 3;
362*abb65b4bSAndroid Build Coastguard Worker }
363*abb65b4bSAndroid Build Coastguard Worker else {
364*abb65b4bSAndroid Build Coastguard Worker continue;
365*abb65b4bSAndroid Build Coastguard Worker }
366*abb65b4bSAndroid Build Coastguard Worker }
367*abb65b4bSAndroid Build Coastguard Worker
368*abb65b4bSAndroid Build Coastguard Worker for(int i = 1; i < adj_rng && !zero_dist; i++) {
369*abb65b4bSAndroid Build Coastguard Worker if(i > 2) {
370*abb65b4bSAndroid Build Coastguard Worker if(best_idx == 0) {
371*abb65b4bSAndroid Build Coastguard Worker continue;
372*abb65b4bSAndroid Build Coastguard Worker }
373*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 1 && i % 2 == 0) {
374*abb65b4bSAndroid Build Coastguard Worker continue;
375*abb65b4bSAndroid Build Coastguard Worker }
376*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 0 && i % 2 == 1) {
377*abb65b4bSAndroid Build Coastguard Worker continue;
378*abb65b4bSAndroid Build Coastguard Worker }
379*abb65b4bSAndroid Build Coastguard Worker }
380*abb65b4bSAndroid Build Coastguard Worker
381*abb65b4bSAndroid Build Coastguard Worker s16 test_coef = org_coef + map_idx_diff[i];
382*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = test_coef;
383*abb65b4bSAndroid Build Coastguard Worker
384*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(recon, coeff, sizeof(s16) * OAPV_BLK_D);
385*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
386*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](recon, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
387*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
388*abb65b4bSAndroid Build Coastguard Worker
389*abb65b4bSAndroid Build Coastguard Worker if(cost < best_cost) {
390*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
391*abb65b4bSAndroid Build Coastguard Worker best_coeff[scanp[j]] = test_coef;
392*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
393*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, recon, sizeof(s16) * OAPV_BLK_D);
394*abb65b4bSAndroid Build Coastguard Worker }
395*abb65b4bSAndroid Build Coastguard Worker best_idx = i;
396*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
397*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
398*abb65b4bSAndroid Build Coastguard Worker }
399*abb65b4bSAndroid Build Coastguard Worker }
400*abb65b4bSAndroid Build Coastguard Worker else {
401*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = org_coef + map_idx_diff[best_idx];
402*abb65b4bSAndroid Build Coastguard Worker }
403*abb65b4bSAndroid Build Coastguard Worker }
404*abb65b4bSAndroid Build Coastguard Worker }
405*abb65b4bSAndroid Build Coastguard Worker }
406*abb65b4bSAndroid Build Coastguard Worker
407*abb65b4bSAndroid Build Coastguard Worker int curr_dc = best_coeff[0];
408*abb65b4bSAndroid Build Coastguard Worker best_coeff[0] -= core->prev_dc[c];
409*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = curr_dc;
410*abb65b4bSAndroid Build Coastguard Worker
411*abb65b4bSAndroid Build Coastguard Worker return best_cost;
412*abb65b4bSAndroid Build Coastguard Worker }
413*abb65b4bSAndroid Build Coastguard Worker
enc_block_rdo_medium(oapve_ctx_t * ctx,oapve_core_t * core,int log2_w,int log2_h,int c)414*abb65b4bSAndroid Build Coastguard Worker static double enc_block_rdo_medium(oapve_ctx_t *ctx, oapve_core_t *core, int log2_w, int log2_h, int c)
415*abb65b4bSAndroid Build Coastguard Worker {
416*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 org[OAPV_BLK_D]);
417*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 recon[OAPV_BLK_D]);
418*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 coeff[OAPV_BLK_D]);
419*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 tmp_buf[OAPV_BLK_D]);
420*abb65b4bSAndroid Build Coastguard Worker
421*abb65b4bSAndroid Build Coastguard Worker ALIGNED_32(int rec_ups[OAPV_BLK_D]);
422*abb65b4bSAndroid Build Coastguard Worker ALIGNED_32(int rec_tmp[OAPV_BLK_D]);
423*abb65b4bSAndroid Build Coastguard Worker
424*abb65b4bSAndroid Build Coastguard Worker int blk_w = 1 << log2_w;
425*abb65b4bSAndroid Build Coastguard Worker int blk_h = 1 << log2_h;
426*abb65b4bSAndroid Build Coastguard Worker int bit_depth = ctx->bit_depth;
427*abb65b4bSAndroid Build Coastguard Worker int qp = core->qp[c];
428*abb65b4bSAndroid Build Coastguard Worker
429*abb65b4bSAndroid Build Coastguard Worker s16 *best_coeff = core->coef;
430*abb65b4bSAndroid Build Coastguard Worker s16 *best_recon = core->coef_rec;
431*abb65b4bSAndroid Build Coastguard Worker
432*abb65b4bSAndroid Build Coastguard Worker int best_cost = INT_MAX;
433*abb65b4bSAndroid Build Coastguard Worker int zero_dist = 0;
434*abb65b4bSAndroid Build Coastguard Worker const u16 *scanp = oapv_tbl_scan;
435*abb65b4bSAndroid Build Coastguard Worker const int map_idx_diff[15] = { 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7 };
436*abb65b4bSAndroid Build Coastguard Worker
437*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(org, core->coef, sizeof(s16) * OAPV_BLK_D);
438*abb65b4bSAndroid Build Coastguard Worker oapv_trans(ctx, core->coef, log2_w, log2_h, bit_depth);
439*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(coeff, core->coef, sizeof(s16) * OAPV_BLK_D);
440*abb65b4bSAndroid Build Coastguard Worker
441*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant[0](coeff, qp, core->q_mat_enc[c], log2_w, log2_h, bit_depth, c ? 112 : 212);
442*abb65b4bSAndroid Build Coastguard Worker
443*abb65b4bSAndroid Build Coastguard Worker {
444*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(recon, coeff, sizeof(s16) * OAPV_BLK_D);
445*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
446*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_part[0](recon, tmp_buf, ITX_SHIFT1, 1 << log2_w);
447*abb65b4bSAndroid Build Coastguard Worker oapv_itx_get_wo_sft(tmp_buf, recon, rec_ups, ITX_SHIFT2(bit_depth), 1 << log2_h);
448*abb65b4bSAndroid Build Coastguard Worker
449*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
450*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_coeff, coeff, sizeof(s16) * OAPV_BLK_D);
451*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
452*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, recon, sizeof(s16) * OAPV_BLK_D);
453*abb65b4bSAndroid Build Coastguard Worker }
454*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
455*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
456*abb65b4bSAndroid Build Coastguard Worker }
457*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
458*abb65b4bSAndroid Build Coastguard Worker }
459*abb65b4bSAndroid Build Coastguard Worker
460*abb65b4bSAndroid Build Coastguard Worker for(int itr = 0; itr < (c == 0 ? 2 : 1) && !zero_dist; itr++) {
461*abb65b4bSAndroid Build Coastguard Worker for(int j = 0; j < OAPV_BLK_D && !zero_dist; j++) {
462*abb65b4bSAndroid Build Coastguard Worker int best_idx = 0;
463*abb65b4bSAndroid Build Coastguard Worker s16 org_coef = coeff[scanp[j]];
464*abb65b4bSAndroid Build Coastguard Worker int adj_rng = (c == 0 ? 13 : 5);
465*abb65b4bSAndroid Build Coastguard Worker if(org_coef == 0) {
466*abb65b4bSAndroid Build Coastguard Worker if(c == 0 && scanp[j] < 3) {
467*abb65b4bSAndroid Build Coastguard Worker adj_rng = 3;
468*abb65b4bSAndroid Build Coastguard Worker }
469*abb65b4bSAndroid Build Coastguard Worker else {
470*abb65b4bSAndroid Build Coastguard Worker continue;
471*abb65b4bSAndroid Build Coastguard Worker }
472*abb65b4bSAndroid Build Coastguard Worker }
473*abb65b4bSAndroid Build Coastguard Worker int q_step = 0;
474*abb65b4bSAndroid Build Coastguard Worker if(core->dq_shift[c] > 0) {
475*abb65b4bSAndroid Build Coastguard Worker q_step = (core->q_mat_dec[c][scanp[j]] + (1 << (core->dq_shift[c] - 1))) >> core->dq_shift[c];
476*abb65b4bSAndroid Build Coastguard Worker }
477*abb65b4bSAndroid Build Coastguard Worker else {
478*abb65b4bSAndroid Build Coastguard Worker q_step = (core->q_mat_dec[c][scanp[j]]) << (-core->dq_shift[c]);
479*abb65b4bSAndroid Build Coastguard Worker }
480*abb65b4bSAndroid Build Coastguard Worker
481*abb65b4bSAndroid Build Coastguard Worker for(int i = 1; i < adj_rng && !zero_dist; i++) {
482*abb65b4bSAndroid Build Coastguard Worker if(i > 2) {
483*abb65b4bSAndroid Build Coastguard Worker if(best_idx == 0) {
484*abb65b4bSAndroid Build Coastguard Worker continue;
485*abb65b4bSAndroid Build Coastguard Worker }
486*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 1 && i % 2 == 0) {
487*abb65b4bSAndroid Build Coastguard Worker continue;
488*abb65b4bSAndroid Build Coastguard Worker }
489*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 0 && i % 2 == 1) {
490*abb65b4bSAndroid Build Coastguard Worker continue;
491*abb65b4bSAndroid Build Coastguard Worker }
492*abb65b4bSAndroid Build Coastguard Worker }
493*abb65b4bSAndroid Build Coastguard Worker
494*abb65b4bSAndroid Build Coastguard Worker s16 test_coef = org_coef + map_idx_diff[i];
495*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = test_coef;
496*abb65b4bSAndroid Build Coastguard Worker int step_diff = q_step * map_idx_diff[i];
497*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_adj[0](rec_ups, rec_tmp, j, step_diff, 9);
498*abb65b4bSAndroid Build Coastguard Worker for(int k = 0; k < 64; k++) {
499*abb65b4bSAndroid Build Coastguard Worker recon[k] = (rec_tmp[k] + 512) >> 10;
500*abb65b4bSAndroid Build Coastguard Worker }
501*abb65b4bSAndroid Build Coastguard Worker
502*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
503*abb65b4bSAndroid Build Coastguard Worker if(cost < best_cost) {
504*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(rec_ups, rec_tmp, sizeof(int) * OAPV_BLK_D);
505*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
506*abb65b4bSAndroid Build Coastguard Worker best_coeff[scanp[j]] = test_coef;
507*abb65b4bSAndroid Build Coastguard Worker best_idx = i;
508*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
509*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
510*abb65b4bSAndroid Build Coastguard Worker }
511*abb65b4bSAndroid Build Coastguard Worker }
512*abb65b4bSAndroid Build Coastguard Worker else {
513*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = org_coef + map_idx_diff[best_idx];
514*abb65b4bSAndroid Build Coastguard Worker }
515*abb65b4bSAndroid Build Coastguard Worker }
516*abb65b4bSAndroid Build Coastguard Worker }
517*abb65b4bSAndroid Build Coastguard Worker }
518*abb65b4bSAndroid Build Coastguard Worker
519*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
520*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, best_coeff, sizeof(s16) * OAPV_BLK_D);
521*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](best_recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
522*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](best_recon, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
523*abb65b4bSAndroid Build Coastguard Worker }
524*abb65b4bSAndroid Build Coastguard Worker
525*abb65b4bSAndroid Build Coastguard Worker int curr_dc = best_coeff[0];
526*abb65b4bSAndroid Build Coastguard Worker best_coeff[0] -= core->prev_dc[c];
527*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = curr_dc;
528*abb65b4bSAndroid Build Coastguard Worker
529*abb65b4bSAndroid Build Coastguard Worker return best_cost;
530*abb65b4bSAndroid Build Coastguard Worker }
531*abb65b4bSAndroid Build Coastguard Worker
enc_block_rdo_placebo(oapve_ctx_t * ctx,oapve_core_t * core,int log2_w,int log2_h,int c)532*abb65b4bSAndroid Build Coastguard Worker static double enc_block_rdo_placebo(oapve_ctx_t *ctx, oapve_core_t *core, int log2_w, int log2_h, int c)
533*abb65b4bSAndroid Build Coastguard Worker {
534*abb65b4bSAndroid Build Coastguard Worker int blk_w = 1 << log2_w;
535*abb65b4bSAndroid Build Coastguard Worker int blk_h = 1 << log2_h;
536*abb65b4bSAndroid Build Coastguard Worker int bit_depth = ctx->bit_depth;
537*abb65b4bSAndroid Build Coastguard Worker int qp = core->qp[c];
538*abb65b4bSAndroid Build Coastguard Worker s16 *best_coeff = core->coef;
539*abb65b4bSAndroid Build Coastguard Worker s16 *best_recon = core->coef_rec;
540*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 org[OAPV_BLK_D]);
541*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 recon[OAPV_BLK_D]);
542*abb65b4bSAndroid Build Coastguard Worker ALIGNED_16(s16 coeff[OAPV_BLK_D]);
543*abb65b4bSAndroid Build Coastguard Worker int best_cost = INT_MAX;
544*abb65b4bSAndroid Build Coastguard Worker int zero_dist = 0;
545*abb65b4bSAndroid Build Coastguard Worker const u16 *scanp = oapv_tbl_scan;
546*abb65b4bSAndroid Build Coastguard Worker const int map_idx_diff[15] = { 0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7 };
547*abb65b4bSAndroid Build Coastguard Worker
548*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(org, core->coef, sizeof(s16) * OAPV_BLK_D);
549*abb65b4bSAndroid Build Coastguard Worker oapv_trans(ctx, core->coef, log2_w, log2_h, bit_depth);
550*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(coeff, core->coef, sizeof(s16) * OAPV_BLK_D);
551*abb65b4bSAndroid Build Coastguard Worker
552*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant[0](coeff, qp, core->q_mat_enc[c], log2_w, log2_h, bit_depth, c ? 112 : 212);
553*abb65b4bSAndroid Build Coastguard Worker
554*abb65b4bSAndroid Build Coastguard Worker {
555*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(recon, coeff, sizeof(s16) * OAPV_BLK_D);
556*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
557*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](recon, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
558*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
559*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_coeff, coeff, sizeof(s16) * OAPV_BLK_D);
560*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
561*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, recon, sizeof(s16) * OAPV_BLK_D);
562*abb65b4bSAndroid Build Coastguard Worker }
563*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
564*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
565*abb65b4bSAndroid Build Coastguard Worker }
566*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
567*abb65b4bSAndroid Build Coastguard Worker }
568*abb65b4bSAndroid Build Coastguard Worker
569*abb65b4bSAndroid Build Coastguard Worker for(int itr = 0; itr < (c == 0 ? 7 : 3) && !zero_dist; itr++) {
570*abb65b4bSAndroid Build Coastguard Worker for(int j = 0; j < OAPV_BLK_D && !zero_dist; j++) {
571*abb65b4bSAndroid Build Coastguard Worker int best_idx = 0;
572*abb65b4bSAndroid Build Coastguard Worker s16 org_coef = coeff[scanp[j]];
573*abb65b4bSAndroid Build Coastguard Worker int adj_rng = (c == 0 ? 15 : 5);
574*abb65b4bSAndroid Build Coastguard Worker if(org_coef == 0) {
575*abb65b4bSAndroid Build Coastguard Worker if(c == 0 && scanp[j] < 3) {
576*abb65b4bSAndroid Build Coastguard Worker adj_rng = 3;
577*abb65b4bSAndroid Build Coastguard Worker }
578*abb65b4bSAndroid Build Coastguard Worker else {
579*abb65b4bSAndroid Build Coastguard Worker continue;
580*abb65b4bSAndroid Build Coastguard Worker }
581*abb65b4bSAndroid Build Coastguard Worker }
582*abb65b4bSAndroid Build Coastguard Worker
583*abb65b4bSAndroid Build Coastguard Worker for(int i = 1; i < adj_rng && !zero_dist; i++) {
584*abb65b4bSAndroid Build Coastguard Worker if(i > 2) {
585*abb65b4bSAndroid Build Coastguard Worker if(best_idx == 0) {
586*abb65b4bSAndroid Build Coastguard Worker continue;
587*abb65b4bSAndroid Build Coastguard Worker }
588*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 1 && i % 2 == 0) {
589*abb65b4bSAndroid Build Coastguard Worker continue;
590*abb65b4bSAndroid Build Coastguard Worker }
591*abb65b4bSAndroid Build Coastguard Worker else if(best_idx % 2 == 0 && i % 2 == 1) {
592*abb65b4bSAndroid Build Coastguard Worker continue;
593*abb65b4bSAndroid Build Coastguard Worker }
594*abb65b4bSAndroid Build Coastguard Worker }
595*abb65b4bSAndroid Build Coastguard Worker
596*abb65b4bSAndroid Build Coastguard Worker s16 test_coef = org_coef + map_idx_diff[i];
597*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = test_coef;
598*abb65b4bSAndroid Build Coastguard Worker
599*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(recon, coeff, sizeof(s16) * OAPV_BLK_D);
600*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](recon, core->q_mat_dec[c], log2_w, log2_h, core->dq_shift[c]);
601*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](recon, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
602*abb65b4bSAndroid Build Coastguard Worker int cost = (int)ctx->fn_ssd[0](blk_w, blk_h, org, recon, blk_w, blk_w, bit_depth);
603*abb65b4bSAndroid Build Coastguard Worker
604*abb65b4bSAndroid Build Coastguard Worker if(cost < best_cost) {
605*abb65b4bSAndroid Build Coastguard Worker best_cost = cost;
606*abb65b4bSAndroid Build Coastguard Worker best_coeff[scanp[j]] = test_coef;
607*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
608*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(best_recon, recon, sizeof(s16) * OAPV_BLK_D);
609*abb65b4bSAndroid Build Coastguard Worker }
610*abb65b4bSAndroid Build Coastguard Worker best_idx = i;
611*abb65b4bSAndroid Build Coastguard Worker if(cost == 0) {
612*abb65b4bSAndroid Build Coastguard Worker zero_dist = 1;
613*abb65b4bSAndroid Build Coastguard Worker }
614*abb65b4bSAndroid Build Coastguard Worker }
615*abb65b4bSAndroid Build Coastguard Worker else {
616*abb65b4bSAndroid Build Coastguard Worker coeff[scanp[j]] = org_coef + map_idx_diff[best_idx];
617*abb65b4bSAndroid Build Coastguard Worker }
618*abb65b4bSAndroid Build Coastguard Worker }
619*abb65b4bSAndroid Build Coastguard Worker }
620*abb65b4bSAndroid Build Coastguard Worker }
621*abb65b4bSAndroid Build Coastguard Worker
622*abb65b4bSAndroid Build Coastguard Worker int curr_dc = best_coeff[0];
623*abb65b4bSAndroid Build Coastguard Worker best_coeff[0] -= core->prev_dc[c];
624*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = curr_dc;
625*abb65b4bSAndroid Build Coastguard Worker
626*abb65b4bSAndroid Build Coastguard Worker return best_cost;
627*abb65b4bSAndroid Build Coastguard Worker }
628*abb65b4bSAndroid Build Coastguard Worker
enc_read_param(oapve_ctx_t * ctx,oapve_param_t * param)629*abb65b4bSAndroid Build Coastguard Worker static int enc_read_param(oapve_ctx_t *ctx, oapve_param_t *param)
630*abb65b4bSAndroid Build Coastguard Worker {
631*abb65b4bSAndroid Build Coastguard Worker /* check input parameters */
632*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(param->w > 0 && param->h > 0, OAPV_ERR_INVALID_ARGUMENT);
633*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(param->qp >= MIN_QUANT && param->qp <= MAX_QUANT, OAPV_ERR_INVALID_ARGUMENT);
634*abb65b4bSAndroid Build Coastguard Worker
635*abb65b4bSAndroid Build Coastguard Worker ctx->qp[Y_C] = param->qp;
636*abb65b4bSAndroid Build Coastguard Worker ctx->qp[U_C] = param->qp + param->qp_cb_offset;
637*abb65b4bSAndroid Build Coastguard Worker ctx->qp[V_C] = param->qp + param->qp_cr_offset;
638*abb65b4bSAndroid Build Coastguard Worker ctx->qp[X_C] = param->qp;
639*abb65b4bSAndroid Build Coastguard Worker
640*abb65b4bSAndroid Build Coastguard Worker ctx->num_comp = get_num_comp(param->csp);
641*abb65b4bSAndroid Build Coastguard Worker
642*abb65b4bSAndroid Build Coastguard Worker if(param->preset == OAPV_PRESET_SLOW) {
643*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block = enc_block_rdo_slow;
644*abb65b4bSAndroid Build Coastguard Worker }
645*abb65b4bSAndroid Build Coastguard Worker else if(param->preset == OAPV_PRESET_PLACEBO) {
646*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block = enc_block_rdo_placebo;
647*abb65b4bSAndroid Build Coastguard Worker }
648*abb65b4bSAndroid Build Coastguard Worker else if(param->preset == OAPV_PRESET_MEDIUM) {
649*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block = enc_block_rdo_medium;
650*abb65b4bSAndroid Build Coastguard Worker }
651*abb65b4bSAndroid Build Coastguard Worker else {
652*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block = enc_block;
653*abb65b4bSAndroid Build Coastguard Worker }
654*abb65b4bSAndroid Build Coastguard Worker
655*abb65b4bSAndroid Build Coastguard Worker ctx->log2_block = OAPV_LOG2_BLK;
656*abb65b4bSAndroid Build Coastguard Worker
657*abb65b4bSAndroid Build Coastguard Worker /* set various value */
658*abb65b4bSAndroid Build Coastguard Worker ctx->w = ((ctx->param->w + (OAPV_MB_W - 1)) >> OAPV_LOG2_MB_W) << OAPV_LOG2_MB_W;
659*abb65b4bSAndroid Build Coastguard Worker ctx->h = ((ctx->param->h + (OAPV_MB_H - 1)) >> OAPV_LOG2_MB_H) << OAPV_LOG2_MB_H;
660*abb65b4bSAndroid Build Coastguard Worker
661*abb65b4bSAndroid Build Coastguard Worker int tile_w = ctx->param->tile_w_mb * OAPV_MB_W;
662*abb65b4bSAndroid Build Coastguard Worker int tile_h = ctx->param->tile_h_mb * OAPV_MB_H;
663*abb65b4bSAndroid Build Coastguard Worker enc_set_tile_info(ctx->tile, ctx->w, ctx->h, tile_w, tile_h, &ctx->num_tile_cols, &ctx->num_tile_rows, &ctx->num_tiles);
664*abb65b4bSAndroid Build Coastguard Worker
665*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
666*abb65b4bSAndroid Build Coastguard Worker }
667*abb65b4bSAndroid Build Coastguard Worker
enc_flush(oapve_ctx_t * ctx)668*abb65b4bSAndroid Build Coastguard Worker static void enc_flush(oapve_ctx_t *ctx)
669*abb65b4bSAndroid Build Coastguard Worker {
670*abb65b4bSAndroid Build Coastguard Worker // Release thread pool controller and created threads
671*abb65b4bSAndroid Build Coastguard Worker if(ctx->cdesc.threads >= 1) {
672*abb65b4bSAndroid Build Coastguard Worker if(ctx->tpool) {
673*abb65b4bSAndroid Build Coastguard Worker // thread controller instance is present
674*abb65b4bSAndroid Build Coastguard Worker // terminate the created thread
675*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
676*abb65b4bSAndroid Build Coastguard Worker if(ctx->thread_id[i]) {
677*abb65b4bSAndroid Build Coastguard Worker // valid thread instance
678*abb65b4bSAndroid Build Coastguard Worker ctx->tpool->release(&ctx->thread_id[i]);
679*abb65b4bSAndroid Build Coastguard Worker }
680*abb65b4bSAndroid Build Coastguard Worker }
681*abb65b4bSAndroid Build Coastguard Worker // dinitialize the tc
682*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_deinit(ctx->tpool);
683*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(ctx->tpool);
684*abb65b4bSAndroid Build Coastguard Worker ctx->tpool = NULL;
685*abb65b4bSAndroid Build Coastguard Worker }
686*abb65b4bSAndroid Build Coastguard Worker }
687*abb65b4bSAndroid Build Coastguard Worker
688*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_sync_obj_delete(&ctx->sync_obj);
689*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
690*abb65b4bSAndroid Build Coastguard Worker enc_core_free(ctx->core[i]);
691*abb65b4bSAndroid Build Coastguard Worker ctx->core[i] = NULL;
692*abb65b4bSAndroid Build Coastguard Worker }
693*abb65b4bSAndroid Build Coastguard Worker
694*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(ctx->tile[0].bs_buf);
695*abb65b4bSAndroid Build Coastguard Worker }
696*abb65b4bSAndroid Build Coastguard Worker
enc_ready(oapve_ctx_t * ctx)697*abb65b4bSAndroid Build Coastguard Worker static int enc_ready(oapve_ctx_t *ctx)
698*abb65b4bSAndroid Build Coastguard Worker {
699*abb65b4bSAndroid Build Coastguard Worker oapve_core_t *core = NULL;
700*abb65b4bSAndroid Build Coastguard Worker int ret = OAPV_OK;
701*abb65b4bSAndroid Build Coastguard Worker oapv_assert(ctx->core[0] == NULL);
702*abb65b4bSAndroid Build Coastguard Worker
703*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
704*abb65b4bSAndroid Build Coastguard Worker core = enc_core_alloc();
705*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(core != NULL, ret, OAPV_ERR_OUT_OF_MEMORY, ERR);
706*abb65b4bSAndroid Build Coastguard Worker ctx->core[i] = core;
707*abb65b4bSAndroid Build Coastguard Worker }
708*abb65b4bSAndroid Build Coastguard Worker
709*abb65b4bSAndroid Build Coastguard Worker // initialize the threads to NULL
710*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < OAPV_MAX_THREADS; i++) {
711*abb65b4bSAndroid Build Coastguard Worker ctx->thread_id[i] = 0;
712*abb65b4bSAndroid Build Coastguard Worker }
713*abb65b4bSAndroid Build Coastguard Worker
714*abb65b4bSAndroid Build Coastguard Worker // get the context synchronization handle
715*abb65b4bSAndroid Build Coastguard Worker ctx->sync_obj = oapv_tpool_sync_obj_create();
716*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->sync_obj != NULL, ret, OAPV_ERR_UNKNOWN, ERR);
717*abb65b4bSAndroid Build Coastguard Worker
718*abb65b4bSAndroid Build Coastguard Worker if(ctx->cdesc.threads >= 1) {
719*abb65b4bSAndroid Build Coastguard Worker ctx->tpool = oapv_malloc(sizeof(oapv_tpool_t));
720*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_init(ctx->tpool, ctx->cdesc.threads);
721*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
722*abb65b4bSAndroid Build Coastguard Worker ctx->thread_id[i] = ctx->tpool->create(ctx->tpool, i);
723*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->thread_id[i] != NULL, ret, OAPV_ERR_UNKNOWN, ERR);
724*abb65b4bSAndroid Build Coastguard Worker }
725*abb65b4bSAndroid Build Coastguard Worker }
726*abb65b4bSAndroid Build Coastguard Worker
727*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < OAPV_MAX_TILES; i++) {
728*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].stat = ENC_TILE_STAT_NOT_ENCODED;
729*abb65b4bSAndroid Build Coastguard Worker }
730*abb65b4bSAndroid Build Coastguard Worker ctx->tile[0].bs_buf = (u8 *)oapv_malloc(ctx->cdesc.max_bs_buf_size);
731*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->tile[0].bs_buf, ret, OAPV_ERR_UNKNOWN, ERR);
732*abb65b4bSAndroid Build Coastguard Worker
733*abb65b4bSAndroid Build Coastguard Worker ctx->rc_param.alpha = OAPV_RC_ALPHA;
734*abb65b4bSAndroid Build Coastguard Worker ctx->rc_param.beta = OAPV_RC_BETA;
735*abb65b4bSAndroid Build Coastguard Worker
736*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
737*abb65b4bSAndroid Build Coastguard Worker ERR:
738*abb65b4bSAndroid Build Coastguard Worker
739*abb65b4bSAndroid Build Coastguard Worker enc_flush(ctx);
740*abb65b4bSAndroid Build Coastguard Worker
741*abb65b4bSAndroid Build Coastguard Worker return ret;
742*abb65b4bSAndroid Build Coastguard Worker }
743*abb65b4bSAndroid Build Coastguard Worker
enc_tile_comp(oapv_bs_t * bs,oapve_tile_t * tile,oapve_ctx_t * ctx,oapve_core_t * core,int c,int s_org,void * org,int s_rec,void * rec)744*abb65b4bSAndroid Build Coastguard Worker static int enc_tile_comp(oapv_bs_t *bs, oapve_tile_t *tile, oapve_ctx_t *ctx, oapve_core_t *core, int c, int s_org, void *org, int s_rec, void *rec)
745*abb65b4bSAndroid Build Coastguard Worker {
746*abb65b4bSAndroid Build Coastguard Worker int mb_h, mb_w, mb_y, mb_x, blk_x, blk_y;
747*abb65b4bSAndroid Build Coastguard Worker s16 *o16 = NULL, *r16 = NULL;
748*abb65b4bSAndroid Build Coastguard Worker
749*abb65b4bSAndroid Build Coastguard Worker u8 *bs_cur = oapv_bsw_sink(bs);
750*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(bsw_is_align8(bs), OAPV_ERR_MALFORMED_BITSTREAM);
751*abb65b4bSAndroid Build Coastguard Worker
752*abb65b4bSAndroid Build Coastguard Worker mb_w = OAPV_MB_W >> ctx->comp_sft[c][0];
753*abb65b4bSAndroid Build Coastguard Worker mb_h = OAPV_MB_H >> ctx->comp_sft[c][1];
754*abb65b4bSAndroid Build Coastguard Worker
755*abb65b4bSAndroid Build Coastguard Worker int tile_le = tile->x >> ctx->comp_sft[c][0];
756*abb65b4bSAndroid Build Coastguard Worker int tile_ri = (tile->w >> ctx->comp_sft[c][0]) + tile_le;
757*abb65b4bSAndroid Build Coastguard Worker int tile_to = tile->y >> ctx->comp_sft[c][1];
758*abb65b4bSAndroid Build Coastguard Worker int tile_bo = (tile->h >> ctx->comp_sft[c][1]) + tile_to;
759*abb65b4bSAndroid Build Coastguard Worker
760*abb65b4bSAndroid Build Coastguard Worker for(mb_y = tile_to; mb_y < tile_bo; mb_y += mb_h) {
761*abb65b4bSAndroid Build Coastguard Worker for(mb_x = tile_le; mb_x < tile_ri; mb_x += mb_w) {
762*abb65b4bSAndroid Build Coastguard Worker for(blk_y = mb_y; blk_y < (mb_y + mb_h); blk_y += OAPV_BLK_H) {
763*abb65b4bSAndroid Build Coastguard Worker for(blk_x = mb_x; blk_x < (mb_x + mb_w); blk_x += OAPV_BLK_W) {
764*abb65b4bSAndroid Build Coastguard Worker o16 = (s16 *)((u8 *)org + blk_y * s_org) + blk_x;
765*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block[c](o16, OAPV_BLK_W, OAPV_BLK_H, s_org, blk_x, (OAPV_BLK_W << 1), core->coef);
766*abb65b4bSAndroid Build Coastguard Worker
767*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block(ctx, core, OAPV_LOG2_BLK_W, OAPV_LOG2_BLK_H, c);
768*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_dc_coeff(ctx, core, bs, core->coef[0], c);
769*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_ac_coeff(ctx, core, bs, core->coef, 0, c);
770*abb65b4bSAndroid Build Coastguard Worker DUMP_COEF(core->coef, OAPV_BLK_D, blk_x, blk_y, c);
771*abb65b4bSAndroid Build Coastguard Worker
772*abb65b4bSAndroid Build Coastguard Worker if(rec != NULL) {
773*abb65b4bSAndroid Build Coastguard Worker r16 = (s16 *)((u8 *)rec + blk_y * s_rec) + blk_x;
774*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[c](core->coef_rec, OAPV_BLK_W, OAPV_BLK_H, (OAPV_BLK_W << 1), blk_x, s_rec, r16);
775*abb65b4bSAndroid Build Coastguard Worker }
776*abb65b4bSAndroid Build Coastguard Worker }
777*abb65b4bSAndroid Build Coastguard Worker }
778*abb65b4bSAndroid Build Coastguard Worker }
779*abb65b4bSAndroid Build Coastguard Worker }
780*abb65b4bSAndroid Build Coastguard Worker
781*abb65b4bSAndroid Build Coastguard Worker /* byte align */
782*abb65b4bSAndroid Build Coastguard Worker while(!bsw_is_align8(bs)) {
783*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_write1(bs, 0);
784*abb65b4bSAndroid Build Coastguard Worker }
785*abb65b4bSAndroid Build Coastguard Worker
786*abb65b4bSAndroid Build Coastguard Worker /* de-init BSW */
787*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_deinit(bs);
788*abb65b4bSAndroid Build Coastguard Worker
789*abb65b4bSAndroid Build Coastguard Worker return (int)(bs->cur - bs_cur);
790*abb65b4bSAndroid Build Coastguard Worker }
791*abb65b4bSAndroid Build Coastguard Worker
enc_tile(oapve_ctx_t * ctx,oapve_core_t * core,oapve_tile_t * tile)792*abb65b4bSAndroid Build Coastguard Worker static int enc_tile(oapve_ctx_t *ctx, oapve_core_t *core, oapve_tile_t *tile)
793*abb65b4bSAndroid Build Coastguard Worker {
794*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs;
795*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_init(&bs, tile->bs_buf, tile->bs_buf_max, NULL);
796*abb65b4bSAndroid Build Coastguard Worker
797*abb65b4bSAndroid Build Coastguard Worker int qp = 0;
798*abb65b4bSAndroid Build Coastguard Worker if(ctx->param->rc_type != 0) {
799*abb65b4bSAndroid Build Coastguard Worker oapve_rc_get_qp(ctx, tile, ctx->qp[Y_C], &qp);
800*abb65b4bSAndroid Build Coastguard Worker oapv_assert(qp != 0);
801*abb65b4bSAndroid Build Coastguard Worker }
802*abb65b4bSAndroid Build Coastguard Worker else {
803*abb65b4bSAndroid Build Coastguard Worker qp = ctx->qp[Y_C];
804*abb65b4bSAndroid Build Coastguard Worker }
805*abb65b4bSAndroid Build Coastguard Worker
806*abb65b4bSAndroid Build Coastguard Worker tile->tile_size = 0;
807*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(0);
808*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_tile_size(&bs, tile->tile_size);
809*abb65b4bSAndroid Build Coastguard Worker oapve_set_tile_header(ctx, &tile->th, core->tile_idx, qp);
810*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_tile_header(ctx, &bs, &tile->th);
811*abb65b4bSAndroid Build Coastguard Worker
812*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < ctx->num_comp; c++) {
813*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
814*abb65b4bSAndroid Build Coastguard Worker core->qp[c] = tile->th.tile_qp[c];
815*abb65b4bSAndroid Build Coastguard Worker int qscale = oapv_quant_scale[core->qp[c] % 6];
816*abb65b4bSAndroid Build Coastguard Worker s32 scale_multiply_16 = (s32)(qscale << 4); // 15bit + 4bit
817*abb65b4bSAndroid Build Coastguard Worker for(int y = 0; y < OAPV_BLK_H; y++) {
818*abb65b4bSAndroid Build Coastguard Worker for(int x = 0; x < OAPV_BLK_W; x++) {
819*abb65b4bSAndroid Build Coastguard Worker core->q_mat_enc[c][cnt++] = scale_multiply_16 / ctx->fh.q_matrix[c][y][x];
820*abb65b4bSAndroid Build Coastguard Worker }
821*abb65b4bSAndroid Build Coastguard Worker }
822*abb65b4bSAndroid Build Coastguard Worker
823*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec || ctx->param->preset > OAPV_PRESET_MEDIUM) {
824*abb65b4bSAndroid Build Coastguard Worker core->dq_shift[c] = ctx->bit_depth - 2 - (core->qp[c] / 6);
825*abb65b4bSAndroid Build Coastguard Worker
826*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
827*abb65b4bSAndroid Build Coastguard Worker int dq_scale = oapv_tbl_dq_scale[core->qp[c] % 6];
828*abb65b4bSAndroid Build Coastguard Worker for(int y = 0; y < OAPV_BLK_H; y++) {
829*abb65b4bSAndroid Build Coastguard Worker for(int x = 0; x < OAPV_BLK_W; x++) {
830*abb65b4bSAndroid Build Coastguard Worker core->q_mat_dec[c][cnt++] = dq_scale * ctx->fh.q_matrix[c][y][x];
831*abb65b4bSAndroid Build Coastguard Worker }
832*abb65b4bSAndroid Build Coastguard Worker }
833*abb65b4bSAndroid Build Coastguard Worker }
834*abb65b4bSAndroid Build Coastguard Worker }
835*abb65b4bSAndroid Build Coastguard Worker
836*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < ctx->num_comp; c++) {
837*abb65b4bSAndroid Build Coastguard Worker core->prev_dc_ctx[c] = 20;
838*abb65b4bSAndroid Build Coastguard Worker core->prev_1st_ac_ctx[c] = 0;
839*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = 0;
840*abb65b4bSAndroid Build Coastguard Worker
841*abb65b4bSAndroid Build Coastguard Worker int tc, s_org, s_rec;
842*abb65b4bSAndroid Build Coastguard Worker s16 *org, *rec;
843*abb65b4bSAndroid Build Coastguard Worker
844*abb65b4bSAndroid Build Coastguard Worker if(OAPV_CS_GET_FORMAT(ctx->imgb->cs) == OAPV_CF_PLANAR2) {
845*abb65b4bSAndroid Build Coastguard Worker tc = c > 0 ? 1 : 0;
846*abb65b4bSAndroid Build Coastguard Worker org = ctx->imgb->a[tc];
847*abb65b4bSAndroid Build Coastguard Worker org += (c > 1) ? 1 : 0;
848*abb65b4bSAndroid Build Coastguard Worker s_org = ctx->imgb->s[tc];
849*abb65b4bSAndroid Build Coastguard Worker
850*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
851*abb65b4bSAndroid Build Coastguard Worker rec = ctx->rec->a[tc];
852*abb65b4bSAndroid Build Coastguard Worker rec += (c > 1) ? 1 : 0;
853*abb65b4bSAndroid Build Coastguard Worker s_rec = ctx->imgb->s[tc];
854*abb65b4bSAndroid Build Coastguard Worker }
855*abb65b4bSAndroid Build Coastguard Worker else {
856*abb65b4bSAndroid Build Coastguard Worker rec = NULL;
857*abb65b4bSAndroid Build Coastguard Worker s_rec = 0;
858*abb65b4bSAndroid Build Coastguard Worker }
859*abb65b4bSAndroid Build Coastguard Worker }
860*abb65b4bSAndroid Build Coastguard Worker else {
861*abb65b4bSAndroid Build Coastguard Worker org = ctx->imgb->a[c];
862*abb65b4bSAndroid Build Coastguard Worker s_org = ctx->imgb->s[c];
863*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
864*abb65b4bSAndroid Build Coastguard Worker rec = ctx->rec->a[c];
865*abb65b4bSAndroid Build Coastguard Worker s_rec = ctx->imgb->s[c];
866*abb65b4bSAndroid Build Coastguard Worker }
867*abb65b4bSAndroid Build Coastguard Worker else {
868*abb65b4bSAndroid Build Coastguard Worker rec = NULL;
869*abb65b4bSAndroid Build Coastguard Worker s_rec = 0;
870*abb65b4bSAndroid Build Coastguard Worker }
871*abb65b4bSAndroid Build Coastguard Worker }
872*abb65b4bSAndroid Build Coastguard Worker
873*abb65b4bSAndroid Build Coastguard Worker tile->th.tile_data_size[c] = enc_tile_comp(&bs, tile, ctx, core, c, s_org, org, s_rec, rec);
874*abb65b4bSAndroid Build Coastguard Worker }
875*abb65b4bSAndroid Build Coastguard Worker
876*abb65b4bSAndroid Build Coastguard Worker u32 bs_size = (int)(bs.cur - bs.beg);
877*abb65b4bSAndroid Build Coastguard Worker if(bs_size > tile->bs_buf_max) {
878*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR_OUT_OF_BS_BUF;
879*abb65b4bSAndroid Build Coastguard Worker }
880*abb65b4bSAndroid Build Coastguard Worker tile->bs_size = bs_size;
881*abb65b4bSAndroid Build Coastguard Worker
882*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs_th;
883*abb65b4bSAndroid Build Coastguard Worker bs_th.is_bin_count = 0;
884*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_init(&bs_th, tile->bs_buf, tile->bs_size, NULL);
885*abb65b4bSAndroid Build Coastguard Worker tile->tile_size = bs_size - OAPV_TILE_SIZE_LEN;
886*abb65b4bSAndroid Build Coastguard Worker
887*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(1);
888*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(0);
889*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_tile_size(&bs_th, tile->tile_size);
890*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_tile_header(ctx, &bs_th, &tile->th);
891*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(1);
892*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_deinit(&bs_th);
893*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
894*abb65b4bSAndroid Build Coastguard Worker }
895*abb65b4bSAndroid Build Coastguard Worker
enc_thread_tile(void * arg)896*abb65b4bSAndroid Build Coastguard Worker static int enc_thread_tile(void *arg)
897*abb65b4bSAndroid Build Coastguard Worker {
898*abb65b4bSAndroid Build Coastguard Worker oapve_core_t *core = (oapve_core_t *)arg;
899*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx = core->ctx;
900*abb65b4bSAndroid Build Coastguard Worker oapve_tile_t *tile = ctx->tile;
901*abb65b4bSAndroid Build Coastguard Worker int ret = OAPV_OK, i;
902*abb65b4bSAndroid Build Coastguard Worker
903*abb65b4bSAndroid Build Coastguard Worker while(1) {
904*abb65b4bSAndroid Build Coastguard Worker // find not encoded tile
905*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
906*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ctx->num_tiles; i++) {
907*abb65b4bSAndroid Build Coastguard Worker if(tile[i].stat == ENC_TILE_STAT_NOT_ENCODED) {
908*abb65b4bSAndroid Build Coastguard Worker tile[i].stat = ENC_TILE_STAT_ON_ENCODING;
909*abb65b4bSAndroid Build Coastguard Worker core->tile_idx = i;
910*abb65b4bSAndroid Build Coastguard Worker break;
911*abb65b4bSAndroid Build Coastguard Worker }
912*abb65b4bSAndroid Build Coastguard Worker }
913*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
914*abb65b4bSAndroid Build Coastguard Worker if(i == ctx->num_tiles) {
915*abb65b4bSAndroid Build Coastguard Worker break;
916*abb65b4bSAndroid Build Coastguard Worker }
917*abb65b4bSAndroid Build Coastguard Worker
918*abb65b4bSAndroid Build Coastguard Worker ret = enc_tile(ctx, core, &tile[core->tile_idx]);
919*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
920*abb65b4bSAndroid Build Coastguard Worker
921*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
922*abb65b4bSAndroid Build Coastguard Worker tile[core->tile_idx].stat = ENC_TILE_STAT_ENCODED;
923*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
924*abb65b4bSAndroid Build Coastguard Worker }
925*abb65b4bSAndroid Build Coastguard Worker ERR:
926*abb65b4bSAndroid Build Coastguard Worker return ret;
927*abb65b4bSAndroid Build Coastguard Worker }
928*abb65b4bSAndroid Build Coastguard Worker
enc_img_pad_p210(oapve_ctx_t * ctx,oapv_imgb_t * imgb)929*abb65b4bSAndroid Build Coastguard Worker static void enc_img_pad_p210(oapve_ctx_t *ctx, oapv_imgb_t *imgb)
930*abb65b4bSAndroid Build Coastguard Worker {
931*abb65b4bSAndroid Build Coastguard Worker if(ctx->w == ctx->param->w && ctx->h == ctx->param->h) {
932*abb65b4bSAndroid Build Coastguard Worker return;
933*abb65b4bSAndroid Build Coastguard Worker }
934*abb65b4bSAndroid Build Coastguard Worker
935*abb65b4bSAndroid Build Coastguard Worker if(ctx->w != ctx->param->w) {
936*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < imgb->np; c++) {
937*abb65b4bSAndroid Build Coastguard Worker int shift_w = 0;
938*abb65b4bSAndroid Build Coastguard Worker int shift_h = 0;
939*abb65b4bSAndroid Build Coastguard Worker
940*abb65b4bSAndroid Build Coastguard Worker int sw = ctx->param->w >> shift_w;
941*abb65b4bSAndroid Build Coastguard Worker int ew = ctx->w >> shift_w;
942*abb65b4bSAndroid Build Coastguard Worker int th = ctx->h >> shift_h;
943*abb65b4bSAndroid Build Coastguard Worker pel *dst = (pel *)imgb->a[c];
944*abb65b4bSAndroid Build Coastguard Worker pel src;
945*abb65b4bSAndroid Build Coastguard Worker
946*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < th; h++) {
947*abb65b4bSAndroid Build Coastguard Worker src = dst[sw - 1];
948*abb65b4bSAndroid Build Coastguard Worker for(int w = sw; w < ew; w++) {
949*abb65b4bSAndroid Build Coastguard Worker dst[w] = src;
950*abb65b4bSAndroid Build Coastguard Worker }
951*abb65b4bSAndroid Build Coastguard Worker dst += (imgb->s[c] >> 1);
952*abb65b4bSAndroid Build Coastguard Worker }
953*abb65b4bSAndroid Build Coastguard Worker }
954*abb65b4bSAndroid Build Coastguard Worker }
955*abb65b4bSAndroid Build Coastguard Worker
956*abb65b4bSAndroid Build Coastguard Worker if(ctx->h != ctx->param->h) {
957*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < imgb->np; c++) {
958*abb65b4bSAndroid Build Coastguard Worker int shift_w = 0;
959*abb65b4bSAndroid Build Coastguard Worker int shift_h = 0;
960*abb65b4bSAndroid Build Coastguard Worker
961*abb65b4bSAndroid Build Coastguard Worker int sh = ctx->param->h >> shift_h;
962*abb65b4bSAndroid Build Coastguard Worker int eh = ctx->h >> shift_h;
963*abb65b4bSAndroid Build Coastguard Worker int tw = ctx->w >> shift_w;
964*abb65b4bSAndroid Build Coastguard Worker pel *dst = ((pel *)imgb->a[c]) + sh * (imgb->s[c] >> 1);
965*abb65b4bSAndroid Build Coastguard Worker pel *src = dst - (imgb->s[c] >> 1);
966*abb65b4bSAndroid Build Coastguard Worker
967*abb65b4bSAndroid Build Coastguard Worker for(int h = sh; h < eh; h++) {
968*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(dst, src, sizeof(pel) * tw);
969*abb65b4bSAndroid Build Coastguard Worker dst += (imgb->s[c] >> 1);
970*abb65b4bSAndroid Build Coastguard Worker }
971*abb65b4bSAndroid Build Coastguard Worker }
972*abb65b4bSAndroid Build Coastguard Worker }
973*abb65b4bSAndroid Build Coastguard Worker }
enc_img_pad(oapve_ctx_t * ctx,oapv_imgb_t * imgb)974*abb65b4bSAndroid Build Coastguard Worker static void enc_img_pad(oapve_ctx_t *ctx, oapv_imgb_t *imgb)
975*abb65b4bSAndroid Build Coastguard Worker {
976*abb65b4bSAndroid Build Coastguard Worker if(ctx->w == ctx->param->w && ctx->h == ctx->param->h) {
977*abb65b4bSAndroid Build Coastguard Worker return;
978*abb65b4bSAndroid Build Coastguard Worker }
979*abb65b4bSAndroid Build Coastguard Worker
980*abb65b4bSAndroid Build Coastguard Worker if(ctx->w != ctx->param->w) {
981*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < imgb->np; c++) {
982*abb65b4bSAndroid Build Coastguard Worker int sw = ctx->param->w >> ctx->comp_sft[c][0];
983*abb65b4bSAndroid Build Coastguard Worker int ew = ctx->w >> ctx->comp_sft[c][0];
984*abb65b4bSAndroid Build Coastguard Worker int th = ctx->h >> ctx->comp_sft[c][1];
985*abb65b4bSAndroid Build Coastguard Worker pel *dst = (pel *)imgb->a[c];
986*abb65b4bSAndroid Build Coastguard Worker pel src;
987*abb65b4bSAndroid Build Coastguard Worker
988*abb65b4bSAndroid Build Coastguard Worker for(int h = 0; h < th; h++) {
989*abb65b4bSAndroid Build Coastguard Worker src = dst[sw - 1];
990*abb65b4bSAndroid Build Coastguard Worker for(int w = sw; w < ew; w++) {
991*abb65b4bSAndroid Build Coastguard Worker dst[w] = src;
992*abb65b4bSAndroid Build Coastguard Worker }
993*abb65b4bSAndroid Build Coastguard Worker dst += (imgb->s[c] >> 1);
994*abb65b4bSAndroid Build Coastguard Worker }
995*abb65b4bSAndroid Build Coastguard Worker }
996*abb65b4bSAndroid Build Coastguard Worker }
997*abb65b4bSAndroid Build Coastguard Worker
998*abb65b4bSAndroid Build Coastguard Worker if(ctx->h != ctx->param->h) {
999*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < imgb->np; c++) {
1000*abb65b4bSAndroid Build Coastguard Worker int sh = ctx->param->h >> ctx->comp_sft[c][1];
1001*abb65b4bSAndroid Build Coastguard Worker int eh = ctx->h >> ctx->comp_sft[c][1];
1002*abb65b4bSAndroid Build Coastguard Worker int tw = ctx->w >> ctx->comp_sft[c][0];
1003*abb65b4bSAndroid Build Coastguard Worker pel *dst = ((pel *)imgb->a[c]) + sh * (imgb->s[c] >> 1);
1004*abb65b4bSAndroid Build Coastguard Worker pel *src = dst - (imgb->s[c] >> 1);
1005*abb65b4bSAndroid Build Coastguard Worker
1006*abb65b4bSAndroid Build Coastguard Worker for(int h = sh; h < eh; h++) {
1007*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(dst, src, sizeof(pel) * tw);
1008*abb65b4bSAndroid Build Coastguard Worker dst += (imgb->s[c] >> 1);
1009*abb65b4bSAndroid Build Coastguard Worker }
1010*abb65b4bSAndroid Build Coastguard Worker }
1011*abb65b4bSAndroid Build Coastguard Worker }
1012*abb65b4bSAndroid Build Coastguard Worker }
1013*abb65b4bSAndroid Build Coastguard Worker
enc_frm_prepare(oapve_ctx_t * ctx,oapv_imgb_t * imgb_i,oapv_imgb_t * imgb_r)1014*abb65b4bSAndroid Build Coastguard Worker static int enc_frm_prepare(oapve_ctx_t *ctx, oapv_imgb_t *imgb_i, oapv_imgb_t *imgb_r)
1015*abb65b4bSAndroid Build Coastguard Worker {
1016*abb65b4bSAndroid Build Coastguard Worker ctx->cfi = color_format_to_chroma_format_idc(OAPV_CS_GET_FORMAT(imgb_i->cs));
1017*abb65b4bSAndroid Build Coastguard Worker ctx->num_comp = get_num_comp(ctx->cfi);
1018*abb65b4bSAndroid Build Coastguard Worker
1019*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[Y_C][0] = 0;
1020*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[Y_C][1] = 0;
1021*abb65b4bSAndroid Build Coastguard Worker for(int c = 1; c < ctx->num_comp; c++) {
1022*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[c][0] = get_chroma_sft_w(ctx->cfi);
1023*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[c][1] = get_chroma_sft_h(ctx->cfi);
1024*abb65b4bSAndroid Build Coastguard Worker }
1025*abb65b4bSAndroid Build Coastguard Worker
1026*abb65b4bSAndroid Build Coastguard Worker ctx->bit_depth = OAPV_CS_GET_BIT_DEPTH(imgb_i->cs);
1027*abb65b4bSAndroid Build Coastguard Worker
1028*abb65b4bSAndroid Build Coastguard Worker if(OAPV_CS_GET_FORMAT(imgb_i->cs) == OAPV_CF_PLANAR2) {
1029*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block_rc = imgb_to_block_p210;
1030*abb65b4bSAndroid Build Coastguard Worker
1031*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block[Y_C] = imgb_to_block_p210_y;
1032*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block[U_C] = imgb_to_block_p210_uv;
1033*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block[V_C] = imgb_to_block_p210_uv;
1034*abb65b4bSAndroid Build Coastguard Worker
1035*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[Y_C] = block_to_imgb_p210_y;
1036*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[U_C] = block_to_imgb_p210_uv;
1037*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[V_C] = block_to_imgb_p210_uv;
1038*abb65b4bSAndroid Build Coastguard Worker ctx->fn_img_pad = enc_img_pad_p210;
1039*abb65b4bSAndroid Build Coastguard Worker }
1040*abb65b4bSAndroid Build Coastguard Worker else {
1041*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block_rc = imgb_to_block;
1042*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_comp; i++) {
1043*abb65b4bSAndroid Build Coastguard Worker ctx->fn_imgb_to_block[i] = imgb_to_block_10bit;
1044*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[i] = block_to_imgb_10bit;
1045*abb65b4bSAndroid Build Coastguard Worker }
1046*abb65b4bSAndroid Build Coastguard Worker ctx->fn_img_pad = enc_img_pad;
1047*abb65b4bSAndroid Build Coastguard Worker }
1048*abb65b4bSAndroid Build Coastguard Worker
1049*abb65b4bSAndroid Build Coastguard Worker /* initialize bitstream container */
1050*abb65b4bSAndroid Build Coastguard Worker // oapv_bsw_init(&ctx->bs, bitb->addr, bitb->bsize, NULL); // TODO : remove
1051*abb65b4bSAndroid Build Coastguard Worker ctx->w = (imgb_i->aw[Y_C] > 0) ? imgb_i->aw[Y_C] : imgb_i->w[Y_C];
1052*abb65b4bSAndroid Build Coastguard Worker ctx->h = (imgb_i->ah[Y_C] > 0) ? imgb_i->ah[Y_C] : imgb_i->h[Y_C];
1053*abb65b4bSAndroid Build Coastguard Worker
1054*abb65b4bSAndroid Build Coastguard Worker ctx->fn_img_pad(ctx, imgb_i);
1055*abb65b4bSAndroid Build Coastguard Worker
1056*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_tiles; i++) {
1057*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].stat = ENC_TILE_STAT_NOT_ENCODED;
1058*abb65b4bSAndroid Build Coastguard Worker }
1059*abb65b4bSAndroid Build Coastguard Worker
1060*abb65b4bSAndroid Build Coastguard Worker ctx->imgb = imgb_i;
1061*abb65b4bSAndroid Build Coastguard Worker imgb_addref(ctx->imgb);
1062*abb65b4bSAndroid Build Coastguard Worker if(imgb_r != NULL) {
1063*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < ctx->num_comp; c++) {
1064*abb65b4bSAndroid Build Coastguard Worker imgb_r->w[c] = imgb_i->w[c];
1065*abb65b4bSAndroid Build Coastguard Worker imgb_r->h[c] = imgb_i->h[c];
1066*abb65b4bSAndroid Build Coastguard Worker imgb_r->x[c] = imgb_i->x[c];
1067*abb65b4bSAndroid Build Coastguard Worker imgb_r->y[c] = imgb_i->y[c];
1068*abb65b4bSAndroid Build Coastguard Worker }
1069*abb65b4bSAndroid Build Coastguard Worker ctx->rec = imgb_r;
1070*abb65b4bSAndroid Build Coastguard Worker imgb_addref(ctx->rec);
1071*abb65b4bSAndroid Build Coastguard Worker }
1072*abb65b4bSAndroid Build Coastguard Worker
1073*abb65b4bSAndroid Build Coastguard Worker int buf_size = ctx->cdesc.max_bs_buf_size / ctx->num_tiles;
1074*abb65b4bSAndroid Build Coastguard Worker ctx->tile[0].bs_buf_max = buf_size;
1075*abb65b4bSAndroid Build Coastguard Worker for(int i = 1; i < ctx->num_tiles; i++) {
1076*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].bs_buf = ctx->tile[i - 1].bs_buf + buf_size;
1077*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].bs_buf_max = buf_size;
1078*abb65b4bSAndroid Build Coastguard Worker }
1079*abb65b4bSAndroid Build Coastguard Worker
1080*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
1081*abb65b4bSAndroid Build Coastguard Worker ctx->core[i]->ctx = ctx;
1082*abb65b4bSAndroid Build Coastguard Worker ctx->core[i]->thread_idx = i;
1083*abb65b4bSAndroid Build Coastguard Worker }
1084*abb65b4bSAndroid Build Coastguard Worker
1085*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1086*abb65b4bSAndroid Build Coastguard Worker }
1087*abb65b4bSAndroid Build Coastguard Worker
enc_frm_finish(oapve_ctx_t * ctx,oapve_stat_t * stat)1088*abb65b4bSAndroid Build Coastguard Worker static int enc_frm_finish(oapve_ctx_t *ctx, oapve_stat_t *stat)
1089*abb65b4bSAndroid Build Coastguard Worker {
1090*abb65b4bSAndroid Build Coastguard Worker imgb_release(ctx->imgb);
1091*abb65b4bSAndroid Build Coastguard Worker if(ctx->rec) {
1092*abb65b4bSAndroid Build Coastguard Worker imgb_release(ctx->rec);
1093*abb65b4bSAndroid Build Coastguard Worker ctx->rec = NULL;
1094*abb65b4bSAndroid Build Coastguard Worker }
1095*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1096*abb65b4bSAndroid Build Coastguard Worker }
1097*abb65b4bSAndroid Build Coastguard Worker
enc_frame(oapve_ctx_t * ctx)1098*abb65b4bSAndroid Build Coastguard Worker static int enc_frame(oapve_ctx_t *ctx)
1099*abb65b4bSAndroid Build Coastguard Worker {
1100*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t *bs = &ctx->bs;
1101*abb65b4bSAndroid Build Coastguard Worker int ret = OAPV_OK;
1102*abb65b4bSAndroid Build Coastguard Worker
1103*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs_fh;
1104*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(&bs_fh, bs, sizeof(oapv_bs_t));
1105*abb65b4bSAndroid Build Coastguard Worker
1106*abb65b4bSAndroid Build Coastguard Worker /* write frame header */
1107*abb65b4bSAndroid Build Coastguard Worker oapve_set_frame_header(ctx, &ctx->fh);
1108*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_frame_header(bs, ctx, &ctx->fh);
1109*abb65b4bSAndroid Build Coastguard Worker
1110*abb65b4bSAndroid Build Coastguard Worker /* de-init BSW */
1111*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_deinit(bs);
1112*abb65b4bSAndroid Build Coastguard Worker
1113*abb65b4bSAndroid Build Coastguard Worker /* rc init */
1114*abb65b4bSAndroid Build Coastguard Worker u64 cost_sum = 0;
1115*abb65b4bSAndroid Build Coastguard Worker if(ctx->param->rc_type != 0) {
1116*abb65b4bSAndroid Build Coastguard Worker oapve_rc_get_tile_cost_thread(ctx, &cost_sum);
1117*abb65b4bSAndroid Build Coastguard Worker
1118*abb65b4bSAndroid Build Coastguard Worker double bits_pic = ((double)ctx->param->bitrate * 1000) / ((double)ctx->param->fps_num / ctx->param->fps_den);
1119*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_tiles; i++) {
1120*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].rc.target_bits_left = bits_pic * ctx->tile[i].rc.cost / cost_sum;
1121*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].rc.target_bits = ctx->tile[i].rc.target_bits_left;
1122*abb65b4bSAndroid Build Coastguard Worker }
1123*abb65b4bSAndroid Build Coastguard Worker
1124*abb65b4bSAndroid Build Coastguard Worker ctx->rc_param.lambda = oapve_rc_estimate_pic_lambda(ctx, cost_sum);
1125*abb65b4bSAndroid Build Coastguard Worker ctx->rc_param.qp = oapve_rc_estimate_pic_qp(ctx->rc_param.lambda);
1126*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < ctx->num_comp; c++) {
1127*abb65b4bSAndroid Build Coastguard Worker ctx->qp[c] = ctx->rc_param.qp;
1128*abb65b4bSAndroid Build Coastguard Worker if(c == 1) {
1129*abb65b4bSAndroid Build Coastguard Worker ctx->qp[c] += ctx->param->qp_cb_offset;
1130*abb65b4bSAndroid Build Coastguard Worker }
1131*abb65b4bSAndroid Build Coastguard Worker else if(c == 2) {
1132*abb65b4bSAndroid Build Coastguard Worker ctx->qp[c] += ctx->param->qp_cr_offset;
1133*abb65b4bSAndroid Build Coastguard Worker }
1134*abb65b4bSAndroid Build Coastguard Worker }
1135*abb65b4bSAndroid Build Coastguard Worker }
1136*abb65b4bSAndroid Build Coastguard Worker
1137*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_t *tpool = ctx->tpool;
1138*abb65b4bSAndroid Build Coastguard Worker int res, tidx = 0, thread_num1 = 0;
1139*abb65b4bSAndroid Build Coastguard Worker int parallel_task = (ctx->cdesc.threads > ctx->num_tiles) ? ctx->num_tiles : ctx->cdesc.threads;
1140*abb65b4bSAndroid Build Coastguard Worker
1141*abb65b4bSAndroid Build Coastguard Worker /* encode tiles ************************************/
1142*abb65b4bSAndroid Build Coastguard Worker for(tidx = 0; tidx < (parallel_task - 1); tidx++) {
1143*abb65b4bSAndroid Build Coastguard Worker tpool->run(ctx->thread_id[tidx], enc_thread_tile,
1144*abb65b4bSAndroid Build Coastguard Worker (void *)ctx->core[tidx]);
1145*abb65b4bSAndroid Build Coastguard Worker }
1146*abb65b4bSAndroid Build Coastguard Worker ret = enc_thread_tile((void *)ctx->core[tidx]);
1147*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1148*abb65b4bSAndroid Build Coastguard Worker
1149*abb65b4bSAndroid Build Coastguard Worker for(thread_num1 = 0; thread_num1 < parallel_task - 1; thread_num1++) {
1150*abb65b4bSAndroid Build Coastguard Worker res = tpool->join(ctx->thread_id[thread_num1], &ret);
1151*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(res == TPOOL_SUCCESS, ret, OAPV_ERR_FAILED_SYSCALL, ERR);
1152*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1153*abb65b4bSAndroid Build Coastguard Worker }
1154*abb65b4bSAndroid Build Coastguard Worker /****************************************************/
1155*abb65b4bSAndroid Build Coastguard Worker
1156*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_tiles; i++) {
1157*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(ctx->bs.cur, ctx->tile[i].bs_buf, ctx->tile[i].bs_size);
1158*abb65b4bSAndroid Build Coastguard Worker ctx->bs.cur = ctx->bs.cur + ctx->tile[i].bs_size;
1159*abb65b4bSAndroid Build Coastguard Worker ctx->fh.tile_size[i] = ctx->tile[i].bs_size - OAPV_TILE_SIZE_LEN;
1160*abb65b4bSAndroid Build Coastguard Worker }
1161*abb65b4bSAndroid Build Coastguard Worker
1162*abb65b4bSAndroid Build Coastguard Worker /* rewrite frame header */
1163*abb65b4bSAndroid Build Coastguard Worker if(ctx->fh.tile_size_present_in_fh_flag) {
1164*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_frame_header(&bs_fh, ctx, &ctx->fh);
1165*abb65b4bSAndroid Build Coastguard Worker }
1166*abb65b4bSAndroid Build Coastguard Worker if(ctx->param->rc_type != 0) {
1167*abb65b4bSAndroid Build Coastguard Worker oapve_rc_update_after_pic(ctx, cost_sum);
1168*abb65b4bSAndroid Build Coastguard Worker }
1169*abb65b4bSAndroid Build Coastguard Worker return ret;
1170*abb65b4bSAndroid Build Coastguard Worker
1171*abb65b4bSAndroid Build Coastguard Worker ERR:
1172*abb65b4bSAndroid Build Coastguard Worker return ret;
1173*abb65b4bSAndroid Build Coastguard Worker }
1174*abb65b4bSAndroid Build Coastguard Worker
enc_platform_init(oapve_ctx_t * ctx)1175*abb65b4bSAndroid Build Coastguard Worker static int enc_platform_init(oapve_ctx_t *ctx)
1176*abb65b4bSAndroid Build Coastguard Worker {
1177*abb65b4bSAndroid Build Coastguard Worker // default settings
1178*abb65b4bSAndroid Build Coastguard Worker ctx->fn_sad = oapv_tbl_fn_sad_16b;
1179*abb65b4bSAndroid Build Coastguard Worker ctx->fn_ssd = oapv_tbl_fn_ssd_16b;
1180*abb65b4bSAndroid Build Coastguard Worker ctx->fn_diff = oapv_tbl_fn_diff_16b;
1181*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_part = oapv_tbl_fn_itx_part;
1182*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx;
1183*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_adj = oapv_tbl_fn_itx_adj;
1184*abb65b4bSAndroid Build Coastguard Worker ctx->fn_txb = oapv_tbl_fn_tx;
1185*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant = oapv_tbl_fn_quant;
1186*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant;
1187*abb65b4bSAndroid Build Coastguard Worker ctx->fn_had8x8 = oapv_dc_removed_had8x8;
1188*abb65b4bSAndroid Build Coastguard Worker #if X86_SSE
1189*abb65b4bSAndroid Build Coastguard Worker int check_cpu, support_sse, support_avx2;
1190*abb65b4bSAndroid Build Coastguard Worker
1191*abb65b4bSAndroid Build Coastguard Worker check_cpu = oapv_check_cpu_info_x86();
1192*abb65b4bSAndroid Build Coastguard Worker support_sse = (check_cpu >> 0) & 1;
1193*abb65b4bSAndroid Build Coastguard Worker support_avx2 = (check_cpu >> 2) & 1;
1194*abb65b4bSAndroid Build Coastguard Worker
1195*abb65b4bSAndroid Build Coastguard Worker if(support_avx2) {
1196*abb65b4bSAndroid Build Coastguard Worker ctx->fn_ssd = oapv_tbl_fn_ssd_16b_avx;
1197*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_part = oapv_tbl_fn_itx_part_avx;
1198*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx_avx;
1199*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx_adj = oapv_tbl_fn_itx_adj_avx;
1200*abb65b4bSAndroid Build Coastguard Worker ctx->fn_txb = oapv_tbl_fn_txb_avx;
1201*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant = oapv_tbl_fn_quant_avx;
1202*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant_avx;
1203*abb65b4bSAndroid Build Coastguard Worker ctx->fn_had8x8 = oapv_dc_removed_had8x8_sse;
1204*abb65b4bSAndroid Build Coastguard Worker }
1205*abb65b4bSAndroid Build Coastguard Worker else if(support_sse) {
1206*abb65b4bSAndroid Build Coastguard Worker ctx->fn_ssd = oapv_tbl_fn_ssd_16b_sse;
1207*abb65b4bSAndroid Build Coastguard Worker ctx->fn_had8x8 = oapv_dc_removed_had8x8_sse;
1208*abb65b4bSAndroid Build Coastguard Worker }
1209*abb65b4bSAndroid Build Coastguard Worker #elif ARM_NEON
1210*abb65b4bSAndroid Build Coastguard Worker ctx->fn_ssd = oapv_tbl_fn_ssd_16b_neon;
1211*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx_neon;
1212*abb65b4bSAndroid Build Coastguard Worker ctx->fn_txb = oapv_tbl_fn_txb_neon;
1213*abb65b4bSAndroid Build Coastguard Worker ctx->fn_quant = oapv_tbl_fn_quant_neon;
1214*abb65b4bSAndroid Build Coastguard Worker ctx->fn_had8x8 = oapv_dc_removed_had8x8;
1215*abb65b4bSAndroid Build Coastguard Worker #endif
1216*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1217*abb65b4bSAndroid Build Coastguard Worker }
1218*abb65b4bSAndroid Build Coastguard Worker
oapve_create(oapve_cdesc_t * cdesc,int * err)1219*abb65b4bSAndroid Build Coastguard Worker oapve_t oapve_create(oapve_cdesc_t *cdesc, int *err)
1220*abb65b4bSAndroid Build Coastguard Worker {
1221*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
1222*abb65b4bSAndroid Build Coastguard Worker int ret;
1223*abb65b4bSAndroid Build Coastguard Worker
1224*abb65b4bSAndroid Build Coastguard Worker DUMP_CREATE(1);
1225*abb65b4bSAndroid Build Coastguard Worker /* memory allocation for ctx and core structure */
1226*abb65b4bSAndroid Build Coastguard Worker ctx = (oapve_ctx_t *)enc_ctx_alloc();
1227*abb65b4bSAndroid Build Coastguard Worker if(ctx != NULL) {
1228*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(&ctx->cdesc, cdesc, sizeof(oapve_cdesc_t));
1229*abb65b4bSAndroid Build Coastguard Worker ret = enc_platform_init(ctx);
1230*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(ret == OAPV_OK, ERR);
1231*abb65b4bSAndroid Build Coastguard Worker
1232*abb65b4bSAndroid Build Coastguard Worker ret = enc_ready(ctx);
1233*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(ret == OAPV_OK, ERR);
1234*abb65b4bSAndroid Build Coastguard Worker
1235*abb65b4bSAndroid Build Coastguard Worker /* set default value for ctx */
1236*abb65b4bSAndroid Build Coastguard Worker ctx->magic = OAPVE_MAGIC_CODE;
1237*abb65b4bSAndroid Build Coastguard Worker ctx->id = (oapve_t)ctx;
1238*abb65b4bSAndroid Build Coastguard Worker if(err) {
1239*abb65b4bSAndroid Build Coastguard Worker *err = OAPV_OK;
1240*abb65b4bSAndroid Build Coastguard Worker }
1241*abb65b4bSAndroid Build Coastguard Worker return (ctx->id);
1242*abb65b4bSAndroid Build Coastguard Worker }
1243*abb65b4bSAndroid Build Coastguard Worker else {
1244*abb65b4bSAndroid Build Coastguard Worker ret = OAPV_ERR;
1245*abb65b4bSAndroid Build Coastguard Worker }
1246*abb65b4bSAndroid Build Coastguard Worker ERR:
1247*abb65b4bSAndroid Build Coastguard Worker if(ctx) {
1248*abb65b4bSAndroid Build Coastguard Worker enc_ctx_free(ctx);
1249*abb65b4bSAndroid Build Coastguard Worker }
1250*abb65b4bSAndroid Build Coastguard Worker if(err) {
1251*abb65b4bSAndroid Build Coastguard Worker *err = ret;
1252*abb65b4bSAndroid Build Coastguard Worker }
1253*abb65b4bSAndroid Build Coastguard Worker return NULL;
1254*abb65b4bSAndroid Build Coastguard Worker }
1255*abb65b4bSAndroid Build Coastguard Worker
oapve_delete(oapve_t eid)1256*abb65b4bSAndroid Build Coastguard Worker void oapve_delete(oapve_t eid)
1257*abb65b4bSAndroid Build Coastguard Worker {
1258*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
1259*abb65b4bSAndroid Build Coastguard Worker
1260*abb65b4bSAndroid Build Coastguard Worker ctx = enc_id_to_ctx(eid);
1261*abb65b4bSAndroid Build Coastguard Worker oapv_assert_r(ctx);
1262*abb65b4bSAndroid Build Coastguard Worker
1263*abb65b4bSAndroid Build Coastguard Worker DUMP_DELETE();
1264*abb65b4bSAndroid Build Coastguard Worker enc_flush(ctx);
1265*abb65b4bSAndroid Build Coastguard Worker enc_ctx_free(ctx);
1266*abb65b4bSAndroid Build Coastguard Worker }
1267*abb65b4bSAndroid Build Coastguard Worker
oapve_encode(oapve_t eid,oapv_frms_t * ifrms,oapvm_t mid,oapv_bitb_t * bitb,oapve_stat_t * stat,oapv_frms_t * rfrms)1268*abb65b4bSAndroid Build Coastguard Worker int oapve_encode(oapve_t eid, oapv_frms_t *ifrms, oapvm_t mid, oapv_bitb_t *bitb, oapve_stat_t *stat, oapv_frms_t *rfrms)
1269*abb65b4bSAndroid Build Coastguard Worker {
1270*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
1271*abb65b4bSAndroid Build Coastguard Worker oapv_frm_t *frm;
1272*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t *bs;
1273*abb65b4bSAndroid Build Coastguard Worker int i, ret;
1274*abb65b4bSAndroid Build Coastguard Worker
1275*abb65b4bSAndroid Build Coastguard Worker ctx = enc_id_to_ctx(eid);
1276*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx != NULL && bitb->addr && bitb->bsize > 0, OAPV_ERR_INVALID_ARGUMENT);
1277*abb65b4bSAndroid Build Coastguard Worker
1278*abb65b4bSAndroid Build Coastguard Worker bs = &ctx->bs;
1279*abb65b4bSAndroid Build Coastguard Worker
1280*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_init(bs, bitb->addr, bitb->bsize, NULL);
1281*abb65b4bSAndroid Build Coastguard Worker oapv_mset(stat, 0, sizeof(oapve_stat_t));
1282*abb65b4bSAndroid Build Coastguard Worker
1283*abb65b4bSAndroid Build Coastguard Worker u8 *bs_pos_au_beg = oapv_bsw_sink(bs); // address syntax of au size
1284*abb65b4bSAndroid Build Coastguard Worker u8 *bs_pos_pbu_beg;
1285*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs_pbu_beg;
1286*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_write(bs, 0, 32);
1287*abb65b4bSAndroid Build Coastguard Worker
1288*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ifrms->num_frms; i++) {
1289*abb65b4bSAndroid Build Coastguard Worker frm = &ifrms->frm[i];
1290*abb65b4bSAndroid Build Coastguard Worker
1291*abb65b4bSAndroid Build Coastguard Worker /* set default value for encoding parameter */
1292*abb65b4bSAndroid Build Coastguard Worker ctx->param = &ctx->cdesc.param[i];
1293*abb65b4bSAndroid Build Coastguard Worker ret = enc_read_param(ctx, ctx->param);
1294*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ret == OAPV_OK, OAPV_ERR);
1295*abb65b4bSAndroid Build Coastguard Worker
1296*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx->param->profile_idc == OAPV_PROFILE_422_10, OAPV_ERR_UNSUPPORTED);
1297*abb65b4bSAndroid Build Coastguard Worker
1298*abb65b4bSAndroid Build Coastguard Worker // prepare for encoding a frame
1299*abb65b4bSAndroid Build Coastguard Worker ret = enc_frm_prepare(ctx, frm->imgb, (rfrms != NULL) ? rfrms->frm[i].imgb : NULL);
1300*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ret == OAPV_OK, ret);
1301*abb65b4bSAndroid Build Coastguard Worker
1302*abb65b4bSAndroid Build Coastguard Worker bs_pos_pbu_beg = oapv_bsw_sink(bs); /* store pbu pos to calculate size */
1303*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(&bs_pbu_beg, bs, sizeof(oapv_bs_t)); /* store pbu pos of ai to re-write */
1304*abb65b4bSAndroid Build Coastguard Worker
1305*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(0);
1306*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_size(bs, 0);
1307*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_header(bs, frm->pbu_type, frm->group_id);
1308*abb65b4bSAndroid Build Coastguard Worker // encode a frame
1309*abb65b4bSAndroid Build Coastguard Worker ret = enc_frame(ctx);
1310*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ret == OAPV_OK, ret);
1311*abb65b4bSAndroid Build Coastguard Worker
1312*abb65b4bSAndroid Build Coastguard Worker // rewrite pbu_size
1313*abb65b4bSAndroid Build Coastguard Worker int pbu_size = ((u8 *)oapv_bsw_sink(bs)) - bs_pos_pbu_beg - 4;
1314*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(1);
1315*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(0);
1316*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_size(&bs_pbu_beg, pbu_size);
1317*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(1);
1318*abb65b4bSAndroid Build Coastguard Worker
1319*abb65b4bSAndroid Build Coastguard Worker stat->frm_size[i] = pbu_size + 4 /* PUB size length*/;
1320*abb65b4bSAndroid Build Coastguard Worker copy_fi_to_finfo(&ctx->fh.fi, frm->pbu_type, frm->group_id, &stat->aui.frm_info[i]);
1321*abb65b4bSAndroid Build Coastguard Worker
1322*abb65b4bSAndroid Build Coastguard Worker // add frame hash value of reconstructed frame into metadata list
1323*abb65b4bSAndroid Build Coastguard Worker if(ctx->use_frm_hash) {
1324*abb65b4bSAndroid Build Coastguard Worker if(frm->pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME ||
1325*abb65b4bSAndroid Build Coastguard Worker frm->pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME) {
1326*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(mid != NULL, OAPV_ERR_INVALID_ARGUMENT);
1327*abb65b4bSAndroid Build Coastguard Worker ret = oapv_set_md5_pld(mid, frm->group_id, ctx->rec);
1328*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1329*abb65b4bSAndroid Build Coastguard Worker }
1330*abb65b4bSAndroid Build Coastguard Worker }
1331*abb65b4bSAndroid Build Coastguard Worker
1332*abb65b4bSAndroid Build Coastguard Worker // finishing of encoding a frame
1333*abb65b4bSAndroid Build Coastguard Worker ret = enc_frm_finish(ctx, stat);
1334*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ret == OAPV_OK, ret);
1335*abb65b4bSAndroid Build Coastguard Worker }
1336*abb65b4bSAndroid Build Coastguard Worker stat->aui.num_frms = ifrms->num_frms;
1337*abb65b4bSAndroid Build Coastguard Worker
1338*abb65b4bSAndroid Build Coastguard Worker oapvm_ctx_t *md_list = mid;
1339*abb65b4bSAndroid Build Coastguard Worker if(md_list != NULL) {
1340*abb65b4bSAndroid Build Coastguard Worker int num_md = md_list->num;
1341*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < num_md; i++) {
1342*abb65b4bSAndroid Build Coastguard Worker int group_id = md_list->group_ids[i];
1343*abb65b4bSAndroid Build Coastguard Worker bs_pos_pbu_beg = oapv_bsw_sink(bs); /* store pbu pos to calculate size */
1344*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(&bs_pbu_beg, bs, sizeof(oapv_bs_t)); /* store pbu pos of ai to re-write */
1345*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(0);
1346*abb65b4bSAndroid Build Coastguard Worker
1347*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_size(bs, 0);
1348*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_header(bs, OAPV_PBU_TYPE_METADATA, group_id);
1349*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_metadata(&md_list->md_arr[i], bs);
1350*abb65b4bSAndroid Build Coastguard Worker
1351*abb65b4bSAndroid Build Coastguard Worker // rewrite pbu_size
1352*abb65b4bSAndroid Build Coastguard Worker int pbu_size = ((u8 *)oapv_bsw_sink(bs)) - bs_pos_pbu_beg - 4;
1353*abb65b4bSAndroid Build Coastguard Worker DUMP_SAVE(1);
1354*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(0);
1355*abb65b4bSAndroid Build Coastguard Worker oapve_vlc_pbu_size(&bs_pbu_beg, pbu_size);
1356*abb65b4bSAndroid Build Coastguard Worker DUMP_LOAD(1);
1357*abb65b4bSAndroid Build Coastguard Worker }
1358*abb65b4bSAndroid Build Coastguard Worker }
1359*abb65b4bSAndroid Build Coastguard Worker
1360*abb65b4bSAndroid Build Coastguard Worker u32 au_size = (u32)((u8 *)oapv_bsw_sink(bs) - bs_pos_au_beg) - 4;
1361*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_write_direct(bs_pos_au_beg, au_size, 32); /* u(32) */
1362*abb65b4bSAndroid Build Coastguard Worker
1363*abb65b4bSAndroid Build Coastguard Worker oapv_bsw_deinit(&ctx->bs); /* de-init BSW */
1364*abb65b4bSAndroid Build Coastguard Worker stat->write = bsw_get_write_byte(&ctx->bs);
1365*abb65b4bSAndroid Build Coastguard Worker
1366*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1367*abb65b4bSAndroid Build Coastguard Worker }
1368*abb65b4bSAndroid Build Coastguard Worker
oapve_config(oapve_t eid,int cfg,void * buf,int * size)1369*abb65b4bSAndroid Build Coastguard Worker int oapve_config(oapve_t eid, int cfg, void *buf, int *size)
1370*abb65b4bSAndroid Build Coastguard Worker {
1371*abb65b4bSAndroid Build Coastguard Worker oapve_ctx_t *ctx;
1372*abb65b4bSAndroid Build Coastguard Worker int t0;
1373*abb65b4bSAndroid Build Coastguard Worker
1374*abb65b4bSAndroid Build Coastguard Worker ctx = enc_id_to_ctx(eid);
1375*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx, OAPV_ERR_INVALID_ARGUMENT);
1376*abb65b4bSAndroid Build Coastguard Worker
1377*abb65b4bSAndroid Build Coastguard Worker switch(cfg) {
1378*abb65b4bSAndroid Build Coastguard Worker /* set config **********************************************************/
1379*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_QP:
1380*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1381*abb65b4bSAndroid Build Coastguard Worker t0 = *((int *)buf);
1382*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(t0 >= MIN_QUANT && t0 <= MAX_QUANT,
1383*abb65b4bSAndroid Build Coastguard Worker OAPV_ERR_INVALID_ARGUMENT);
1384*abb65b4bSAndroid Build Coastguard Worker ctx->param->qp = t0;
1385*abb65b4bSAndroid Build Coastguard Worker break;
1386*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_FPS_NUM:
1387*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1388*abb65b4bSAndroid Build Coastguard Worker t0 = *((int *)buf);
1389*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(t0 > 0, OAPV_ERR_INVALID_ARGUMENT);
1390*abb65b4bSAndroid Build Coastguard Worker ctx->param->fps_num = t0;
1391*abb65b4bSAndroid Build Coastguard Worker break;
1392*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_FPS_DEN:
1393*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1394*abb65b4bSAndroid Build Coastguard Worker t0 = *((int *)buf);
1395*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(t0 > 0, OAPV_ERR_INVALID_ARGUMENT);
1396*abb65b4bSAndroid Build Coastguard Worker ctx->param->fps_den = t0;
1397*abb65b4bSAndroid Build Coastguard Worker break;
1398*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_BPS:
1399*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1400*abb65b4bSAndroid Build Coastguard Worker t0 = *((int *)buf);
1401*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(t0 > 0, OAPV_ERR_INVALID_ARGUMENT);
1402*abb65b4bSAndroid Build Coastguard Worker ctx->param->bitrate = t0;
1403*abb65b4bSAndroid Build Coastguard Worker break;
1404*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_USE_FRM_HASH:
1405*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1406*abb65b4bSAndroid Build Coastguard Worker ctx->use_frm_hash = (*((int *)buf)) ? 1 : 0;
1407*abb65b4bSAndroid Build Coastguard Worker break;
1408*abb65b4bSAndroid Build Coastguard Worker /* get config *******************************************************/
1409*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_QP:
1410*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1411*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->qp;
1412*abb65b4bSAndroid Build Coastguard Worker break;
1413*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_WIDTH:
1414*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1415*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->w;
1416*abb65b4bSAndroid Build Coastguard Worker break;
1417*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_HEIGHT:
1418*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1419*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->h;
1420*abb65b4bSAndroid Build Coastguard Worker break;
1421*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_FPS_NUM:
1422*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1423*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->fps_num;
1424*abb65b4bSAndroid Build Coastguard Worker break;
1425*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_FPS_DEN:
1426*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1427*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->fps_den;
1428*abb65b4bSAndroid Build Coastguard Worker break;
1429*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_GET_BPS:
1430*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(*size == sizeof(int), OAPV_ERR_INVALID_ARGUMENT);
1431*abb65b4bSAndroid Build Coastguard Worker *((int *)buf) = ctx->param->bitrate;
1432*abb65b4bSAndroid Build Coastguard Worker break;
1433*abb65b4bSAndroid Build Coastguard Worker default:
1434*abb65b4bSAndroid Build Coastguard Worker oapv_trace("unknown config value (%d)\n", cfg);
1435*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(0, OAPV_ERR_UNSUPPORTED);
1436*abb65b4bSAndroid Build Coastguard Worker }
1437*abb65b4bSAndroid Build Coastguard Worker
1438*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1439*abb65b4bSAndroid Build Coastguard Worker }
1440*abb65b4bSAndroid Build Coastguard Worker
oapve_param_default(oapve_param_t * param)1441*abb65b4bSAndroid Build Coastguard Worker int oapve_param_default(oapve_param_t *param)
1442*abb65b4bSAndroid Build Coastguard Worker {
1443*abb65b4bSAndroid Build Coastguard Worker oapv_mset(param, 0, sizeof(oapve_param_t));
1444*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_DEFAULT;
1445*abb65b4bSAndroid Build Coastguard Worker
1446*abb65b4bSAndroid Build Coastguard Worker param->qp_cb_offset = 0;
1447*abb65b4bSAndroid Build Coastguard Worker param->qp_cr_offset = 0;
1448*abb65b4bSAndroid Build Coastguard Worker
1449*abb65b4bSAndroid Build Coastguard Worker param->tile_w_mb = 16;
1450*abb65b4bSAndroid Build Coastguard Worker param->tile_h_mb = 16;
1451*abb65b4bSAndroid Build Coastguard Worker
1452*abb65b4bSAndroid Build Coastguard Worker param->profile_idc = OAPV_PROFILE_422_10;
1453*abb65b4bSAndroid Build Coastguard Worker param->level_idc = (int)(4.1 * 30);
1454*abb65b4bSAndroid Build Coastguard Worker param->band_idc = 2;
1455*abb65b4bSAndroid Build Coastguard Worker
1456*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1457*abb65b4bSAndroid Build Coastguard Worker }
1458*abb65b4bSAndroid Build Coastguard Worker
1459*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1460*abb65b4bSAndroid Build Coastguard Worker // enc of encoder code
1461*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_ENCODER
1462*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1463*abb65b4bSAndroid Build Coastguard Worker
1464*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1465*abb65b4bSAndroid Build Coastguard Worker // start of decoder code
1466*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_DECODER
1467*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
dec_id_to_ctx(oapvd_t id)1468*abb65b4bSAndroid Build Coastguard Worker static oapvd_ctx_t *dec_id_to_ctx(oapvd_t id)
1469*abb65b4bSAndroid Build Coastguard Worker {
1470*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
1471*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(id, NULL);
1472*abb65b4bSAndroid Build Coastguard Worker ctx = (oapvd_ctx_t *)id;
1473*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx->magic == OAPVD_MAGIC_CODE, NULL);
1474*abb65b4bSAndroid Build Coastguard Worker return ctx;
1475*abb65b4bSAndroid Build Coastguard Worker }
1476*abb65b4bSAndroid Build Coastguard Worker
dec_ctx_alloc(void)1477*abb65b4bSAndroid Build Coastguard Worker static oapvd_ctx_t *dec_ctx_alloc(void)
1478*abb65b4bSAndroid Build Coastguard Worker {
1479*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
1480*abb65b4bSAndroid Build Coastguard Worker
1481*abb65b4bSAndroid Build Coastguard Worker ctx = (oapvd_ctx_t *)oapv_malloc_fast(sizeof(oapvd_ctx_t));
1482*abb65b4bSAndroid Build Coastguard Worker
1483*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx != NULL, NULL);
1484*abb65b4bSAndroid Build Coastguard Worker oapv_mset_x64a(ctx, 0, sizeof(oapvd_ctx_t));
1485*abb65b4bSAndroid Build Coastguard Worker
1486*abb65b4bSAndroid Build Coastguard Worker return ctx;
1487*abb65b4bSAndroid Build Coastguard Worker }
1488*abb65b4bSAndroid Build Coastguard Worker
dec_ctx_free(oapvd_ctx_t * ctx)1489*abb65b4bSAndroid Build Coastguard Worker static void dec_ctx_free(oapvd_ctx_t *ctx)
1490*abb65b4bSAndroid Build Coastguard Worker {
1491*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(ctx);
1492*abb65b4bSAndroid Build Coastguard Worker }
1493*abb65b4bSAndroid Build Coastguard Worker
dec_core_alloc(void)1494*abb65b4bSAndroid Build Coastguard Worker static oapvd_core_t *dec_core_alloc(void)
1495*abb65b4bSAndroid Build Coastguard Worker {
1496*abb65b4bSAndroid Build Coastguard Worker oapvd_core_t *core;
1497*abb65b4bSAndroid Build Coastguard Worker
1498*abb65b4bSAndroid Build Coastguard Worker core = (oapvd_core_t *)oapv_malloc_fast(sizeof(oapvd_core_t));
1499*abb65b4bSAndroid Build Coastguard Worker
1500*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(core, NULL);
1501*abb65b4bSAndroid Build Coastguard Worker oapv_mset_x64a(core, 0, sizeof(oapvd_core_t));
1502*abb65b4bSAndroid Build Coastguard Worker
1503*abb65b4bSAndroid Build Coastguard Worker return core;
1504*abb65b4bSAndroid Build Coastguard Worker }
1505*abb65b4bSAndroid Build Coastguard Worker
dec_core_free(oapvd_core_t * core)1506*abb65b4bSAndroid Build Coastguard Worker static void dec_core_free(oapvd_core_t *core)
1507*abb65b4bSAndroid Build Coastguard Worker {
1508*abb65b4bSAndroid Build Coastguard Worker oapv_mfree_fast(core);
1509*abb65b4bSAndroid Build Coastguard Worker }
1510*abb65b4bSAndroid Build Coastguard Worker
dec_block(oapvd_ctx_t * ctx,oapvd_core_t * core,int log2_w,int log2_h,int c)1511*abb65b4bSAndroid Build Coastguard Worker static int dec_block(oapvd_ctx_t *ctx, oapvd_core_t *core, int log2_w, int log2_h, int c)
1512*abb65b4bSAndroid Build Coastguard Worker {
1513*abb65b4bSAndroid Build Coastguard Worker int bit_depth = ctx->bit_depth;
1514*abb65b4bSAndroid Build Coastguard Worker
1515*abb65b4bSAndroid Build Coastguard Worker // DC prediction
1516*abb65b4bSAndroid Build Coastguard Worker core->coef[0] += core->prev_dc[c];
1517*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = core->coef[0];
1518*abb65b4bSAndroid Build Coastguard Worker // Inverse quantization
1519*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant[0](core->coef, core->q_mat[c], log2_w, log2_h, core->dq_shift[c]);
1520*abb65b4bSAndroid Build Coastguard Worker // Inverse transform
1521*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx[0](core->coef, ITX_SHIFT1, ITX_SHIFT2(bit_depth), 1 << log2_w);
1522*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1523*abb65b4bSAndroid Build Coastguard Worker }
1524*abb65b4bSAndroid Build Coastguard Worker
dec_set_tile_info(oapvd_tile_t * tile,int w_pel,int h_pel,int tile_w,int tile_h,int num_tile_cols,int num_tiles)1525*abb65b4bSAndroid Build Coastguard Worker static int dec_set_tile_info(oapvd_tile_t* tile, int w_pel, int h_pel, int tile_w, int tile_h, int num_tile_cols, int num_tiles)
1526*abb65b4bSAndroid Build Coastguard Worker {
1527*abb65b4bSAndroid Build Coastguard Worker
1528*abb65b4bSAndroid Build Coastguard Worker for (int i = 0; i < num_tiles; i++)
1529*abb65b4bSAndroid Build Coastguard Worker {
1530*abb65b4bSAndroid Build Coastguard Worker int tx = (i % (num_tile_cols)) * tile_w;
1531*abb65b4bSAndroid Build Coastguard Worker int ty = (i / (num_tile_cols)) * tile_h;
1532*abb65b4bSAndroid Build Coastguard Worker tile[i].x = tx;
1533*abb65b4bSAndroid Build Coastguard Worker tile[i].y = ty;
1534*abb65b4bSAndroid Build Coastguard Worker tile[i].w = tx + tile_w > w_pel ? w_pel - tx : tile_w;
1535*abb65b4bSAndroid Build Coastguard Worker tile[i].h = ty + tile_h > h_pel ? h_pel - ty : tile_h;
1536*abb65b4bSAndroid Build Coastguard Worker }
1537*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1538*abb65b4bSAndroid Build Coastguard Worker }
1539*abb65b4bSAndroid Build Coastguard Worker
dec_frm_prepare(oapvd_ctx_t * ctx,oapv_imgb_t * imgb)1540*abb65b4bSAndroid Build Coastguard Worker static int dec_frm_prepare(oapvd_ctx_t *ctx, oapv_imgb_t *imgb)
1541*abb65b4bSAndroid Build Coastguard Worker {
1542*abb65b4bSAndroid Build Coastguard Worker ctx->imgb = imgb;
1543*abb65b4bSAndroid Build Coastguard Worker imgb_addref(ctx->imgb); // increase reference count
1544*abb65b4bSAndroid Build Coastguard Worker
1545*abb65b4bSAndroid Build Coastguard Worker ctx->bit_depth = ctx->fh.fi.bit_depth;
1546*abb65b4bSAndroid Build Coastguard Worker ctx->cfi = ctx->fh.fi.chroma_format_idc;
1547*abb65b4bSAndroid Build Coastguard Worker ctx->num_comp = get_num_comp(ctx->cfi);
1548*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[Y_C][0] = 0;
1549*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[Y_C][1] = 0;
1550*abb65b4bSAndroid Build Coastguard Worker
1551*abb65b4bSAndroid Build Coastguard Worker for(int c = 1; c < ctx->num_comp; c++) {
1552*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[c][0] = get_chroma_sft_w(color_format_to_chroma_format_idc(OAPV_CS_GET_FORMAT(imgb->cs)));
1553*abb65b4bSAndroid Build Coastguard Worker ctx->comp_sft[c][1] = get_chroma_sft_h(color_format_to_chroma_format_idc(OAPV_CS_GET_FORMAT(imgb->cs)));
1554*abb65b4bSAndroid Build Coastguard Worker }
1555*abb65b4bSAndroid Build Coastguard Worker
1556*abb65b4bSAndroid Build Coastguard Worker ctx->w = oapv_align_value(ctx->fh.fi.frame_width, OAPV_MB_W);
1557*abb65b4bSAndroid Build Coastguard Worker ctx->h = oapv_align_value(ctx->fh.fi.frame_height, OAPV_MB_H);
1558*abb65b4bSAndroid Build Coastguard Worker
1559*abb65b4bSAndroid Build Coastguard Worker if(OAPV_CS_GET_FORMAT(imgb->cs) == OAPV_CF_PLANAR2) {
1560*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[Y_C] = block_to_imgb_p210_y;
1561*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[U_C] = block_to_imgb_p210_uv;
1562*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[V_C] = block_to_imgb_p210_uv;
1563*abb65b4bSAndroid Build Coastguard Worker }
1564*abb65b4bSAndroid Build Coastguard Worker else {
1565*abb65b4bSAndroid Build Coastguard Worker for(int c = 0; c < ctx->num_comp; c++) {
1566*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[c] = block_to_imgb_10bit;
1567*abb65b4bSAndroid Build Coastguard Worker }
1568*abb65b4bSAndroid Build Coastguard Worker }
1569*abb65b4bSAndroid Build Coastguard Worker
1570*abb65b4bSAndroid Build Coastguard Worker int tile_w = ctx->fh.tile_width_in_mbs * OAPV_MB_W;
1571*abb65b4bSAndroid Build Coastguard Worker int tile_h = ctx->fh.tile_height_in_mbs * OAPV_MB_H;
1572*abb65b4bSAndroid Build Coastguard Worker
1573*abb65b4bSAndroid Build Coastguard Worker ctx->num_tile_cols = (ctx->w + (tile_w - 1)) / tile_w;
1574*abb65b4bSAndroid Build Coastguard Worker ctx->num_tile_rows = (ctx->h + (tile_h - 1)) / tile_h;
1575*abb65b4bSAndroid Build Coastguard Worker ctx->num_tiles = ctx->num_tile_cols * ctx->num_tile_rows;
1576*abb65b4bSAndroid Build Coastguard Worker
1577*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv((ctx->num_tile_cols <= OAPV_MAX_TILE_COLS) && (ctx->num_tile_rows <= OAPV_MAX_TILE_ROWS), OAPV_ERR_MALFORMED_BITSTREAM);
1578*abb65b4bSAndroid Build Coastguard Worker dec_set_tile_info(ctx->tile, ctx->w, ctx->h, tile_w, tile_h, ctx->num_tile_cols, ctx->num_tiles);
1579*abb65b4bSAndroid Build Coastguard Worker
1580*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_tiles; i++) {
1581*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].bs_beg = NULL;
1582*abb65b4bSAndroid Build Coastguard Worker }
1583*abb65b4bSAndroid Build Coastguard Worker ctx->tile[0].bs_beg = oapv_bsr_sink(&ctx->bs);
1584*abb65b4bSAndroid Build Coastguard Worker
1585*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->num_tiles; i++) {
1586*abb65b4bSAndroid Build Coastguard Worker ctx->tile[i].stat = DEC_TILE_STAT_NOT_DECODED;
1587*abb65b4bSAndroid Build Coastguard Worker }
1588*abb65b4bSAndroid Build Coastguard Worker
1589*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1590*abb65b4bSAndroid Build Coastguard Worker }
1591*abb65b4bSAndroid Build Coastguard Worker
dec_frm_finish(oapvd_ctx_t * ctx)1592*abb65b4bSAndroid Build Coastguard Worker static int dec_frm_finish(oapvd_ctx_t *ctx)
1593*abb65b4bSAndroid Build Coastguard Worker {
1594*abb65b4bSAndroid Build Coastguard Worker oapv_mset(&ctx->bs, 0, sizeof(oapv_bs_t)); // clean data
1595*abb65b4bSAndroid Build Coastguard Worker imgb_release(ctx->imgb); // decrease reference cnout
1596*abb65b4bSAndroid Build Coastguard Worker ctx->imgb = NULL;
1597*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1598*abb65b4bSAndroid Build Coastguard Worker }
1599*abb65b4bSAndroid Build Coastguard Worker
dec_tile_comp(oapvd_tile_t * tile,oapvd_ctx_t * ctx,oapvd_core_t * core,oapv_bs_t * bs,int c,int s_dst,void * dst)1600*abb65b4bSAndroid Build Coastguard Worker static int dec_tile_comp(oapvd_tile_t *tile, oapvd_ctx_t *ctx, oapvd_core_t *core, oapv_bs_t *bs, int c, int s_dst, void *dst)
1601*abb65b4bSAndroid Build Coastguard Worker {
1602*abb65b4bSAndroid Build Coastguard Worker int mb_h, mb_w, mb_y, mb_x, blk_y, blk_x;
1603*abb65b4bSAndroid Build Coastguard Worker int le, ri, to, bo;
1604*abb65b4bSAndroid Build Coastguard Worker int ret;
1605*abb65b4bSAndroid Build Coastguard Worker s16 *d16;
1606*abb65b4bSAndroid Build Coastguard Worker
1607*abb65b4bSAndroid Build Coastguard Worker mb_h = OAPV_MB_H >> ctx->comp_sft[c][1];
1608*abb65b4bSAndroid Build Coastguard Worker mb_w = OAPV_MB_W >> ctx->comp_sft[c][0];
1609*abb65b4bSAndroid Build Coastguard Worker
1610*abb65b4bSAndroid Build Coastguard Worker le = tile->x >> ctx->comp_sft[c][0]; // left position of tile
1611*abb65b4bSAndroid Build Coastguard Worker ri = (tile->w >> ctx->comp_sft[c][0]) + le; // right pixel position of tile
1612*abb65b4bSAndroid Build Coastguard Worker to = tile->y >> ctx->comp_sft[c][1]; // top pixel position of tile
1613*abb65b4bSAndroid Build Coastguard Worker bo = (tile->h >> ctx->comp_sft[c][1]) + to; // bottom pixel position of tile
1614*abb65b4bSAndroid Build Coastguard Worker
1615*abb65b4bSAndroid Build Coastguard Worker for(mb_y = to; mb_y < bo; mb_y += mb_h) {
1616*abb65b4bSAndroid Build Coastguard Worker for(mb_x = le; mb_x < ri; mb_x += mb_w) {
1617*abb65b4bSAndroid Build Coastguard Worker for(blk_y = mb_y; blk_y < (mb_y + mb_h); blk_y += OAPV_BLK_H) {
1618*abb65b4bSAndroid Build Coastguard Worker for(blk_x = mb_x; blk_x < (mb_x + mb_w); blk_x += OAPV_BLK_W) {
1619*abb65b4bSAndroid Build Coastguard Worker // parse DC coefficient
1620*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_dc_coeff(ctx, core, bs, &core->coef[0], c);
1621*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1622*abb65b4bSAndroid Build Coastguard Worker
1623*abb65b4bSAndroid Build Coastguard Worker // parse AC coefficient
1624*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_ac_coeff(ctx, core, bs, core->coef, c);
1625*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1626*abb65b4bSAndroid Build Coastguard Worker DUMP_COEF(core->coef, OAPV_BLK_D, blk_x, blk_y, c);
1627*abb65b4bSAndroid Build Coastguard Worker
1628*abb65b4bSAndroid Build Coastguard Worker // decode a block
1629*abb65b4bSAndroid Build Coastguard Worker ret = dec_block(ctx, core, OAPV_LOG2_BLK_W, OAPV_LOG2_BLK_H, c);
1630*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1631*abb65b4bSAndroid Build Coastguard Worker
1632*abb65b4bSAndroid Build Coastguard Worker // copy decoded block to image buffer
1633*abb65b4bSAndroid Build Coastguard Worker d16 = (s16 *)((u8 *)dst + blk_y * s_dst) + blk_x;
1634*abb65b4bSAndroid Build Coastguard Worker ctx->fn_block_to_imgb[c](core->coef, OAPV_BLK_W, OAPV_BLK_H, (OAPV_BLK_W << 1), blk_x, s_dst, d16);
1635*abb65b4bSAndroid Build Coastguard Worker }
1636*abb65b4bSAndroid Build Coastguard Worker }
1637*abb65b4bSAndroid Build Coastguard Worker }
1638*abb65b4bSAndroid Build Coastguard Worker }
1639*abb65b4bSAndroid Build Coastguard Worker
1640*abb65b4bSAndroid Build Coastguard Worker /* byte align */
1641*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_align8(bs);
1642*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1643*abb65b4bSAndroid Build Coastguard Worker }
1644*abb65b4bSAndroid Build Coastguard Worker
dec_tile(oapvd_core_t * core,oapvd_tile_t * tile)1645*abb65b4bSAndroid Build Coastguard Worker static int dec_tile(oapvd_core_t *core, oapvd_tile_t *tile)
1646*abb65b4bSAndroid Build Coastguard Worker {
1647*abb65b4bSAndroid Build Coastguard Worker int ret, midx, x, y, c;
1648*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx = core->ctx;
1649*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs;
1650*abb65b4bSAndroid Build Coastguard Worker
1651*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_init(&bs, tile->bs_beg + OAPV_TILE_SIZE_LEN, tile->data_size, NULL);
1652*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_tile_header(&bs, ctx, &tile->th);
1653*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1654*abb65b4bSAndroid Build Coastguard Worker for(c = 0; c < ctx->num_comp; c++) {
1655*abb65b4bSAndroid Build Coastguard Worker core->qp[c] = tile->th.tile_qp[c];
1656*abb65b4bSAndroid Build Coastguard Worker int dq_scale = oapv_tbl_dq_scale[core->qp[c] % 6];
1657*abb65b4bSAndroid Build Coastguard Worker core->dq_shift[c] = ctx->bit_depth - 2 - (core->qp[c] / 6);
1658*abb65b4bSAndroid Build Coastguard Worker
1659*abb65b4bSAndroid Build Coastguard Worker core->prev_dc_ctx[c] = 20;
1660*abb65b4bSAndroid Build Coastguard Worker core->prev_1st_ac_ctx[c] = 0;
1661*abb65b4bSAndroid Build Coastguard Worker core->prev_dc[c] = 0;
1662*abb65b4bSAndroid Build Coastguard Worker
1663*abb65b4bSAndroid Build Coastguard Worker midx = 0;
1664*abb65b4bSAndroid Build Coastguard Worker for(y = 0; y < OAPV_BLK_H; y++) {
1665*abb65b4bSAndroid Build Coastguard Worker for(x = 0; x < OAPV_BLK_W; x++) {
1666*abb65b4bSAndroid Build Coastguard Worker core->q_mat[c][midx++] = dq_scale * ctx->fh.q_matrix[c][y][x]; // 7bit + 8bit
1667*abb65b4bSAndroid Build Coastguard Worker }
1668*abb65b4bSAndroid Build Coastguard Worker }
1669*abb65b4bSAndroid Build Coastguard Worker }
1670*abb65b4bSAndroid Build Coastguard Worker
1671*abb65b4bSAndroid Build Coastguard Worker for(c = 0; c < ctx->num_comp; c++) {
1672*abb65b4bSAndroid Build Coastguard Worker int tc, s_dst;
1673*abb65b4bSAndroid Build Coastguard Worker s16 *dst;
1674*abb65b4bSAndroid Build Coastguard Worker
1675*abb65b4bSAndroid Build Coastguard Worker if(OAPV_CS_GET_FORMAT(ctx->imgb->cs) == OAPV_CF_PLANAR2) {
1676*abb65b4bSAndroid Build Coastguard Worker tc = c > 0 ? 1 : 0;
1677*abb65b4bSAndroid Build Coastguard Worker dst = ctx->imgb->a[tc];
1678*abb65b4bSAndroid Build Coastguard Worker dst += (c > 1) ? 1 : 0;
1679*abb65b4bSAndroid Build Coastguard Worker s_dst = ctx->imgb->s[tc];
1680*abb65b4bSAndroid Build Coastguard Worker }
1681*abb65b4bSAndroid Build Coastguard Worker else {
1682*abb65b4bSAndroid Build Coastguard Worker dst = ctx->imgb->a[c];
1683*abb65b4bSAndroid Build Coastguard Worker s_dst = ctx->imgb->s[c];
1684*abb65b4bSAndroid Build Coastguard Worker }
1685*abb65b4bSAndroid Build Coastguard Worker
1686*abb65b4bSAndroid Build Coastguard Worker ret = dec_tile_comp(tile, ctx, core, &bs, c, s_dst, dst);
1687*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
1688*abb65b4bSAndroid Build Coastguard Worker }
1689*abb65b4bSAndroid Build Coastguard Worker
1690*abb65b4bSAndroid Build Coastguard Worker oapvd_vlc_tile_dummy_data(&bs);
1691*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1692*abb65b4bSAndroid Build Coastguard Worker }
1693*abb65b4bSAndroid Build Coastguard Worker
dec_thread_tile(void * arg)1694*abb65b4bSAndroid Build Coastguard Worker static int dec_thread_tile(void *arg)
1695*abb65b4bSAndroid Build Coastguard Worker {
1696*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs;
1697*abb65b4bSAndroid Build Coastguard Worker int i, ret, run, tile_idx = 0, thread_ret = OAPV_OK;
1698*abb65b4bSAndroid Build Coastguard Worker
1699*abb65b4bSAndroid Build Coastguard Worker oapvd_core_t *core = (oapvd_core_t *)arg;
1700*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx = core->ctx;
1701*abb65b4bSAndroid Build Coastguard Worker oapvd_tile_t *tile = ctx->tile;
1702*abb65b4bSAndroid Build Coastguard Worker
1703*abb65b4bSAndroid Build Coastguard Worker while(1) {
1704*abb65b4bSAndroid Build Coastguard Worker // find not decoded tile
1705*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
1706*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ctx->num_tiles; i++) {
1707*abb65b4bSAndroid Build Coastguard Worker if(tile[i].stat == DEC_TILE_STAT_NOT_DECODED) {
1708*abb65b4bSAndroid Build Coastguard Worker tile[i].stat = DEC_TILE_STAT_ON_DECODING;
1709*abb65b4bSAndroid Build Coastguard Worker tile_idx = i;
1710*abb65b4bSAndroid Build Coastguard Worker break;
1711*abb65b4bSAndroid Build Coastguard Worker }
1712*abb65b4bSAndroid Build Coastguard Worker }
1713*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
1714*abb65b4bSAndroid Build Coastguard Worker if(i == ctx->num_tiles) {
1715*abb65b4bSAndroid Build Coastguard Worker break;
1716*abb65b4bSAndroid Build Coastguard Worker }
1717*abb65b4bSAndroid Build Coastguard Worker
1718*abb65b4bSAndroid Build Coastguard Worker // wait until to know bistream start position
1719*abb65b4bSAndroid Build Coastguard Worker run = 1;
1720*abb65b4bSAndroid Build Coastguard Worker while(run) {
1721*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
1722*abb65b4bSAndroid Build Coastguard Worker if(tile[tile_idx].bs_beg != NULL) {
1723*abb65b4bSAndroid Build Coastguard Worker run = 0;
1724*abb65b4bSAndroid Build Coastguard Worker }
1725*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
1726*abb65b4bSAndroid Build Coastguard Worker }
1727*abb65b4bSAndroid Build Coastguard Worker /* read tile size */
1728*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_init(&bs, tile[tile_idx].bs_beg, OAPV_TILE_SIZE_LEN, NULL);
1729*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_tile_size(&bs, &tile[tile_idx].data_size);
1730*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1731*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(tile[tile_idx].bs_beg + OAPV_TILE_SIZE_LEN + (tile[tile_idx].data_size - 1) <= ctx->bs.end, ERR);
1732*abb65b4bSAndroid Build Coastguard Worker
1733*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
1734*abb65b4bSAndroid Build Coastguard Worker if(tile_idx + 1 < ctx->num_tiles) {
1735*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx + 1].bs_beg = tile[tile_idx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tile_idx].data_size;
1736*abb65b4bSAndroid Build Coastguard Worker }
1737*abb65b4bSAndroid Build Coastguard Worker else {
1738*abb65b4bSAndroid Build Coastguard Worker ctx->tile_end = tile[tile_idx].bs_beg + OAPV_TILE_SIZE_LEN + tile[tile_idx].data_size;
1739*abb65b4bSAndroid Build Coastguard Worker }
1740*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
1741*abb65b4bSAndroid Build Coastguard Worker
1742*abb65b4bSAndroid Build Coastguard Worker ret = dec_tile(core, &tile[tile_idx]);
1743*abb65b4bSAndroid Build Coastguard Worker
1744*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
1745*abb65b4bSAndroid Build Coastguard Worker if (OAPV_SUCCEEDED(ret)) {
1746*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx].stat = DEC_TILE_STAT_DECODED;
1747*abb65b4bSAndroid Build Coastguard Worker }
1748*abb65b4bSAndroid Build Coastguard Worker else {
1749*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx].stat = ret;
1750*abb65b4bSAndroid Build Coastguard Worker thread_ret = ret;
1751*abb65b4bSAndroid Build Coastguard Worker }
1752*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx].stat = OAPV_SUCCEEDED(ret) ? DEC_TILE_STAT_DECODED : ret;
1753*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
1754*abb65b4bSAndroid Build Coastguard Worker }
1755*abb65b4bSAndroid Build Coastguard Worker return thread_ret;
1756*abb65b4bSAndroid Build Coastguard Worker
1757*abb65b4bSAndroid Build Coastguard Worker ERR:
1758*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_enter_cs(ctx->sync_obj);
1759*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx].stat = DEC_TILE_STAT_SIZE_ERROR;
1760*abb65b4bSAndroid Build Coastguard Worker if (tile_idx + 1 < ctx->num_tiles)
1761*abb65b4bSAndroid Build Coastguard Worker {
1762*abb65b4bSAndroid Build Coastguard Worker tile[tile_idx + 1].bs_beg = tile[tile_idx].bs_beg;
1763*abb65b4bSAndroid Build Coastguard Worker }
1764*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_leave_cs(ctx->sync_obj);
1765*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR_MALFORMED_BITSTREAM;
1766*abb65b4bSAndroid Build Coastguard Worker }
1767*abb65b4bSAndroid Build Coastguard Worker
dec_flush(oapvd_ctx_t * ctx)1768*abb65b4bSAndroid Build Coastguard Worker static void dec_flush(oapvd_ctx_t *ctx)
1769*abb65b4bSAndroid Build Coastguard Worker {
1770*abb65b4bSAndroid Build Coastguard Worker if(ctx->cdesc.threads >= 2) {
1771*abb65b4bSAndroid Build Coastguard Worker if(ctx->tpool) {
1772*abb65b4bSAndroid Build Coastguard Worker // thread controller instance is present
1773*abb65b4bSAndroid Build Coastguard Worker // terminate the created thread
1774*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads - 1; i++) {
1775*abb65b4bSAndroid Build Coastguard Worker if(ctx->thread_id[i]) {
1776*abb65b4bSAndroid Build Coastguard Worker // valid thread instance
1777*abb65b4bSAndroid Build Coastguard Worker ctx->tpool->release(&ctx->thread_id[i]);
1778*abb65b4bSAndroid Build Coastguard Worker }
1779*abb65b4bSAndroid Build Coastguard Worker }
1780*abb65b4bSAndroid Build Coastguard Worker // dinitialize the tpool
1781*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_deinit(ctx->tpool);
1782*abb65b4bSAndroid Build Coastguard Worker oapv_mfree(ctx->tpool);
1783*abb65b4bSAndroid Build Coastguard Worker ctx->tpool = NULL;
1784*abb65b4bSAndroid Build Coastguard Worker }
1785*abb65b4bSAndroid Build Coastguard Worker }
1786*abb65b4bSAndroid Build Coastguard Worker
1787*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_sync_obj_delete(&(ctx->sync_obj));
1788*abb65b4bSAndroid Build Coastguard Worker
1789*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ctx->cdesc.threads; i++) {
1790*abb65b4bSAndroid Build Coastguard Worker dec_core_free(ctx->core[i]);
1791*abb65b4bSAndroid Build Coastguard Worker }
1792*abb65b4bSAndroid Build Coastguard Worker }
1793*abb65b4bSAndroid Build Coastguard Worker
dec_ready(oapvd_ctx_t * ctx)1794*abb65b4bSAndroid Build Coastguard Worker static int dec_ready(oapvd_ctx_t *ctx)
1795*abb65b4bSAndroid Build Coastguard Worker {
1796*abb65b4bSAndroid Build Coastguard Worker int i, ret = OAPV_OK;
1797*abb65b4bSAndroid Build Coastguard Worker
1798*abb65b4bSAndroid Build Coastguard Worker if(ctx->core[0] == NULL) {
1799*abb65b4bSAndroid Build Coastguard Worker // create cores
1800*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ctx->cdesc.threads; i++) {
1801*abb65b4bSAndroid Build Coastguard Worker ctx->core[i] = dec_core_alloc();
1802*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->core[i], ret, OAPV_ERR_OUT_OF_MEMORY, ERR);
1803*abb65b4bSAndroid Build Coastguard Worker ctx->core[i]->ctx = ctx;
1804*abb65b4bSAndroid Build Coastguard Worker }
1805*abb65b4bSAndroid Build Coastguard Worker }
1806*abb65b4bSAndroid Build Coastguard Worker
1807*abb65b4bSAndroid Build Coastguard Worker // initialize the threads to NULL
1808*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < OAPV_MAX_THREADS; i++) {
1809*abb65b4bSAndroid Build Coastguard Worker ctx->thread_id[i] = 0;
1810*abb65b4bSAndroid Build Coastguard Worker }
1811*abb65b4bSAndroid Build Coastguard Worker
1812*abb65b4bSAndroid Build Coastguard Worker // get the context synchronization handle
1813*abb65b4bSAndroid Build Coastguard Worker ctx->sync_obj = oapv_tpool_sync_obj_create();
1814*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->sync_obj != NULL, ret, OAPV_ERR_UNKNOWN, ERR);
1815*abb65b4bSAndroid Build Coastguard Worker
1816*abb65b4bSAndroid Build Coastguard Worker if(ctx->cdesc.threads >= 2) {
1817*abb65b4bSAndroid Build Coastguard Worker ctx->tpool = oapv_malloc(sizeof(oapv_tpool_t));
1818*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_init(ctx->tpool, ctx->cdesc.threads - 1);
1819*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ctx->cdesc.threads - 1; i++) {
1820*abb65b4bSAndroid Build Coastguard Worker ctx->thread_id[i] = ctx->tpool->create(ctx->tpool, i);
1821*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx->thread_id[i] != NULL, ret, OAPV_ERR_UNKNOWN, ERR);
1822*abb65b4bSAndroid Build Coastguard Worker }
1823*abb65b4bSAndroid Build Coastguard Worker }
1824*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1825*abb65b4bSAndroid Build Coastguard Worker
1826*abb65b4bSAndroid Build Coastguard Worker ERR:
1827*abb65b4bSAndroid Build Coastguard Worker dec_flush(ctx);
1828*abb65b4bSAndroid Build Coastguard Worker
1829*abb65b4bSAndroid Build Coastguard Worker return ret;
1830*abb65b4bSAndroid Build Coastguard Worker }
1831*abb65b4bSAndroid Build Coastguard Worker
dec_platform_init(oapvd_ctx_t * ctx)1832*abb65b4bSAndroid Build Coastguard Worker static int dec_platform_init(oapvd_ctx_t *ctx)
1833*abb65b4bSAndroid Build Coastguard Worker {
1834*abb65b4bSAndroid Build Coastguard Worker // default settings
1835*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx;
1836*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant;
1837*abb65b4bSAndroid Build Coastguard Worker
1838*abb65b4bSAndroid Build Coastguard Worker #if X86_SSE
1839*abb65b4bSAndroid Build Coastguard Worker int check_cpu, support_sse, support_avx2;
1840*abb65b4bSAndroid Build Coastguard Worker
1841*abb65b4bSAndroid Build Coastguard Worker check_cpu = oapv_check_cpu_info_x86();
1842*abb65b4bSAndroid Build Coastguard Worker support_sse = (check_cpu >> 0) & 1;
1843*abb65b4bSAndroid Build Coastguard Worker support_avx2 = (check_cpu >> 2) & 1;
1844*abb65b4bSAndroid Build Coastguard Worker
1845*abb65b4bSAndroid Build Coastguard Worker if(support_avx2) {
1846*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx_avx;
1847*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant_avx;
1848*abb65b4bSAndroid Build Coastguard Worker }
1849*abb65b4bSAndroid Build Coastguard Worker else if(support_sse) {
1850*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx;
1851*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant;
1852*abb65b4bSAndroid Build Coastguard Worker }
1853*abb65b4bSAndroid Build Coastguard Worker #elif ARM_NEON
1854*abb65b4bSAndroid Build Coastguard Worker ctx->fn_itx = oapv_tbl_fn_itx_neon;
1855*abb65b4bSAndroid Build Coastguard Worker ctx->fn_dquant = oapv_tbl_fn_dquant;
1856*abb65b4bSAndroid Build Coastguard Worker #endif
1857*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
1858*abb65b4bSAndroid Build Coastguard Worker }
1859*abb65b4bSAndroid Build Coastguard Worker
oapvd_create(oapvd_cdesc_t * cdesc,int * err)1860*abb65b4bSAndroid Build Coastguard Worker oapvd_t oapvd_create(oapvd_cdesc_t *cdesc, int *err)
1861*abb65b4bSAndroid Build Coastguard Worker {
1862*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
1863*abb65b4bSAndroid Build Coastguard Worker int ret;
1864*abb65b4bSAndroid Build Coastguard Worker
1865*abb65b4bSAndroid Build Coastguard Worker DUMP_CREATE(0);
1866*abb65b4bSAndroid Build Coastguard Worker ctx = NULL;
1867*abb65b4bSAndroid Build Coastguard Worker
1868*abb65b4bSAndroid Build Coastguard Worker /* check if any decoder argument is correctly set */
1869*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(cdesc->threads > 0 && cdesc->threads <= OAPV_MAX_THREADS, ret, OAPV_ERR_INVALID_ARGUMENT, ERR);
1870*abb65b4bSAndroid Build Coastguard Worker
1871*abb65b4bSAndroid Build Coastguard Worker /* memory allocation for ctx and core structure */
1872*abb65b4bSAndroid Build Coastguard Worker ctx = (oapvd_ctx_t *)dec_ctx_alloc();
1873*abb65b4bSAndroid Build Coastguard Worker oapv_assert_gv(ctx != NULL, ret, OAPV_ERR_OUT_OF_MEMORY, ERR);
1874*abb65b4bSAndroid Build Coastguard Worker oapv_mcpy(&ctx->cdesc, cdesc, sizeof(oapvd_cdesc_t));
1875*abb65b4bSAndroid Build Coastguard Worker
1876*abb65b4bSAndroid Build Coastguard Worker /* initialize platform-specific variables */
1877*abb65b4bSAndroid Build Coastguard Worker ret = dec_platform_init(ctx);
1878*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(ret == OAPV_OK, ERR);
1879*abb65b4bSAndroid Build Coastguard Worker
1880*abb65b4bSAndroid Build Coastguard Worker /* ready for decoding */
1881*abb65b4bSAndroid Build Coastguard Worker ret = dec_ready(ctx);
1882*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(ret == OAPV_OK, ERR);
1883*abb65b4bSAndroid Build Coastguard Worker
1884*abb65b4bSAndroid Build Coastguard Worker ctx->magic = OAPVD_MAGIC_CODE;
1885*abb65b4bSAndroid Build Coastguard Worker ctx->id = (oapvd_t)ctx;
1886*abb65b4bSAndroid Build Coastguard Worker if(err) {
1887*abb65b4bSAndroid Build Coastguard Worker *err = OAPV_OK;
1888*abb65b4bSAndroid Build Coastguard Worker }
1889*abb65b4bSAndroid Build Coastguard Worker return (ctx->id);
1890*abb65b4bSAndroid Build Coastguard Worker
1891*abb65b4bSAndroid Build Coastguard Worker ERR:
1892*abb65b4bSAndroid Build Coastguard Worker if(ctx) {
1893*abb65b4bSAndroid Build Coastguard Worker dec_ctx_free(ctx);
1894*abb65b4bSAndroid Build Coastguard Worker }
1895*abb65b4bSAndroid Build Coastguard Worker if(err) {
1896*abb65b4bSAndroid Build Coastguard Worker *err = ret;
1897*abb65b4bSAndroid Build Coastguard Worker }
1898*abb65b4bSAndroid Build Coastguard Worker return NULL;
1899*abb65b4bSAndroid Build Coastguard Worker }
1900*abb65b4bSAndroid Build Coastguard Worker
oapvd_delete(oapvd_t did)1901*abb65b4bSAndroid Build Coastguard Worker void oapvd_delete(oapvd_t did)
1902*abb65b4bSAndroid Build Coastguard Worker {
1903*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
1904*abb65b4bSAndroid Build Coastguard Worker ctx = dec_id_to_ctx(did);
1905*abb65b4bSAndroid Build Coastguard Worker oapv_assert_r(ctx);
1906*abb65b4bSAndroid Build Coastguard Worker
1907*abb65b4bSAndroid Build Coastguard Worker DUMP_DELETE();
1908*abb65b4bSAndroid Build Coastguard Worker dec_flush(ctx);
1909*abb65b4bSAndroid Build Coastguard Worker dec_ctx_free(ctx);
1910*abb65b4bSAndroid Build Coastguard Worker }
1911*abb65b4bSAndroid Build Coastguard Worker
oapvd_decode(oapvd_t did,oapv_bitb_t * bitb,oapv_frms_t * ofrms,oapvm_t mid,oapvd_stat_t * stat)1912*abb65b4bSAndroid Build Coastguard Worker int oapvd_decode(oapvd_t did, oapv_bitb_t *bitb, oapv_frms_t *ofrms, oapvm_t mid, oapvd_stat_t *stat)
1913*abb65b4bSAndroid Build Coastguard Worker {
1914*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
1915*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t *bs;
1916*abb65b4bSAndroid Build Coastguard Worker oapv_pbuh_t pbuh;
1917*abb65b4bSAndroid Build Coastguard Worker int ret = OAPV_OK;
1918*abb65b4bSAndroid Build Coastguard Worker u32 pbu_size;
1919*abb65b4bSAndroid Build Coastguard Worker u32 remain;
1920*abb65b4bSAndroid Build Coastguard Worker u8 *curpos;
1921*abb65b4bSAndroid Build Coastguard Worker int frame_cnt = 0;
1922*abb65b4bSAndroid Build Coastguard Worker
1923*abb65b4bSAndroid Build Coastguard Worker ctx = dec_id_to_ctx(did);
1924*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx, OAPV_ERR_INVALID_ARGUMENT);
1925*abb65b4bSAndroid Build Coastguard Worker
1926*abb65b4bSAndroid Build Coastguard Worker curpos = (u8 *)bitb->addr;
1927*abb65b4bSAndroid Build Coastguard Worker remain = bitb->ssize;
1928*abb65b4bSAndroid Build Coastguard Worker
1929*abb65b4bSAndroid Build Coastguard Worker while(remain > 8) {
1930*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_init(&ctx->bs, curpos, remain, NULL);
1931*abb65b4bSAndroid Build Coastguard Worker bs = &ctx->bs;
1932*abb65b4bSAndroid Build Coastguard Worker
1933*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_pbu_size(bs, &pbu_size); // 4byte
1934*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1935*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g((pbu_size + 4) <= bs->size, ERR);
1936*abb65b4bSAndroid Build Coastguard Worker
1937*abb65b4bSAndroid Build Coastguard Worker curpos += 4; // pbu_size syntax
1938*abb65b4bSAndroid Build Coastguard Worker remain -= 4;
1939*abb65b4bSAndroid Build Coastguard Worker
1940*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_pbu_header(bs, &pbuh);
1941*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1942*abb65b4bSAndroid Build Coastguard Worker
1943*abb65b4bSAndroid Build Coastguard Worker if(pbuh.pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME ||
1944*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME ||
1945*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_PREVIEW_FRAME ||
1946*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_DEPTH_FRAME ||
1947*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_ALPHA_FRAME) {
1948*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_frame_header(bs, &ctx->fh);
1949*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1950*abb65b4bSAndroid Build Coastguard Worker
1951*abb65b4bSAndroid Build Coastguard Worker ret = dec_frm_prepare(ctx, ofrms->frm[frame_cnt].imgb);
1952*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1953*abb65b4bSAndroid Build Coastguard Worker
1954*abb65b4bSAndroid Build Coastguard Worker int res;
1955*abb65b4bSAndroid Build Coastguard Worker oapv_tpool_t *tpool = ctx->tpool;
1956*abb65b4bSAndroid Build Coastguard Worker int parallel_task = 1;
1957*abb65b4bSAndroid Build Coastguard Worker int tidx = 0;
1958*abb65b4bSAndroid Build Coastguard Worker
1959*abb65b4bSAndroid Build Coastguard Worker parallel_task = (ctx->cdesc.threads > ctx->num_tiles) ? ctx->num_tiles : ctx->cdesc.threads;
1960*abb65b4bSAndroid Build Coastguard Worker
1961*abb65b4bSAndroid Build Coastguard Worker /* decode tiles ************************************/
1962*abb65b4bSAndroid Build Coastguard Worker for(tidx = 0; tidx < (parallel_task - 1); tidx++) {
1963*abb65b4bSAndroid Build Coastguard Worker tpool->run(ctx->thread_id[tidx], dec_thread_tile,
1964*abb65b4bSAndroid Build Coastguard Worker (void *)ctx->core[tidx]);
1965*abb65b4bSAndroid Build Coastguard Worker }
1966*abb65b4bSAndroid Build Coastguard Worker ret = dec_thread_tile((void *)ctx->core[tidx]);
1967*abb65b4bSAndroid Build Coastguard Worker for(tidx = 0; tidx < parallel_task - 1; tidx++) {
1968*abb65b4bSAndroid Build Coastguard Worker tpool->join(ctx->thread_id[tidx], &res);
1969*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(res)) {
1970*abb65b4bSAndroid Build Coastguard Worker ret = res;
1971*abb65b4bSAndroid Build Coastguard Worker }
1972*abb65b4bSAndroid Build Coastguard Worker }
1973*abb65b4bSAndroid Build Coastguard Worker /****************************************************/
1974*abb65b4bSAndroid Build Coastguard Worker
1975*abb65b4bSAndroid Build Coastguard Worker /* READ FILLER HERE !!! */
1976*abb65b4bSAndroid Build Coastguard Worker
1977*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_move(&ctx->bs, ctx->tile_end);
1978*abb65b4bSAndroid Build Coastguard Worker stat->read += bsr_get_read_byte(&ctx->bs);
1979*abb65b4bSAndroid Build Coastguard Worker
1980*abb65b4bSAndroid Build Coastguard Worker copy_fi_to_finfo(&ctx->fh.fi, pbuh.pbu_type, pbuh.group_id, &stat->aui.frm_info[frame_cnt]);
1981*abb65b4bSAndroid Build Coastguard Worker if(ret == OAPV_OK && ctx->use_frm_hash) {
1982*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_set_md5(ctx->imgb);
1983*abb65b4bSAndroid Build Coastguard Worker }
1984*abb65b4bSAndroid Build Coastguard Worker ret = dec_frm_finish(ctx); // FIX-ME
1985*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1986*abb65b4bSAndroid Build Coastguard Worker
1987*abb65b4bSAndroid Build Coastguard Worker ofrms->frm[frame_cnt].pbu_type = pbuh.pbu_type;
1988*abb65b4bSAndroid Build Coastguard Worker ofrms->frm[frame_cnt].group_id = pbuh.group_id;
1989*abb65b4bSAndroid Build Coastguard Worker stat->frm_size[frame_cnt] = pbu_size + 4 /* PUB size length*/;
1990*abb65b4bSAndroid Build Coastguard Worker frame_cnt++;
1991*abb65b4bSAndroid Build Coastguard Worker }
1992*abb65b4bSAndroid Build Coastguard Worker else if(pbuh.pbu_type == OAPV_PBU_TYPE_METADATA) {
1993*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_metadata(bs, pbu_size, mid, pbuh.group_id);
1994*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1995*abb65b4bSAndroid Build Coastguard Worker
1996*abb65b4bSAndroid Build Coastguard Worker stat->read += bsr_get_read_byte(&ctx->bs);
1997*abb65b4bSAndroid Build Coastguard Worker }
1998*abb65b4bSAndroid Build Coastguard Worker else if(pbuh.pbu_type == OAPV_PBU_TYPE_FILLER) {
1999*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_filler(bs, (pbu_size - 4));
2000*abb65b4bSAndroid Build Coastguard Worker oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
2001*abb65b4bSAndroid Build Coastguard Worker }
2002*abb65b4bSAndroid Build Coastguard Worker curpos += pbu_size;
2003*abb65b4bSAndroid Build Coastguard Worker remain = (remain < pbu_size)? 0: (remain - pbu_size);
2004*abb65b4bSAndroid Build Coastguard Worker }
2005*abb65b4bSAndroid Build Coastguard Worker stat->aui.num_frms = frame_cnt;
2006*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ofrms->num_frms == frame_cnt, OAPV_ERR_MALFORMED_BITSTREAM);
2007*abb65b4bSAndroid Build Coastguard Worker return ret;
2008*abb65b4bSAndroid Build Coastguard Worker
2009*abb65b4bSAndroid Build Coastguard Worker ERR:
2010*abb65b4bSAndroid Build Coastguard Worker return ret;
2011*abb65b4bSAndroid Build Coastguard Worker }
2012*abb65b4bSAndroid Build Coastguard Worker
oapvd_config(oapvd_t did,int cfg,void * buf,int * size)2013*abb65b4bSAndroid Build Coastguard Worker int oapvd_config(oapvd_t did, int cfg, void *buf, int *size)
2014*abb65b4bSAndroid Build Coastguard Worker {
2015*abb65b4bSAndroid Build Coastguard Worker oapvd_ctx_t *ctx;
2016*abb65b4bSAndroid Build Coastguard Worker
2017*abb65b4bSAndroid Build Coastguard Worker ctx = dec_id_to_ctx(did);
2018*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(ctx, OAPV_ERR_INVALID_ARGUMENT);
2019*abb65b4bSAndroid Build Coastguard Worker
2020*abb65b4bSAndroid Build Coastguard Worker switch(cfg) {
2021*abb65b4bSAndroid Build Coastguard Worker /* set config ************************************************************/
2022*abb65b4bSAndroid Build Coastguard Worker case OAPV_CFG_SET_USE_FRM_HASH:
2023*abb65b4bSAndroid Build Coastguard Worker ctx->use_frm_hash = (*((int *)buf)) ? 1 : 0;
2024*abb65b4bSAndroid Build Coastguard Worker break;
2025*abb65b4bSAndroid Build Coastguard Worker
2026*abb65b4bSAndroid Build Coastguard Worker default:
2027*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(0, OAPV_ERR_UNSUPPORTED);
2028*abb65b4bSAndroid Build Coastguard Worker }
2029*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
2030*abb65b4bSAndroid Build Coastguard Worker }
2031*abb65b4bSAndroid Build Coastguard Worker
oapvd_info(void * au,int au_size,oapv_au_info_t * aui)2032*abb65b4bSAndroid Build Coastguard Worker int oapvd_info(void *au, int au_size, oapv_au_info_t *aui)
2033*abb65b4bSAndroid Build Coastguard Worker {
2034*abb65b4bSAndroid Build Coastguard Worker int ret, frm_count = 0;
2035*abb65b4bSAndroid Build Coastguard Worker int pbu_cnt = 0;
2036*abb65b4bSAndroid Build Coastguard Worker u8 *curpos;
2037*abb65b4bSAndroid Build Coastguard Worker u32 remain;
2038*abb65b4bSAndroid Build Coastguard Worker
2039*abb65b4bSAndroid Build Coastguard Worker curpos = (u8 *)au;
2040*abb65b4bSAndroid Build Coastguard Worker remain = au_size;
2041*abb65b4bSAndroid Build Coastguard Worker
2042*abb65b4bSAndroid Build Coastguard Worker DUMP_SET(0);
2043*abb65b4bSAndroid Build Coastguard Worker while(remain > 8) // FIX-ME (8byte?)
2044*abb65b4bSAndroid Build Coastguard Worker {
2045*abb65b4bSAndroid Build Coastguard Worker oapv_bs_t bs;
2046*abb65b4bSAndroid Build Coastguard Worker u32 pbu_size = 0;
2047*abb65b4bSAndroid Build Coastguard Worker
2048*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_init(&bs, curpos, remain, NULL);
2049*abb65b4bSAndroid Build Coastguard Worker
2050*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_pbu_size(&bs, &pbu_size); // 4 byte
2051*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
2052*abb65b4bSAndroid Build Coastguard Worker curpos += 4; // pbu_size syntax
2053*abb65b4bSAndroid Build Coastguard Worker remain -= 4;
2054*abb65b4bSAndroid Build Coastguard Worker
2055*abb65b4bSAndroid Build Coastguard Worker /* pbu header */
2056*abb65b4bSAndroid Build Coastguard Worker oapv_pbuh_t pbuh;
2057*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_pbu_header(&bs, &pbuh); // 4 byte
2058*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), OAPV_ERR_MALFORMED_BITSTREAM);
2059*abb65b4bSAndroid Build Coastguard Worker if(pbuh.pbu_type == OAPV_PBU_TYPE_AU_INFO) {
2060*abb65b4bSAndroid Build Coastguard Worker // parse access_unit_info in PBU
2061*abb65b4bSAndroid Build Coastguard Worker oapv_aui_t ai;
2062*abb65b4bSAndroid Build Coastguard Worker
2063*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_au_info(&bs, &ai);
2064*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
2065*abb65b4bSAndroid Build Coastguard Worker
2066*abb65b4bSAndroid Build Coastguard Worker aui->num_frms = ai.num_frames;
2067*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ai.num_frames; i++) {
2068*abb65b4bSAndroid Build Coastguard Worker copy_fi_to_finfo(&ai.frame_info[i], ai.pbu_type[i], ai.group_id[i], &aui->frm_info[i]);
2069*abb65b4bSAndroid Build Coastguard Worker }
2070*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK; // founded access_unit_info, no need to read more PBUs
2071*abb65b4bSAndroid Build Coastguard Worker }
2072*abb65b4bSAndroid Build Coastguard Worker if(pbuh.pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME ||
2073*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME ||
2074*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_PREVIEW_FRAME ||
2075*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_DEPTH_FRAME ||
2076*abb65b4bSAndroid Build Coastguard Worker pbuh.pbu_type == OAPV_PBU_TYPE_ALPHA_FRAME) {
2077*abb65b4bSAndroid Build Coastguard Worker // parse frame_info in PBU
2078*abb65b4bSAndroid Build Coastguard Worker oapv_fi_t fi;
2079*abb65b4bSAndroid Build Coastguard Worker
2080*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(frm_count < OAPV_MAX_NUM_FRAMES, OAPV_ERR_REACHED_MAX)
2081*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_vlc_frame_info(&bs, &fi);
2082*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
2083*abb65b4bSAndroid Build Coastguard Worker
2084*abb65b4bSAndroid Build Coastguard Worker copy_fi_to_finfo(&fi, pbuh.pbu_type, pbuh.group_id, &aui->frm_info[frm_count]);
2085*abb65b4bSAndroid Build Coastguard Worker frm_count++;
2086*abb65b4bSAndroid Build Coastguard Worker }
2087*abb65b4bSAndroid Build Coastguard Worker aui->num_frms = frm_count;
2088*abb65b4bSAndroid Build Coastguard Worker
2089*abb65b4bSAndroid Build Coastguard Worker curpos += pbu_size;
2090*abb65b4bSAndroid Build Coastguard Worker remain = (remain < pbu_size)? 0: (remain - pbu_size);
2091*abb65b4bSAndroid Build Coastguard Worker ++pbu_cnt;
2092*abb65b4bSAndroid Build Coastguard Worker }
2093*abb65b4bSAndroid Build Coastguard Worker DUMP_SET(1);
2094*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
2095*abb65b4bSAndroid Build Coastguard Worker }
2096*abb65b4bSAndroid Build Coastguard Worker
2097*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
2098*abb65b4bSAndroid Build Coastguard Worker // end of decoder code
2099*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_DECODER
2100*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////