/src/ffmpeg/libavcodec/h263.c
Line | Count | Source |
1 | | /* |
2 | | * H.263/MPEG-4 backend for encoder and decoder |
3 | | * Copyright (c) 2000,2001 Fabrice Bellard |
4 | | * H.263+ support. |
5 | | * Copyright (c) 2001 Juan J. Sierralta P |
6 | | * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> |
7 | | * |
8 | | * This file is part of FFmpeg. |
9 | | * |
10 | | * FFmpeg is free software; you can redistribute it and/or |
11 | | * modify it under the terms of the GNU Lesser General Public |
12 | | * License as published by the Free Software Foundation; either |
13 | | * version 2.1 of the License, or (at your option) any later version. |
14 | | * |
15 | | * FFmpeg is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 | | * Lesser General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU Lesser General Public |
21 | | * License along with FFmpeg; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 | | */ |
24 | | |
25 | | /** |
26 | | * @file |
27 | | * H.263/MPEG-4 codec. |
28 | | */ |
29 | | |
30 | | #include "config.h" |
31 | | |
32 | | #include "libavutil/thread.h" |
33 | | #include "mpegvideo.h" |
34 | | #include "h263.h" |
35 | | #include "h263data.h" |
36 | | #include "h263dsp.h" |
37 | | #include "mathops.h" |
38 | | #include "mpegpicture.h" |
39 | | #include "mpegutils.h" |
40 | | #include "rl.h" |
41 | | |
42 | | #if CONFIG_MPEGVIDEO |
43 | | static av_cold void h263_init_rl_inter(void) |
44 | 13 | { |
45 | 13 | static uint8_t h263_rl_inter_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; |
46 | 13 | ff_rl_init(&ff_h263_rl_inter, h263_rl_inter_table); |
47 | 13 | } |
48 | | |
49 | | av_cold void ff_h263_init_rl_inter(void) |
50 | 13 | { |
51 | 13 | static AVOnce init_static_once = AV_ONCE_INIT; |
52 | 13 | ff_thread_once(&init_static_once, h263_init_rl_inter); |
53 | 13 | } |
54 | | #endif |
55 | | |
56 | 47.5M | void ff_h263_update_motion_val(MpegEncContext * s){ |
57 | 47.5M | const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; |
58 | | //FIXME a lot of that is only needed for !low_delay |
59 | 47.5M | const int wrap = s->b8_stride; |
60 | 47.5M | const int xy = s->block_index[0]; |
61 | | |
62 | 47.5M | if(s->mv_type != MV_TYPE_8X8){ |
63 | 46.4M | int motion_x, motion_y; |
64 | 46.4M | if (s->mb_intra) { |
65 | 7.98M | motion_x = 0; |
66 | 7.98M | motion_y = 0; |
67 | 38.4M | } else if (s->mv_type == MV_TYPE_16X16) { |
68 | 38.3M | motion_x = s->mv[0][0][0]; |
69 | 38.3M | motion_y = s->mv[0][0][1]; |
70 | 38.3M | } else /*if (s->mv_type == MV_TYPE_FIELD)*/ { |
71 | 37.2k | int i; |
72 | 37.2k | motion_x = s->mv[0][0][0] + s->mv[0][1][0]; |
73 | 37.2k | motion_y = s->mv[0][0][1] + s->mv[0][1][1]; |
74 | 37.2k | motion_x = (motion_x>>1) | (motion_x&1); |
75 | 111k | for(i=0; i<2; i++){ |
76 | 74.4k | s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; |
77 | 74.4k | s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; |
78 | 74.4k | } |
79 | 37.2k | s->cur_pic.ref_index[0][4*mb_xy ] = |
80 | 37.2k | s->cur_pic.ref_index[0][4*mb_xy + 1] = s->field_select[0][0]; |
81 | 37.2k | s->cur_pic.ref_index[0][4*mb_xy + 2] = |
82 | 37.2k | s->cur_pic.ref_index[0][4*mb_xy + 3] = s->field_select[0][1]; |
83 | 37.2k | } |
84 | | |
85 | | /* no update if 8X8 because it has been done during parsing */ |
86 | 46.4M | s->cur_pic.motion_val[0][xy][0] = motion_x; |
87 | 46.4M | s->cur_pic.motion_val[0][xy][1] = motion_y; |
88 | 46.4M | s->cur_pic.motion_val[0][xy + 1][0] = motion_x; |
89 | 46.4M | s->cur_pic.motion_val[0][xy + 1][1] = motion_y; |
90 | 46.4M | s->cur_pic.motion_val[0][xy + wrap][0] = motion_x; |
91 | 46.4M | s->cur_pic.motion_val[0][xy + wrap][1] = motion_y; |
92 | 46.4M | s->cur_pic.motion_val[0][xy + 1 + wrap][0] = motion_x; |
93 | 46.4M | s->cur_pic.motion_val[0][xy + 1 + wrap][1] = motion_y; |
94 | 46.4M | } |
95 | 47.5M | } |
96 | | |
97 | 6.46M | void ff_h263_loop_filter(MpegEncContext * s){ |
98 | 6.46M | int qp_c; |
99 | 6.46M | const int linesize = s->linesize; |
100 | 6.46M | const int uvlinesize= s->uvlinesize; |
101 | 6.46M | const int xy = s->mb_y * s->mb_stride + s->mb_x; |
102 | 6.46M | uint8_t *dest_y = s->dest[0]; |
103 | 6.46M | uint8_t *dest_cb= s->dest[1]; |
104 | 6.46M | uint8_t *dest_cr= s->dest[2]; |
105 | | |
106 | | /* |
107 | | Diag Top |
108 | | Left Center |
109 | | */ |
110 | 6.46M | if (!IS_SKIP(s->cur_pic.mb_type[xy])) { |
111 | 2.85M | qp_c= s->qscale; |
112 | 2.85M | s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize, linesize, qp_c); |
113 | 2.85M | s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c); |
114 | 2.85M | }else |
115 | 3.60M | qp_c= 0; |
116 | | |
117 | 6.46M | if(s->mb_y){ |
118 | 5.56M | int qp_dt, qp_tt, qp_tc; |
119 | | |
120 | 5.56M | if (IS_SKIP(s->cur_pic.mb_type[xy - s->mb_stride])) |
121 | 3.07M | qp_tt=0; |
122 | 2.49M | else |
123 | 2.49M | qp_tt = s->cur_pic.qscale_table[xy - s->mb_stride]; |
124 | | |
125 | 5.56M | if(qp_c) |
126 | 2.42M | qp_tc= qp_c; |
127 | 3.13M | else |
128 | 3.13M | qp_tc= qp_tt; |
129 | | |
130 | 5.56M | if(qp_tc){ |
131 | 3.02M | const int chroma_qp= s->chroma_qscale_table[qp_tc]; |
132 | 3.02M | s->h263dsp.h263_v_loop_filter(dest_y, linesize, qp_tc); |
133 | 3.02M | s->h263dsp.h263_v_loop_filter(dest_y + 8, linesize, qp_tc); |
134 | | |
135 | 3.02M | s->h263dsp.h263_v_loop_filter(dest_cb, uvlinesize, chroma_qp); |
136 | 3.02M | s->h263dsp.h263_v_loop_filter(dest_cr, uvlinesize, chroma_qp); |
137 | 3.02M | } |
138 | | |
139 | 5.56M | if(qp_tt) |
140 | 2.31M | s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize + 8, linesize, qp_tt); |
141 | | |
142 | 5.56M | if(s->mb_x){ |
143 | 4.83M | if (qp_tt || IS_SKIP(s->cur_pic.mb_type[xy - 1 - s->mb_stride])) |
144 | 3.95M | qp_dt= qp_tt; |
145 | 878k | else |
146 | 878k | qp_dt = s->cur_pic.qscale_table[xy - 1 - s->mb_stride]; |
147 | | |
148 | 4.83M | if(qp_dt){ |
149 | 2.65M | const int chroma_qp= s->chroma_qscale_table[qp_dt]; |
150 | 2.65M | s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize, linesize, qp_dt); |
151 | 2.65M | s->h263dsp.h263_h_loop_filter(dest_cb - 8 * uvlinesize, uvlinesize, chroma_qp); |
152 | 2.65M | s->h263dsp.h263_h_loop_filter(dest_cr - 8 * uvlinesize, uvlinesize, chroma_qp); |
153 | 2.65M | } |
154 | 4.83M | } |
155 | 5.56M | } |
156 | | |
157 | 6.46M | if(qp_c){ |
158 | 2.85M | s->h263dsp.h263_h_loop_filter(dest_y + 8, linesize, qp_c); |
159 | 2.85M | if(s->mb_y + 1 == s->mb_height) |
160 | 138k | s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c); |
161 | 2.85M | } |
162 | | |
163 | 6.46M | if(s->mb_x){ |
164 | 5.68M | int qp_lc; |
165 | 5.68M | if (qp_c || IS_SKIP(s->cur_pic.mb_type[xy - 1])) |
166 | 4.87M | qp_lc= qp_c; |
167 | 813k | else |
168 | 813k | qp_lc = s->cur_pic.qscale_table[xy - 1]; |
169 | | |
170 | 5.68M | if(qp_lc){ |
171 | 3.26M | s->h263dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); |
172 | 3.26M | if(s->mb_y + 1 == s->mb_height){ |
173 | 164k | const int chroma_qp= s->chroma_qscale_table[qp_lc]; |
174 | 164k | s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize, linesize, qp_lc); |
175 | 164k | s->h263dsp.h263_h_loop_filter(dest_cb, uvlinesize, chroma_qp); |
176 | 164k | s->h263dsp.h263_h_loop_filter(dest_cr, uvlinesize, chroma_qp); |
177 | 164k | } |
178 | 3.26M | } |
179 | 5.68M | } |
180 | 6.46M | } |
181 | | |
182 | | int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, |
183 | | int *px, int *py) |
184 | 16.1M | { |
185 | 16.1M | int wrap; |
186 | 16.1M | int16_t *A, *B, *C, (*mot_val)[2]; |
187 | 16.1M | static const int off[4]= {2, 1, 1, -1}; |
188 | | |
189 | 16.1M | wrap = s->b8_stride; |
190 | 16.1M | mot_val = s->cur_pic.motion_val[dir] + s->block_index[block]; |
191 | | |
192 | 16.1M | A = mot_val[ - 1]; |
193 | | /* special case for first (slice) line */ |
194 | 16.1M | if (s->first_slice_line && block<3) { |
195 | | // we can't just change some MVs to simulate that as we need them for the B-frames (and ME) |
196 | | // and if we ever support non rectangular objects than we need to do a few ifs here anyway :( |
197 | 4.98M | if(block==0){ //most common case |
198 | 3.53M | if(s->mb_x == s->resync_mb_x){ //rare |
199 | 520k | *px= *py = 0; |
200 | 3.01M | }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare |
201 | 3.41k | C = mot_val[off[block] - wrap]; |
202 | 3.41k | if(s->mb_x==0){ |
203 | 1.11k | *px = C[0]; |
204 | 1.11k | *py = C[1]; |
205 | 2.29k | }else{ |
206 | 2.29k | *px = mid_pred(A[0], 0, C[0]); |
207 | 2.29k | *py = mid_pred(A[1], 0, C[1]); |
208 | 2.29k | } |
209 | 3.00M | }else{ |
210 | 3.00M | *px = A[0]; |
211 | 3.00M | *py = A[1]; |
212 | 3.00M | } |
213 | 3.53M | }else if(block==1){ |
214 | 733k | if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare |
215 | 1.72k | C = mot_val[off[block] - wrap]; |
216 | 1.72k | *px = mid_pred(A[0], 0, C[0]); |
217 | 1.72k | *py = mid_pred(A[1], 0, C[1]); |
218 | 731k | }else{ |
219 | 731k | *px = A[0]; |
220 | 731k | *py = A[1]; |
221 | 731k | } |
222 | 733k | }else{ /* block==2*/ |
223 | 714k | B = mot_val[ - wrap]; |
224 | 714k | C = mot_val[off[block] - wrap]; |
225 | 714k | if(s->mb_x == s->resync_mb_x) //rare |
226 | 31.5k | A[0]=A[1]=0; |
227 | | |
228 | 714k | *px = mid_pred(A[0], B[0], C[0]); |
229 | 714k | *py = mid_pred(A[1], B[1], C[1]); |
230 | 714k | } |
231 | 11.1M | } else { |
232 | 11.1M | B = mot_val[ - wrap]; |
233 | 11.1M | C = mot_val[off[block] - wrap]; |
234 | 11.1M | *px = mid_pred(A[0], B[0], C[0]); |
235 | 11.1M | *py = mid_pred(A[1], B[1], C[1]); |
236 | 11.1M | } |
237 | 16.1M | return *mot_val; |
238 | 16.1M | } |