1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * H.263 encoder header
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci#ifndef AVCODEC_H263ENC_H
21cabdff1aSopenharmony_ci#define AVCODEC_H263ENC_H
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci#include <stdint.h>
24cabdff1aSopenharmony_ci#include "h263data.h"
25cabdff1aSopenharmony_ci#include "mpegvideoenc.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_civoid ff_h263_encode_init(MpegEncContext *s);
28cabdff1aSopenharmony_civoid ff_h263_encode_picture_header(MpegEncContext *s, int picture_number);
29cabdff1aSopenharmony_civoid ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
30cabdff1aSopenharmony_civoid ff_h263_encode_mb(MpegEncContext *s,
31cabdff1aSopenharmony_ci                       int16_t block[6][64],
32cabdff1aSopenharmony_ci                       int motion_x, int motion_y);
33cabdff1aSopenharmony_civoid ff_h263_encode_mba(MpegEncContext *s);
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_civoid ff_init_qscale_tab(MpegEncContext *s);
36cabdff1aSopenharmony_civoid ff_clean_h263_qscales(MpegEncContext *s);
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_civoid ff_h263_encode_motion(PutBitContext *pb, int val, int f_code);
39cabdff1aSopenharmony_ci
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_cistatic inline int h263_get_motion_length(int val, int f_code)
42cabdff1aSopenharmony_ci{
43cabdff1aSopenharmony_ci    int bit_size, code, sign;
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci    if (val == 0) {
46cabdff1aSopenharmony_ci        return 1; /* ff_mvtab[0][1] */
47cabdff1aSopenharmony_ci    } else {
48cabdff1aSopenharmony_ci        bit_size = f_code - 1;
49cabdff1aSopenharmony_ci        /* modulo encoding */
50cabdff1aSopenharmony_ci        val  = sign_extend(val, 6 + bit_size);
51cabdff1aSopenharmony_ci        sign = val >> 31;
52cabdff1aSopenharmony_ci        val  = (val ^ sign) - sign; /* val = FFABS(val) */
53cabdff1aSopenharmony_ci        val--;
54cabdff1aSopenharmony_ci        code = (val >> bit_size) + 1;
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci        return ff_mvtab[code][1] + 1 + bit_size;
57cabdff1aSopenharmony_ci    }
58cabdff1aSopenharmony_ci}
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_cistatic inline void ff_h263_encode_motion_vector(MpegEncContext * s,
61cabdff1aSopenharmony_ci                                                int x, int y, int f_code)
62cabdff1aSopenharmony_ci{
63cabdff1aSopenharmony_ci    if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) {
64cabdff1aSopenharmony_ci        skip_put_bits(&s->pb,
65cabdff1aSopenharmony_ci                      h263_get_motion_length(x, f_code) +
66cabdff1aSopenharmony_ci                      h263_get_motion_length(y, f_code));
67cabdff1aSopenharmony_ci    } else {
68cabdff1aSopenharmony_ci        ff_h263_encode_motion(&s->pb, x, f_code);
69cabdff1aSopenharmony_ci        ff_h263_encode_motion(&s->pb, y, f_code);
70cabdff1aSopenharmony_ci    }
71cabdff1aSopenharmony_ci}
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_cistatic inline int get_p_cbp(MpegEncContext * s,
74cabdff1aSopenharmony_ci                      int16_t block[6][64],
75cabdff1aSopenharmony_ci                      int motion_x, int motion_y){
76cabdff1aSopenharmony_ci    int cbp;
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_ci    if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
79cabdff1aSopenharmony_ci        int best_cbpy_score = INT_MAX;
80cabdff1aSopenharmony_ci        int best_cbpc_score = INT_MAX;
81cabdff1aSopenharmony_ci        int cbpc = (-1), cbpy = (-1);
82cabdff1aSopenharmony_ci        const int offset = (s->mv_type == MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0);
83cabdff1aSopenharmony_ci        const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci        for (int i = 0; i < 4; i++) {
86cabdff1aSopenharmony_ci            int score = ff_h263_inter_MCBPC_bits[i + offset] * lambda;
87cabdff1aSopenharmony_ci            if (i & 1) score += s->coded_score[5];
88cabdff1aSopenharmony_ci            if (i & 2) score += s->coded_score[4];
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ci            if (score < best_cbpc_score) {
91cabdff1aSopenharmony_ci                best_cbpc_score = score;
92cabdff1aSopenharmony_ci                cbpc = i;
93cabdff1aSopenharmony_ci            }
94cabdff1aSopenharmony_ci        }
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_ci        for (int i = 0; i < 16; i++) {
97cabdff1aSopenharmony_ci            int score= ff_h263_cbpy_tab[i ^ 0xF][1] * lambda;
98cabdff1aSopenharmony_ci            if (i & 1) score += s->coded_score[3];
99cabdff1aSopenharmony_ci            if (i & 2) score += s->coded_score[2];
100cabdff1aSopenharmony_ci            if (i & 4) score += s->coded_score[1];
101cabdff1aSopenharmony_ci            if (i & 8) score += s->coded_score[0];
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci            if (score < best_cbpy_score) {
104cabdff1aSopenharmony_ci                best_cbpy_score = score;
105cabdff1aSopenharmony_ci                cbpy = i;
106cabdff1aSopenharmony_ci            }
107cabdff1aSopenharmony_ci        }
108cabdff1aSopenharmony_ci        cbp = cbpc + 4 * cbpy;
109cabdff1aSopenharmony_ci        if (!(motion_x | motion_y | s->dquant) && s->mv_type == MV_TYPE_16X16) {
110cabdff1aSopenharmony_ci            if (best_cbpy_score + best_cbpc_score + 2 * lambda >= 0)
111cabdff1aSopenharmony_ci                cbp= 0;
112cabdff1aSopenharmony_ci        }
113cabdff1aSopenharmony_ci
114cabdff1aSopenharmony_ci        for (int i = 0; i < 6; i++) {
115cabdff1aSopenharmony_ci            if (s->block_last_index[i] >= 0 && !((cbp >> (5 - i)) & 1)) {
116cabdff1aSopenharmony_ci                s->block_last_index[i] = -1;
117cabdff1aSopenharmony_ci                s->bdsp.clear_block(s->block[i]);
118cabdff1aSopenharmony_ci            }
119cabdff1aSopenharmony_ci        }
120cabdff1aSopenharmony_ci    } else {
121cabdff1aSopenharmony_ci        cbp = 0;
122cabdff1aSopenharmony_ci        for (int i = 0; i < 6; i++) {
123cabdff1aSopenharmony_ci            if (s->block_last_index[i] >= 0)
124cabdff1aSopenharmony_ci                cbp |= 1 << (5 - i);
125cabdff1aSopenharmony_ci        }
126cabdff1aSopenharmony_ci    }
127cabdff1aSopenharmony_ci    return cbp;
128cabdff1aSopenharmony_ci}
129cabdff1aSopenharmony_ci
130cabdff1aSopenharmony_ci#endif
131