]> git.sesse.net Git - ffmpeg/blob - libavcodec/h264_hl_motion.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / h264_hl_motion.c
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 }