1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "onyx_int.h"
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/threading.h"
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/common.h"
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp8/common/extend.h"
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "bitstream.h"
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "encodeframe.h"
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_MULTITHREAD
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan
20233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip);
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan
22233d2500723e5594f3e7c70896ffeeef32b9c950ywanextern void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan
24233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic THREAD_FUNCTION thread_loopfilter(void *p_data)
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VP8_COMP *cpi = (VP8_COMP *)(((LPFTHREAD_DATA *)p_data)->ptr1);
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VP8_COMMON *cm = &cpi->common;
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan    while (1)
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (cpi->b_multi_threaded == 0)
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (sem_wait(&cpi->h_event_start_lpf) == 0)
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (cpi->b_multi_threaded == 0) /* we're shutting down */
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan                break;
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_loopfilter_frame(cpi, cm);
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_post(&cpi->h_event_end_lpf);
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan
48233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic
49233d2500723e5594f3e7c70896ffeeef32b9c950ywanTHREAD_FUNCTION thread_encoding_proc(void *p_data)
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread;
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VP8_COMP *cpi = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1);
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2);
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ENTROPY_CONTEXT_PLANES mb_row_left_context;
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan    while (1)
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (cpi->b_multi_threaded == 0)
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (sem_wait(&cpi->h_event_start_encoding[ithread]) == 0)
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int nsync = cpi->mt_sync_range;
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan            VP8_COMMON *cm = &cpi->common;
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int mb_row;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan            MACROBLOCK *x = &mbri->mb;
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan            MACROBLOCKD *xd = &x->e_mbd;
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan            TOKENEXTRA *tp ;
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan            TOKENEXTRA *tp_start = cpi->tok + (1 + ithread) * (16 * 24);
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int num_part = (1 << cm->multi_token_partition);
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int *segment_counts = mbri->segment_counts;
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int *totalrate = &mbri->totalrate;
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (cpi->b_multi_threaded == 0) /* we're shutting down */
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan                break;
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan            for (mb_row = ithread + 1; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int recon_yoffset, recon_uvoffset;
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int mb_col;
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int ref_fb_idx = cm->lst_fb_idx;
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int dst_fb_idx = cm->new_fb_idx;
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan                int map_index = (mb_row * cm->mb_cols);
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan                volatile const int *last_row_current_mb_col;
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan                volatile int *current_mb_col = &cpi->mt_current_mb_col[mb_row];
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if  (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vp8_writer *w = &cpi->bc[1 + (mb_row % num_part)];
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan                tp = cpi->tok + (mb_row * (cm->mb_cols * 16 * 24));
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan                cpi->tplist[mb_row].start = tp;
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan                last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* reset above block coeffs */
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan                xd->above_context = cm->above_context;
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan                xd->left_context = &mb_row_left_context;
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vp8_zero(mb_row_left_context);
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan                xd->up_available = (mb_row != 0);
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan                recon_yoffset = (mb_row * recon_y_stride * 16);
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan                recon_uvoffset = (mb_row * recon_uv_stride * 8);
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* Set the mb activity pointer to the start of the row. */
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->mb_activity_ptr = &cpi->mb_activity_map[map_index];
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* for each macroblock col in image */
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan                for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan                {
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    *current_mb_col = mb_col - 1;
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    if ((mb_col & (nsync - 1)) == 0)
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    {
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        while (mb_col > (*last_row_current_mb_col - nsync))
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        {
124233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            x86_pause_hint();
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            thread_sleep(0);
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        }
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    }
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    tp = tp_start;
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
132233d2500723e5594f3e7c70896ffeeef32b9c950ywan
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Distance of Mb to the various image edges.
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     * These specified to 8th pel as they are always compared
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     * to values that are in 1/8th pel units
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     */
137233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->mb_to_left_edge = -((mb_col * 16) << 3);
138233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
139233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->mb_to_top_edge = -((mb_row * 16) << 3);
140233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
141233d2500723e5594f3e7c70896ffeeef32b9c950ywan
142233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Set up limit values for motion vectors used to prevent
143233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     * them extending outside the UMV borders
144233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     */
145233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
146233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
147233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
148233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
149233d2500723e5594f3e7c70896ffeeef32b9c950ywan
150233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
151233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
152233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
153233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->left_available = (mb_col != 0);
154233d2500723e5594f3e7c70896ffeeef32b9c950ywan
155233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->rddiv = cpi->RDDIV;
156233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->rdmult = cpi->RDMULT;
157233d2500723e5594f3e7c70896ffeeef32b9c950ywan
158233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Copy current mb to a buffer */
159233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
160233d2500723e5594f3e7c70896ffeeef32b9c950ywan
161233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
162233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vp8_activity_masking(cpi, x);
163233d2500723e5594f3e7c70896ffeeef32b9c950ywan
164233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Is segmentation enabled */
165233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* MB level adjustment to quantizer */
166233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    if (xd->segmentation_enabled)
167233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    {
168233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        /* Code to set segment id in xd->mbmi.segment_id for
169233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * current MB (with range checking)
170233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         */
171233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        if (cpi->segmentation_map[map_index + mb_col] <= 3)
172233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[map_index + mb_col];
173233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        else
174233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            xd->mode_info_context->mbmi.segment_id = 0;
175233d2500723e5594f3e7c70896ffeeef32b9c950ywan
176233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vp8cx_mb_init_quantizer(cpi, x, 1);
177233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    }
178233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    else
179233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        /* Set to Segment 0 by default */
180233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        xd->mode_info_context->mbmi.segment_id = 0;
181233d2500723e5594f3e7c70896ffeeef32b9c950ywan
182233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->active_ptr = cpi->active_map + map_index + mb_col;
183233d2500723e5594f3e7c70896ffeeef32b9c950ywan
184233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    if (cm->frame_type == KEY_FRAME)
185233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    {
186233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        *totalrate += vp8cx_encode_intra_macroblock(cpi, x, &tp);
187233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef MODE_STATS
188233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        y_modes[xd->mbmi.mode] ++;
189233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
190233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    }
191233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    else
192233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    {
193233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        *totalrate += vp8cx_encode_inter_macroblock(cpi, x, &tp, recon_yoffset, recon_uvoffset, mb_row, mb_col);
194233d2500723e5594f3e7c70896ffeeef32b9c950ywan
195233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef MODE_STATS
196233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        inter_y_modes[xd->mbmi.mode] ++;
197233d2500723e5594f3e7c70896ffeeef32b9c950ywan
198233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        if (xd->mbmi.mode == SPLITMV)
199233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        {
200233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            int b;
201233d2500723e5594f3e7c70896ffeeef32b9c950ywan
202233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            for (b = 0; b < xd->mbmi.partition_count; b++)
203233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            {
204233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                inter_b_modes[x->partition->bmi[b].mode] ++;
205233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            }
206233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        }
207233d2500723e5594f3e7c70896ffeeef32b9c950ywan
208233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
209233d2500723e5594f3e7c70896ffeeef32b9c950ywan
210233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        /* Special case code for cyclic refresh
211233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * If cyclic update enabled then copy
212233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * xd->mbmi.segment_id; (which may have been updated
213233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * based on mode during
214233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * vp8cx_encode_inter_macroblock()) back into the
215233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         * global segmentation map
216233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         */
217233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        if ((cpi->current_layer == 0) &&
218233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            (cpi->cyclic_refresh_mode_enabled &&
219233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             xd->segmentation_enabled))
220233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        {
221233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            const MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
222233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            cpi->segmentation_map[map_index + mb_col] = mbmi->segment_id;
223233d2500723e5594f3e7c70896ffeeef32b9c950ywan
224233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            /* If the block has been refreshed mark it as clean
225233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * (the magnitude of the -ve influences how long it
226233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * will be before we consider another refresh):
227233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * Else if it was coded (last frame 0,0) and has
228233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * not already been refreshed then mark it as a
229233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * candidate for cleanup next time (marked 0) else
230233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             * mark it as dirty (1).
231233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             */
232233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            if (mbmi->segment_id)
233233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                cpi->cyclic_refresh_map[map_index + mb_col] = -1;
234233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            else if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
235233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            {
236233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                if (cpi->cyclic_refresh_map[map_index + mb_col] == 1)
237233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    cpi->cyclic_refresh_map[map_index + mb_col] = 0;
238233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            }
239233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            else
240233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                cpi->cyclic_refresh_map[map_index + mb_col] = 1;
241233d2500723e5594f3e7c70896ffeeef32b9c950ywan
242233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        }
243233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    }
244233d2500723e5594f3e7c70896ffeeef32b9c950ywan
245233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
246233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* pack tokens for this MB */
247233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    {
248233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        int tok_count = tp - tp_start;
249233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        pack_tokens(w, tp_start, tok_count);
250233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    }
251233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else
252233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    cpi->tplist[mb_row].stop = tp;
253233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
254233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Increment pointer into gf usage flags structure. */
255233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->gf_active_ptr++;
256233d2500723e5594f3e7c70896ffeeef32b9c950ywan
257233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Increment the activity mask pointers. */
258233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->mb_activity_ptr++;
259233d2500723e5594f3e7c70896ffeeef32b9c950ywan
260233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* adjust to the next column of macroblocks */
261233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->src.y_buffer += 16;
262233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->src.u_buffer += 8;
263233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->src.v_buffer += 8;
264233d2500723e5594f3e7c70896ffeeef32b9c950ywan
265233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    recon_yoffset += 16;
266233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    recon_uvoffset += 8;
267233d2500723e5594f3e7c70896ffeeef32b9c950ywan
268233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* Keep track of segment usage */
269233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    segment_counts[xd->mode_info_context->mbmi.segment_id]++;
270233d2500723e5594f3e7c70896ffeeef32b9c950ywan
271233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    /* skip to next mb */
272233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->mode_info_context++;
273233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    x->partition_info++;
274233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    xd->above_context++;
275233d2500723e5594f3e7c70896ffeeef32b9c950ywan                }
276233d2500723e5594f3e7c70896ffeeef32b9c950ywan
277233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vp8_extend_mb_row( &cm->yv12_fb[dst_fb_idx],
278233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    xd->dst.y_buffer + 16,
279233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    xd->dst.u_buffer + 8,
280233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    xd->dst.v_buffer + 8);
281233d2500723e5594f3e7c70896ffeeef32b9c950ywan
282233d2500723e5594f3e7c70896ffeeef32b9c950ywan                *current_mb_col = mb_col + nsync;
283233d2500723e5594f3e7c70896ffeeef32b9c950ywan
284233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* this is to account for the border */
285233d2500723e5594f3e7c70896ffeeef32b9c950ywan                xd->mode_info_context++;
286233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->partition_info++;
287233d2500723e5594f3e7c70896ffeeef32b9c950ywan
288233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
289233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
290233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
291233d2500723e5594f3e7c70896ffeeef32b9c950ywan
292233d2500723e5594f3e7c70896ffeeef32b9c950ywan                xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
293233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count;
294233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->gf_active_ptr   += cm->mb_cols * cpi->encoding_thread_count;
295233d2500723e5594f3e7c70896ffeeef32b9c950ywan
296233d2500723e5594f3e7c70896ffeeef32b9c950ywan                if (mb_row == cm->mb_rows - 1)
297233d2500723e5594f3e7c70896ffeeef32b9c950ywan                {
298233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
299233d2500723e5594f3e7c70896ffeeef32b9c950ywan                }
300233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
301233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
302233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
303233d2500723e5594f3e7c70896ffeeef32b9c950ywan
304233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* printf("exit thread %d\n", ithread); */
305233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
306233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
307233d2500723e5594f3e7c70896ffeeef32b9c950ywan
308233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc)
309233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
310233d2500723e5594f3e7c70896ffeeef32b9c950ywan
311233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MACROBLOCK *x = mbsrc;
312233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MACROBLOCK *z = mbdst;
313233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
314233d2500723e5594f3e7c70896ffeeef32b9c950ywan
315233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->ss               = x->ss;
316233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->ss_count          = x->ss_count;
317233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->searches_per_step  = x->searches_per_step;
318233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->errorperbit      = x->errorperbit;
319233d2500723e5594f3e7c70896ffeeef32b9c950ywan
320233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->sadperbit16      = x->sadperbit16;
321233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->sadperbit4       = x->sadperbit4;
322233d2500723e5594f3e7c70896ffeeef32b9c950ywan
323233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /*
324233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mv_col_min    = x->mv_col_min;
325233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mv_col_max    = x->mv_col_max;
326233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mv_row_min    = x->mv_row_min;
327233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mv_row_max    = x->mv_row_max;
328233d2500723e5594f3e7c70896ffeeef32b9c950ywan    */
329233d2500723e5594f3e7c70896ffeeef32b9c950ywan
330233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->short_fdct4x4     = x->short_fdct4x4;
331233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->short_fdct8x4     = x->short_fdct8x4;
332233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->short_walsh4x4    = x->short_walsh4x4;
333233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->quantize_b        = x->quantize_b;
334233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->quantize_b_pair   = x->quantize_b_pair;
335233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->optimize          = x->optimize;
336233d2500723e5594f3e7c70896ffeeef32b9c950ywan
337233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /*
338233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mvc              = x->mvc;
339233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->src.y_buffer      = x->src.y_buffer;
340233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->src.u_buffer      = x->src.u_buffer;
341233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->src.v_buffer      = x->src.v_buffer;
342233d2500723e5594f3e7c70896ffeeef32b9c950ywan    */
343233d2500723e5594f3e7c70896ffeeef32b9c950ywan
344233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mvcost[0] =  x->mvcost[0];
345233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mvcost[1] =  x->mvcost[1];
346233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mvsadcost[0] =  x->mvsadcost[0];
347233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mvsadcost[1] =  x->mvsadcost[1];
348233d2500723e5594f3e7c70896ffeeef32b9c950ywan
349233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->token_costs = x->token_costs;
350233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->inter_bmode_costs = x->inter_bmode_costs;
351233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->mbmode_cost = x->mbmode_cost;
352233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->intra_uv_mode_cost = x->intra_uv_mode_cost;
353233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->bmode_costs = x->bmode_costs;
354233d2500723e5594f3e7c70896ffeeef32b9c950ywan
355233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < 25; i++)
356233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
357233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].quant           = x->block[i].quant;
358233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].quant_fast      = x->block[i].quant_fast;
359233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].quant_shift     = x->block[i].quant_shift;
360233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].zbin            = x->block[i].zbin;
361233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].zrun_zbin_boost = x->block[i].zrun_zbin_boost;
362233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].round           = x->block[i].round;
363233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->block[i].src_stride      = x->block[i].src_stride;
364233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
365233d2500723e5594f3e7c70896ffeeef32b9c950ywan
366233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->q_index           = x->q_index;
367233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->act_zbin_adj      = x->act_zbin_adj;
368233d2500723e5594f3e7c70896ffeeef32b9c950ywan    z->last_act_zbin_adj = x->last_act_zbin_adj;
369233d2500723e5594f3e7c70896ffeeef32b9c950ywan
370233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
371233d2500723e5594f3e7c70896ffeeef32b9c950ywan        MACROBLOCKD *xd = &x->e_mbd;
372233d2500723e5594f3e7c70896ffeeef32b9c950ywan        MACROBLOCKD *zd = &z->e_mbd;
373233d2500723e5594f3e7c70896ffeeef32b9c950ywan
374233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /*
375233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mode_info_context = xd->mode_info_context;
376233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mode_info        = xd->mode_info;
377233d2500723e5594f3e7c70896ffeeef32b9c950ywan
378233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mode_info_stride  = xd->mode_info_stride;
379233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->frame_type       = xd->frame_type;
380233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->up_available     = xd->up_available   ;
381233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->left_available   = xd->left_available;
382233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->left_context     = xd->left_context;
383233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->last_frame_dc     = xd->last_frame_dc;
384233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->last_frame_dccons = xd->last_frame_dccons;
385233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->gold_frame_dc     = xd->gold_frame_dc;
386233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->gold_frame_dccons = xd->gold_frame_dccons;
387233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mb_to_left_edge    = xd->mb_to_left_edge;
388233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mb_to_right_edge   = xd->mb_to_right_edge;
389233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mb_to_top_edge     = xd->mb_to_top_edge   ;
390233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mb_to_bottom_edge  = xd->mb_to_bottom_edge;
391233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->gf_active_ptr     = xd->gf_active_ptr;
392233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->frames_since_golden       = xd->frames_since_golden;
393233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->frames_till_alt_ref_frame   = xd->frames_till_alt_ref_frame;
394233d2500723e5594f3e7c70896ffeeef32b9c950ywan        */
395233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->subpixel_predict         = xd->subpixel_predict;
396233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->subpixel_predict8x4      = xd->subpixel_predict8x4;
397233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->subpixel_predict8x8      = xd->subpixel_predict8x8;
398233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
399233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->segmentation_enabled     = xd->segmentation_enabled;
400233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
401233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data,
402233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(xd->segment_feature_data));
403233d2500723e5594f3e7c70896ffeeef32b9c950ywan
404233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc,
405233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(xd->dequant_y1_dc));
406233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(zd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
407233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(zd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
408233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(zd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));
409233d2500723e5594f3e7c70896ffeeef32b9c950ywan
410233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 1
411233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until
412233d2500723e5594f3e7c70896ffeeef32b9c950ywan         * the quantizer code uses a passed in pointer to the dequant constants.
413233d2500723e5594f3e7c70896ffeeef32b9c950ywan         * This will also require modifications to the x86 and neon assembly.
414233d2500723e5594f3e7c70896ffeeef32b9c950ywan         * */
415233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < 16; i++)
416233d2500723e5594f3e7c70896ffeeef32b9c950ywan            zd->block[i].dequant = zd->dequant_y1;
417233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 16; i < 24; i++)
418233d2500723e5594f3e7c70896ffeeef32b9c950ywan            zd->block[i].dequant = zd->dequant_uv;
419233d2500723e5594f3e7c70896ffeeef32b9c950ywan        zd->block[24].dequant = zd->dequant_y2;
420233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
421233d2500723e5594f3e7c70896ffeeef32b9c950ywan
422233d2500723e5594f3e7c70896ffeeef32b9c950ywan
423233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(z->rd_threshes, x->rd_threshes, sizeof(x->rd_threshes));
424233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(z->rd_thresh_mult, x->rd_thresh_mult,
425233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(x->rd_thresh_mult));
426233d2500723e5594f3e7c70896ffeeef32b9c950ywan
427233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->zbin_over_quant = x->zbin_over_quant;
428233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->zbin_mode_boost_enabled = x->zbin_mode_boost_enabled;
429233d2500723e5594f3e7c70896ffeeef32b9c950ywan        z->zbin_mode_boost = x->zbin_mode_boost;
430233d2500723e5594f3e7c70896ffeeef32b9c950ywan
431233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memset(z->error_bins, 0, sizeof(z->error_bins));
432233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
433233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
434233d2500723e5594f3e7c70896ffeeef32b9c950ywan
435233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8cx_init_mbrthread_data(VP8_COMP *cpi,
436233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               MACROBLOCK *x,
437233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               MB_ROW_COMP *mbr_ei,
438233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               int count
439233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              )
440233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
441233d2500723e5594f3e7c70896ffeeef32b9c950ywan
442233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VP8_COMMON *const cm = & cpi->common;
443233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MACROBLOCKD *const xd = & x->e_mbd;
444233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
445233d2500723e5594f3e7c70896ffeeef32b9c950ywan
446233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < count; i++)
447233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
448233d2500723e5594f3e7c70896ffeeef32b9c950ywan        MACROBLOCK *mb = & mbr_ei[i].mb;
449233d2500723e5594f3e7c70896ffeeef32b9c950ywan        MACROBLOCKD *mbd = &mb->e_mbd;
450233d2500723e5594f3e7c70896ffeeef32b9c950ywan
451233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->subpixel_predict        = xd->subpixel_predict;
452233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
453233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
454233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
455233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->gf_active_ptr            = x->gf_active_ptr;
456233d2500723e5594f3e7c70896ffeeef32b9c950ywan
457233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
458233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbr_ei[i].totalrate = 0;
459233d2500723e5594f3e7c70896ffeeef32b9c950ywan
460233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1);
461233d2500723e5594f3e7c70896ffeeef32b9c950ywan
462233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->mode_info_context = cm->mi   + x->e_mbd.mode_info_stride * (i + 1);
463233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->mode_info_stride  = cm->mode_info_stride;
464233d2500723e5594f3e7c70896ffeeef32b9c950ywan
465233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->frame_type = cm->frame_type;
466233d2500723e5594f3e7c70896ffeeef32b9c950ywan
467233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->src = * cpi->Source;
468233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->pre = cm->yv12_fb[cm->lst_fb_idx];
469233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->dst = cm->yv12_fb[cm->new_fb_idx];
470233d2500723e5594f3e7c70896ffeeef32b9c950ywan
471233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->src.y_buffer += 16 * x->src.y_stride * (i + 1);
472233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->src.u_buffer +=  8 * x->src.uv_stride * (i + 1);
473233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->src.v_buffer +=  8 * x->src.uv_stride * (i + 1);
474233d2500723e5594f3e7c70896ffeeef32b9c950ywan
475233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_build_block_offsets(mb);
476233d2500723e5594f3e7c70896ffeeef32b9c950ywan
477233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->left_context = &cm->left_context;
478233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->mvc = cm->fc.mvc;
479233d2500723e5594f3e7c70896ffeeef32b9c950ywan
480233d2500723e5594f3e7c70896ffeeef32b9c950ywan        setup_mbby_copy(&mbr_ei[i].mb, x);
481233d2500723e5594f3e7c70896ffeeef32b9c950ywan
482233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbd->fullpixel_mask = 0xffffffff;
483233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if(cm->full_pixel)
484233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mbd->fullpixel_mask = 0xfffffff8;
485233d2500723e5594f3e7c70896ffeeef32b9c950ywan
486233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_zero(mb->coef_counts);
487233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_zero(x->ymode_count);
488233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->skip_true_count = 0;
489233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_zero(mb->MVcount);
490233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->prediction_error = 0;
491233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->intra_error = 0;
492233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp8_zero(mb->count_mb_ref_frame_usage);
493233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mb->mbs_tested_so_far = 0;
494233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
495233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
496233d2500723e5594f3e7c70896ffeeef32b9c950ywan
497233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp8cx_create_encoder_threads(VP8_COMP *cpi)
498233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
499233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const VP8_COMMON * cm = &cpi->common;
500233d2500723e5594f3e7c70896ffeeef32b9c950ywan
501233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->b_multi_threaded = 0;
502233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->encoding_thread_count = 0;
503233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->b_lpf_running = 0;
504233d2500723e5594f3e7c70896ffeeef32b9c950ywan
505233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1)
506233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
507233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int ithread;
508233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int th_count = cpi->oxcf.multi_threaded - 1;
509233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int rc = 0;
510233d2500723e5594f3e7c70896ffeeef32b9c950ywan
511233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /* don't allocate more threads than cores available */
512233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (cpi->oxcf.multi_threaded > cm->processor_core_count)
513233d2500723e5594f3e7c70896ffeeef32b9c950ywan            th_count = cm->processor_core_count - 1;
514233d2500723e5594f3e7c70896ffeeef32b9c950ywan
515233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /* we have th_count + 1 (main) threads processing one row each */
516233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /* no point to have more threads than the sync range allows */
517233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if(th_count > ((cm->mb_cols / cpi->mt_sync_range) - 1))
518233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
519233d2500723e5594f3e7c70896ffeeef32b9c950ywan            th_count = (cm->mb_cols / cpi->mt_sync_range) - 1;
520233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
521233d2500723e5594f3e7c70896ffeeef32b9c950ywan
522233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if(th_count == 0)
523233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return 0;
524233d2500723e5594f3e7c70896ffeeef32b9c950ywan
525233d2500723e5594f3e7c70896ffeeef32b9c950ywan        CHECK_MEM_ERROR(cpi->h_encoding_thread,
526233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vpx_malloc(sizeof(pthread_t) * th_count));
527233d2500723e5594f3e7c70896ffeeef32b9c950ywan        CHECK_MEM_ERROR(cpi->h_event_start_encoding,
528233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vpx_malloc(sizeof(sem_t) * th_count));
529233d2500723e5594f3e7c70896ffeeef32b9c950ywan        CHECK_MEM_ERROR(cpi->mb_row_ei,
530233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
531233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
532233d2500723e5594f3e7c70896ffeeef32b9c950ywan        CHECK_MEM_ERROR(cpi->en_thread_data,
533233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));
534233d2500723e5594f3e7c70896ffeeef32b9c950ywan
535233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sem_init(&cpi->h_event_end_encoding, 0, 0);
536233d2500723e5594f3e7c70896ffeeef32b9c950ywan
537233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->b_multi_threaded = 1;
538233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->encoding_thread_count = th_count;
539233d2500723e5594f3e7c70896ffeeef32b9c950ywan
540233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /*
541233d2500723e5594f3e7c70896ffeeef32b9c950ywan        printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n",
542233d2500723e5594f3e7c70896ffeeef32b9c950ywan               (cpi->encoding_thread_count +1));
543233d2500723e5594f3e7c70896ffeeef32b9c950ywan        */
544233d2500723e5594f3e7c70896ffeeef32b9c950ywan
545233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (ithread = 0; ithread < th_count; ithread++)
546233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
547233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ENCODETHREAD_DATA *ethd = &cpi->en_thread_data[ithread];
548233d2500723e5594f3e7c70896ffeeef32b9c950ywan
549233d2500723e5594f3e7c70896ffeeef32b9c950ywan            /* Setup block ptrs and offsets */
550233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_setup_block_ptrs(&cpi->mb_row_ei[ithread].mb);
551233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp8_setup_block_dptrs(&cpi->mb_row_ei[ithread].mb.e_mbd);
552233d2500723e5594f3e7c70896ffeeef32b9c950ywan
553233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_init(&cpi->h_event_start_encoding[ithread], 0, 0);
554233d2500723e5594f3e7c70896ffeeef32b9c950ywan
555233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ethd->ithread = ithread;
556233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ethd->ptr1 = (void *)cpi;
557233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];
558233d2500723e5594f3e7c70896ffeeef32b9c950ywan
559233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rc = pthread_create(&cpi->h_encoding_thread[ithread], 0,
560233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                thread_encoding_proc, ethd);
561233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if(rc)
562233d2500723e5594f3e7c70896ffeeef32b9c950ywan                break;
563233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
564233d2500723e5594f3e7c70896ffeeef32b9c950ywan
565233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if(rc)
566233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
567233d2500723e5594f3e7c70896ffeeef32b9c950ywan            /* shutdown other threads */
568233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->b_multi_threaded = 0;
569233d2500723e5594f3e7c70896ffeeef32b9c950ywan            for(--ithread; ithread >= 0; ithread--)
570233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
571233d2500723e5594f3e7c70896ffeeef32b9c950ywan                pthread_join(cpi->h_encoding_thread[ithread], 0);
572233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_destroy(&cpi->h_event_start_encoding[ithread]);
573233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
574233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_destroy(&cpi->h_event_end_encoding);
575233d2500723e5594f3e7c70896ffeeef32b9c950ywan
576233d2500723e5594f3e7c70896ffeeef32b9c950ywan            /* free thread related resources */
577233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vpx_free(cpi->h_event_start_encoding);
578233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vpx_free(cpi->h_encoding_thread);
579233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vpx_free(cpi->mb_row_ei);
580233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vpx_free(cpi->en_thread_data);
581233d2500723e5594f3e7c70896ffeeef32b9c950ywan
582233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return -1;
583233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
584233d2500723e5594f3e7c70896ffeeef32b9c950ywan
585233d2500723e5594f3e7c70896ffeeef32b9c950ywan
586233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
587233d2500723e5594f3e7c70896ffeeef32b9c950ywan            LPFTHREAD_DATA * lpfthd = &cpi->lpf_thread_data;
588233d2500723e5594f3e7c70896ffeeef32b9c950ywan
589233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_init(&cpi->h_event_start_lpf, 0, 0);
590233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_init(&cpi->h_event_end_lpf, 0, 0);
591233d2500723e5594f3e7c70896ffeeef32b9c950ywan
592233d2500723e5594f3e7c70896ffeeef32b9c950ywan            lpfthd->ptr1 = (void *)cpi;
593233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter,
594233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                lpfthd);
595233d2500723e5594f3e7c70896ffeeef32b9c950ywan
596233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if(rc)
597233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
598233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* shutdown other threads */
599233d2500723e5594f3e7c70896ffeeef32b9c950ywan                cpi->b_multi_threaded = 0;
600233d2500723e5594f3e7c70896ffeeef32b9c950ywan                for(--ithread; ithread >= 0; ithread--)
601233d2500723e5594f3e7c70896ffeeef32b9c950ywan                {
602233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    sem_post(&cpi->h_event_start_encoding[ithread]);
603233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    pthread_join(cpi->h_encoding_thread[ithread], 0);
604233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    sem_destroy(&cpi->h_event_start_encoding[ithread]);
605233d2500723e5594f3e7c70896ffeeef32b9c950ywan                }
606233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_destroy(&cpi->h_event_end_encoding);
607233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_destroy(&cpi->h_event_end_lpf);
608233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_destroy(&cpi->h_event_start_lpf);
609233d2500723e5594f3e7c70896ffeeef32b9c950ywan
610233d2500723e5594f3e7c70896ffeeef32b9c950ywan                /* free thread related resources */
611233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vpx_free(cpi->h_event_start_encoding);
612233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vpx_free(cpi->h_encoding_thread);
613233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vpx_free(cpi->mb_row_ei);
614233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vpx_free(cpi->en_thread_data);
615233d2500723e5594f3e7c70896ffeeef32b9c950ywan
616233d2500723e5594f3e7c70896ffeeef32b9c950ywan                return -2;
617233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
618233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
619233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
620233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
621233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
622233d2500723e5594f3e7c70896ffeeef32b9c950ywan
623233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp8cx_remove_encoder_threads(VP8_COMP *cpi)
624233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
625233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->b_multi_threaded)
626233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {
627233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /* shutdown other threads */
628233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->b_multi_threaded = 0;
629233d2500723e5594f3e7c70896ffeeef32b9c950ywan        {
630233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int i;
631233d2500723e5594f3e7c70896ffeeef32b9c950ywan
632233d2500723e5594f3e7c70896ffeeef32b9c950ywan            for (i = 0; i < cpi->encoding_thread_count; i++)
633233d2500723e5594f3e7c70896ffeeef32b9c950ywan            {
634233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_post(&cpi->h_event_start_encoding[i]);
635233d2500723e5594f3e7c70896ffeeef32b9c950ywan                pthread_join(cpi->h_encoding_thread[i], 0);
636233d2500723e5594f3e7c70896ffeeef32b9c950ywan
637233d2500723e5594f3e7c70896ffeeef32b9c950ywan                sem_destroy(&cpi->h_event_start_encoding[i]);
638233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
639233d2500723e5594f3e7c70896ffeeef32b9c950ywan
640233d2500723e5594f3e7c70896ffeeef32b9c950ywan            sem_post(&cpi->h_event_start_lpf);
641233d2500723e5594f3e7c70896ffeeef32b9c950ywan            pthread_join(cpi->h_filter_thread, 0);
642233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
643233d2500723e5594f3e7c70896ffeeef32b9c950ywan
644233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sem_destroy(&cpi->h_event_end_encoding);
645233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sem_destroy(&cpi->h_event_end_lpf);
646233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sem_destroy(&cpi->h_event_start_lpf);
647233d2500723e5594f3e7c70896ffeeef32b9c950ywan
648233d2500723e5594f3e7c70896ffeeef32b9c950ywan        /* free thread related resources */
649233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_free(cpi->h_event_start_encoding);
650233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_free(cpi->h_encoding_thread);
651233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_free(cpi->mb_row_ei);
652233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_free(cpi->en_thread_data);
653233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
654233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
655233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
656