diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-01-28 00:59:24 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-02-13 19:41:43 +0100 |
commit | 20d74fb09dbf133f9de92ed55314c7a547309d84 (patch) | |
tree | 2baf144700f3befc5e66bb4969a0f90fab0b36d7 /libavcodec/h263enc.h | |
parent | 20033c7da4d631385dcb2afc4ed907c3500d8372 (diff) |
avcodec/h263.h: Move encoder-only stuff to a new header h263enc.h
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/h263enc.h')
-rw-r--r-- | libavcodec/h263enc.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/libavcodec/h263enc.h b/libavcodec/h263enc.h new file mode 100644 index 0000000000..31f00665ce --- /dev/null +++ b/libavcodec/h263enc.h @@ -0,0 +1,130 @@ +/* + * H.263 encoder header + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVCODEC_H263ENC_H +#define AVCODEC_H263ENC_H + +#include <stdint.h> +#include "h263data.h" +#include "mpegvideo.h" + +void ff_h263_encode_init(MpegEncContext *s); +void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line); +void ff_h263_encode_mb(MpegEncContext *s, + int16_t block[6][64], + int motion_x, int motion_y); +void ff_h263_encode_mba(MpegEncContext *s); + +void ff_init_qscale_tab(MpegEncContext *s); +void ff_clean_h263_qscales(MpegEncContext *s); + +void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code); + + +static inline int h263_get_motion_length(int val, int f_code) +{ + int bit_size, code, sign; + + if (val == 0) { + return 1; /* ff_mvtab[0][1] */ + } else { + bit_size = f_code - 1; + /* modulo encoding */ + val = sign_extend(val, 6 + bit_size); + sign = val >> 31; + val = (val ^ sign) - sign; /* val = FFABS(val) */ + val--; + code = (val >> bit_size) + 1; + + return ff_mvtab[code][1] + 1 + bit_size; + } +} + +static inline void ff_h263_encode_motion_vector(MpegEncContext * s, + int x, int y, int f_code) +{ + if (s->avctx->flags2 & AV_CODEC_FLAG2_NO_OUTPUT) { + skip_put_bits(&s->pb, + h263_get_motion_length(x, f_code) + + h263_get_motion_length(y, f_code)); + } else { + ff_h263_encode_motion(&s->pb, x, f_code); + ff_h263_encode_motion(&s->pb, y, f_code); + } +} + +static inline int get_p_cbp(MpegEncContext * s, + int16_t block[6][64], + int motion_x, int motion_y){ + int cbp; + + if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) { + int best_cbpy_score = INT_MAX; + int best_cbpc_score = INT_MAX; + int cbpc = (-1), cbpy = (-1); + const int offset = (s->mv_type == MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0); + const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + for (int i = 0; i < 4; i++) { + int score = ff_h263_inter_MCBPC_bits[i + offset] * lambda; + if (i & 1) score += s->coded_score[5]; + if (i & 2) score += s->coded_score[4]; + + if (score < best_cbpc_score) { + best_cbpc_score = score; + cbpc = i; + } + } + + for (int i = 0; i < 16; i++) { + int score= ff_h263_cbpy_tab[i ^ 0xF][1] * lambda; + if (i & 1) score += s->coded_score[3]; + if (i & 2) score += s->coded_score[2]; + if (i & 4) score += s->coded_score[1]; + if (i & 8) score += s->coded_score[0]; + + if (score < best_cbpy_score) { + best_cbpy_score = score; + cbpy = i; + } + } + cbp = cbpc + 4 * cbpy; + if (!(motion_x | motion_y | s->dquant) && s->mv_type == MV_TYPE_16X16) { + if (best_cbpy_score + best_cbpc_score + 2 * lambda >= 0) + cbp= 0; + } + + for (int i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0 && !((cbp >> (5 - i)) & 1)) { + s->block_last_index[i] = -1; + s->bdsp.clear_block(s->block[i]); + } + } + } else { + cbp = 0; + for (int i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + } + return cbp; +} + +#endif |