Statistics
| Branch: | Revision:

ffmpeg / libavcodec / h264_hl_motion.c @ a50f0bea

History | View | Annotate | Download (6.41 KB)

1

    
2
#include "h264.h"
3
#include "thread.h"
4

    
5
static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n, int height,
6
                                 int y_offset, int list){
7
    int raw_my= h->mv_cache[list][ scan8[n] ][1];
8
    int filter_height= (raw_my&3) ? 2 : 0;
9
    int full_my= (raw_my>>2) + y_offset;
10
    int top = full_my - filter_height, bottom = full_my + height + filter_height;
11

    
12
    return FFMAX(abs(top), bottom);
13
}
14

    
15
static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, int height,
16
                               int y_offset, int list0, int list1, int *nrefs){
17
    MpegEncContext * const s = &h->s;
18
    int my;
19

    
20
    y_offset += 16*(s->mb_y >> MB_FIELD);
21

    
22
    if(list0){
23
        int ref_n = h->ref_cache[0][ scan8[n] ];
24
        Picture *ref= &h->ref_list[0][ref_n];
25

    
26
        // Error resilience puts the current picture in the ref list.
27
        // Don't try to wait on these as it will cause a deadlock.
28
        // Fields can wait on each other, though.
29
        if(ref->thread_opaque != s->current_picture.thread_opaque ||
30
           (ref->reference&3) != s->picture_structure) {
31
            my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
32
            if (refs[0][ref_n] < 0) nrefs[0] += 1;
33
            refs[0][ref_n] = FFMAX(refs[0][ref_n], my);
34
        }
35
    }
36

    
37
    if(list1){
38
        int ref_n = h->ref_cache[1][ scan8[n] ];
39
        Picture *ref= &h->ref_list[1][ref_n];
40

    
41
        if(ref->thread_opaque != s->current_picture.thread_opaque ||
42
           (ref->reference&3) != s->picture_structure) {
43
            my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
44
            if (refs[1][ref_n] < 0) nrefs[1] += 1;
45
            refs[1][ref_n] = FFMAX(refs[1][ref_n], my);
46
        }
47
    }
48
}
49

    
50
/**
51
 * Wait until all reference frames are available for MC operations.
52
 *
53
 * @param h the H264 context
54
 */
55
static void await_references(H264Context *h){
56
    MpegEncContext * const s = &h->s;
57
    const int mb_xy= h->mb_xy;
58
    const int mb_type= s->current_picture.mb_type[mb_xy];
59
    int refs[2][48];
60
    int nrefs[2] = {0};
61
    int ref, list;
62

    
63
    memset(refs, -1, sizeof(refs));
64

    
65
    if(IS_16X16(mb_type)){
66
        get_lowest_part_y(h, refs, 0, 16, 0,
67
                  IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs);
68
    }else if(IS_16X8(mb_type)){
69
        get_lowest_part_y(h, refs, 0, 8, 0,
70
                  IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs);
71
        get_lowest_part_y(h, refs, 8, 8, 8,
72
                  IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1), nrefs);
73
    }else if(IS_8X16(mb_type)){
74
        get_lowest_part_y(h, refs, 0, 16, 0,
75
                  IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs);
76
        get_lowest_part_y(h, refs, 4, 16, 0,
77
                  IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1), nrefs);
78
    }else{
79
        int i;
80

    
81
        assert(IS_8X8(mb_type));
82

    
83
        for(i=0; i<4; i++){
84
            const int sub_mb_type= h->sub_mb_type[i];
85
            const int n= 4*i;
86
            int y_offset= (i&2)<<2;
87

    
88
            if(IS_SUB_8X8(sub_mb_type)){
89
                get_lowest_part_y(h, refs, n  , 8, y_offset,
90
                          IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
91
            }else if(IS_SUB_8X4(sub_mb_type)){
92
                get_lowest_part_y(h, refs, n  , 4, y_offset,
93
                          IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
94
                get_lowest_part_y(h, refs, n+2, 4, y_offset+4,
95
                          IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
96
            }else if(IS_SUB_4X8(sub_mb_type)){
97
                get_lowest_part_y(h, refs, n  , 8, y_offset,
98
                          IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
99
                get_lowest_part_y(h, refs, n+1, 8, y_offset,
100
                          IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
101
            }else{
102
                int j;
103
                assert(IS_SUB_4X4(sub_mb_type));
104
                for(j=0; j<4; j++){
105
                    int sub_y_offset= y_offset + 2*(j&2);
106
                    get_lowest_part_y(h, refs, n+j, 4, sub_y_offset,
107
                              IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs);
108
                }
109
            }
110
        }
111
    }
112

    
113
    for(list=h->list_count-1; list>=0; list--){
114
        for(ref=0; ref<48 && nrefs[list]; ref++){
115
            int row = refs[list][ref];
116
            if(row >= 0){
117
                Picture *ref_pic = &h->ref_list[list][ref];
118
                int ref_field = ref_pic->reference - 1;
119
                int ref_field_picture = ref_pic->field_picture;
120
                int pic_height = 16*s->mb_height >> ref_field_picture;
121

    
122
                row <<= MB_MBAFF;
123
                nrefs[list]--;
124

    
125
                if(!FIELD_PICTURE && ref_field_picture){ // frame referencing two fields
126
                    ff_thread_await_progress((AVFrame*)ref_pic, FFMIN((row >> 1) - !(row&1), pic_height-1), 1);
127
                    ff_thread_await_progress((AVFrame*)ref_pic, FFMIN((row >> 1)           , pic_height-1), 0);
128
                }else if(FIELD_PICTURE && !ref_field_picture){ // field referencing one field of a frame
129
                    ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row*2 + ref_field    , pic_height-1), 0);
130
                }else if(FIELD_PICTURE){
131
                    ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), ref_field);
132
                }else{
133
                    ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), 0);
134
                }
135
            }
136
        }
137
    }
138
}
139

    
140
#define FUNC(a) a ## _8
141
#define PIXEL_SHIFT 0
142
#include "h264_hl_motion.h"
143

    
144
#undef PIXEL_SHIFT
145
#undef FUNC
146
#define FUNC(a) a ## _16
147
#define PIXEL_SHIFT 1
148
#include "h264_hl_motion.h"
149

    
150
void ff_hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
151
                      qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put),
152
                      qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg),
153
                      h264_weight_func *weight_op, h264_biweight_func *weight_avg){
154
    if(h->pixel_shift){
155
        hl_motion_16(h, dest_y, dest_cb, dest_cr,
156
                      qpix_put, chroma_put,
157
                      qpix_avg, chroma_avg,
158
                      weight_op, weight_avg);
159
    }else
160
        hl_motion_8(h, dest_y, dest_cb, dest_cr,
161
                      qpix_put, chroma_put,
162
                      qpix_avg, chroma_avg,
163
                      weight_op, weight_avg);
164
}