summaryrefslogtreecommitdiff
path: root/libavcodec/motion_est.h
blob: 3b63972d6e830c72d06a0ab75972c2c93c2af19b (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
/*
 * Motion estimation
 *
 * This file is part of Libav.
 *
 * Libav 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.
 *
 * Libav 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 Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef AVCODEC_MOTIONEST_H
#define AVCODEC_MOTIONEST_H

#include <stdint.h>

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

struct MpegEncContext;

#define MAX_MV 2048
#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 */
    int mc_mb_var_sum_temp;
    int 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];
    uint8_t (*mv_penalty)[MAX_MV * 2 + 1]; ///< bit amount needed to encode a MV
    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,
                          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,
                      int16_t (*mv_table)[2], int type);

void ff_fix_long_p_mvs(struct MpegEncContext *s);
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_MOTIONEST_H */