summaryrefslogtreecommitdiff
path: root/libavcodec/motion_est.h
blob: d0950bf7e6080449b4e252fa5e5b0b8b81aedc79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Motion estimation
 *
 * 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_MOTION_EST_H
#define AVCODEC_MOTION_EST_H

#include <stdint.h>

#include "avcodec.h"
#include "hpeldsp.h"
#include "qpeldsp.h"

struct MpegEncContext;

#if ARCH_IA64 // Limit static arrays to avoid gcc failing "short data segment overflowed"
#define MAX_MV 1024
#else
#define MAX_MV 4096
#endif
#define MAX_DMV (2*MAX_MV)
#define ME_MAP_SIZE 64

#define FF_ME_ZERO 0
#define FF_ME_EPZS 1
#define FF_ME_XONE 2

/**
 * Motion estimation context.
 */
typedef struct MotionEstContext {
    AVCodecContext *avctx;
    int skip;                       ///< set if ME is skipped for the current MB
    int co_located_mv[4][2];        ///< mv from last P-frame for direct mode ME
    int direct_basis_mv[4][2];
    uint8_t *scratchpad;            /**< data area for the ME algo, so that
                                     * the ME does not need to malloc/free. */
    uint8_t *best_mb;
    uint8_t *temp_mb[2];
    uint8_t *temp;
    int best_bits;
    uint32_t *map;                  ///< map to avoid duplicate evaluations
    uint32_t *score_map;            ///< map to store the scores
    unsigned map_generation;
    int pre_penalty_factor;
    int penalty_factor;             /**< an estimate of the bits required to
                                     * code a given mv value, e.g. (1,0) takes
                                     * more bits than (0,0). We have to
                                     * estimate whether any reduction in
                                     * residual is worth the extra bits. */
    int sub_penalty_factor;
    int mb_penalty_factor;
    int flags;
    int sub_flags;
    int mb_flags;
    int pre_pass;                   ///< = 1 for the pre pass
    int dia_size;
    int xmin;
    int xmax;
    int ymin;
    int ymax;
    int pred_x;
    int pred_y;
    uint8_t *src[4][4];
    uint8_t *ref[4][4];
    int stride;
    int uvstride;
    /* temp variables for picture complexity calculation */
    int64_t mc_mb_var_sum_temp;
    int64_t mb_var_sum_temp;
    int scene_change_score;

    op_pixels_func(*hpel_put)[4];
    op_pixels_func(*hpel_avg)[4];
    qpel_mc_func(*qpel_put)[16];
    qpel_mc_func(*qpel_avg)[16];
    const uint8_t (*mv_penalty)[MAX_DMV * 2 + 1]; ///< bit amount needed to encode a MV
    const uint8_t *current_mv_penalty;
    int (*sub_motion_search)(struct MpegEncContext *s,
                             int *mx_ptr, int *my_ptr, int dmin,
                             int src_index, int ref_index,
                             int size, int h);
} MotionEstContext;

static inline int ff_h263_round_chroma(int x)
{
    //FIXME static or not?
    static const uint8_t h263_chroma_roundtab[16] = {
    //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
        0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
    };
    return h263_chroma_roundtab[x & 0xf] + (x >> 3);
}

int ff_init_me(struct MpegEncContext *s);

void ff_estimate_p_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);
void ff_estimate_b_frame_motion(struct MpegEncContext *s, int mb_x, int mb_y);

int ff_pre_estimate_p_frame_motion(struct MpegEncContext *s,
                                   int mb_x, int mb_y);

int ff_epzs_motion_search(struct MpegEncContext *s, int *mx_ptr, int *my_ptr,
                          int P[10][2], int src_index, int ref_index,
                          const int16_t (*last_mv)[2], int ref_mv_scale,
                          int size, int h);

int ff_get_mb_score(struct MpegEncContext *s, int mx, int my, int src_index,
                    int ref_index, int size, int h, int add_rate);

int ff_get_best_fcode(struct MpegEncContext *s,
                      const int16_t (*mv_table)[2], int type);

void ff_fix_long_p_mvs(struct MpegEncContext *s, int type);
void ff_fix_long_mvs(struct MpegEncContext *s, uint8_t *field_select_table,
                     int field_select, int16_t (*mv_table)[2], int f_code,
                     int type, int truncate);

#endif /* AVCODEC_MOTION_EST_H */