00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030
00031 #include <limits.h>
00032
00033 #include "dsputil.h"
00034 #include "avcodec.h"
00035 #include "mpegvideo.h"
00036 #include "h263.h"
00037 #include "h263data.h"
00038 #include "mathops.h"
00039 #include "unary.h"
00040 #include "flv.h"
00041 #include "mpeg4video.h"
00042
00043
00044
00045
00046 uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
00047
00048
00049 void ff_h263_update_motion_val(MpegEncContext * s){
00050 const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
00051
00052 const int wrap = s->b8_stride;
00053 const int xy = s->block_index[0];
00054
00055 s->current_picture.mbskip_table[mb_xy]= s->mb_skipped;
00056
00057 if(s->mv_type != MV_TYPE_8X8){
00058 int motion_x, motion_y;
00059 if (s->mb_intra) {
00060 motion_x = 0;
00061 motion_y = 0;
00062 } else if (s->mv_type == MV_TYPE_16X16) {
00063 motion_x = s->mv[0][0][0];
00064 motion_y = s->mv[0][0][1];
00065 } else {
00066 int i;
00067 motion_x = s->mv[0][0][0] + s->mv[0][1][0];
00068 motion_y = s->mv[0][0][1] + s->mv[0][1][1];
00069 motion_x = (motion_x>>1) | (motion_x&1);
00070 for(i=0; i<2; i++){
00071 s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
00072 s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
00073 }
00074 s->current_picture.ref_index[0][4*mb_xy ]=
00075 s->current_picture.ref_index[0][4*mb_xy + 1]= s->field_select[0][0];
00076 s->current_picture.ref_index[0][4*mb_xy + 2]=
00077 s->current_picture.ref_index[0][4*mb_xy + 3]= s->field_select[0][1];
00078 }
00079
00080
00081 s->current_picture.motion_val[0][xy][0] = motion_x;
00082 s->current_picture.motion_val[0][xy][1] = motion_y;
00083 s->current_picture.motion_val[0][xy + 1][0] = motion_x;
00084 s->current_picture.motion_val[0][xy + 1][1] = motion_y;
00085 s->current_picture.motion_val[0][xy + wrap][0] = motion_x;
00086 s->current_picture.motion_val[0][xy + wrap][1] = motion_y;
00087 s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
00088 s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
00089 }
00090
00091 if(s->encoding){
00092 if (s->mv_type == MV_TYPE_8X8)
00093 s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8;
00094 else if(s->mb_intra)
00095 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA;
00096 else
00097 s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16;
00098 }
00099 }
00100
00101 int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr)
00102 {
00103 int x, y, wrap, a, c, pred_dc;
00104 int16_t *dc_val;
00105
00106
00107 if (n < 4) {
00108 x = 2 * s->mb_x + (n & 1);
00109 y = 2 * s->mb_y + ((n & 2) >> 1);
00110 wrap = s->b8_stride;
00111 dc_val = s->dc_val[0];
00112 } else {
00113 x = s->mb_x;
00114 y = s->mb_y;
00115 wrap = s->mb_stride;
00116 dc_val = s->dc_val[n - 4 + 1];
00117 }
00118
00119
00120
00121 a = dc_val[(x - 1) + (y) * wrap];
00122 c = dc_val[(x) + (y - 1) * wrap];
00123
00124
00125 if(s->first_slice_line && n!=3){
00126 if(n!=2) c= 1024;
00127 if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
00128 }
00129
00130 if (a != 1024 && c != 1024)
00131 pred_dc = (a + c) >> 1;
00132 else if (a != 1024)
00133 pred_dc = a;
00134 else
00135 pred_dc = c;
00136
00137
00138 *dc_val_ptr = &dc_val[x + y * wrap];
00139 return pred_dc;
00140 }
00141
00142 void ff_h263_loop_filter(MpegEncContext * s){
00143 int qp_c;
00144 const int linesize = s->linesize;
00145 const int uvlinesize= s->uvlinesize;
00146 const int xy = s->mb_y * s->mb_stride + s->mb_x;
00147 uint8_t *dest_y = s->dest[0];
00148 uint8_t *dest_cb= s->dest[1];
00149 uint8_t *dest_cr= s->dest[2];
00150
00151
00152
00153
00154
00155
00156
00157 if(!IS_SKIP(s->current_picture.mb_type[xy])){
00158 qp_c= s->qscale;
00159 s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c);
00160 s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
00161 }else
00162 qp_c= 0;
00163
00164 if(s->mb_y){
00165 int qp_dt, qp_tt, qp_tc;
00166
00167 if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride]))
00168 qp_tt=0;
00169 else
00170 qp_tt= s->current_picture.qscale_table[xy-s->mb_stride];
00171
00172 if(qp_c)
00173 qp_tc= qp_c;
00174 else
00175 qp_tc= qp_tt;
00176
00177 if(qp_tc){
00178 const int chroma_qp= s->chroma_qscale_table[qp_tc];
00179 s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc);
00180 s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc);
00181
00182 s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp);
00183 s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp);
00184 }
00185
00186 if(qp_tt)
00187 s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_tt);
00188
00189 if(s->mb_x){
00190 if(qp_tt || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride]))
00191 qp_dt= qp_tt;
00192 else
00193 qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride];
00194
00195 if(qp_dt){
00196 const int chroma_qp= s->chroma_qscale_table[qp_dt];
00197 s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt);
00198 s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp);
00199 s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp);
00200 }
00201 }
00202 }
00203
00204 if(qp_c){
00205 s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c);
00206 if(s->mb_y + 1 == s->mb_height)
00207 s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
00208 }
00209
00210 if(s->mb_x){
00211 int qp_lc;
00212 if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1]))
00213 qp_lc= qp_c;
00214 else
00215 qp_lc= s->current_picture.qscale_table[xy-1];
00216
00217 if(qp_lc){
00218 s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
00219 if(s->mb_y + 1 == s->mb_height){
00220 const int chroma_qp= s->chroma_qscale_table[qp_lc];
00221 s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc);
00222 s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp);
00223 s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp);
00224 }
00225 }
00226 }
00227 }
00228
00229 void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n)
00230 {
00231 int x, y, wrap, a, c, pred_dc, scale, i;
00232 int16_t *dc_val, *ac_val, *ac_val1;
00233
00234
00235 if (n < 4) {
00236 x = 2 * s->mb_x + (n & 1);
00237 y = 2 * s->mb_y + (n>> 1);
00238 wrap = s->b8_stride;
00239 dc_val = s->dc_val[0];
00240 ac_val = s->ac_val[0][0];
00241 scale = s->y_dc_scale;
00242 } else {
00243 x = s->mb_x;
00244 y = s->mb_y;
00245 wrap = s->mb_stride;
00246 dc_val = s->dc_val[n - 4 + 1];
00247 ac_val = s->ac_val[n - 4 + 1][0];
00248 scale = s->c_dc_scale;
00249 }
00250
00251 ac_val += ((y) * wrap + (x)) * 16;
00252 ac_val1 = ac_val;
00253
00254
00255
00256
00257 a = dc_val[(x - 1) + (y) * wrap];
00258 c = dc_val[(x) + (y - 1) * wrap];
00259
00260
00261 if(s->first_slice_line && n!=3){
00262 if(n!=2) c= 1024;
00263 if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024;
00264 }
00265
00266 if (s->ac_pred) {
00267 pred_dc = 1024;
00268 if (s->h263_aic_dir) {
00269
00270 if (a != 1024) {
00271 ac_val -= 16;
00272 for(i=1;i<8;i++) {
00273 block[s->dsp.idct_permutation[i<<3]] += ac_val[i];
00274 }
00275 pred_dc = a;
00276 }
00277 } else {
00278
00279 if (c != 1024) {
00280 ac_val -= 16 * wrap;
00281 for(i=1;i<8;i++) {
00282 block[s->dsp.idct_permutation[i ]] += ac_val[i + 8];
00283 }
00284 pred_dc = c;
00285 }
00286 }
00287 } else {
00288
00289 if (a != 1024 && c != 1024)
00290 pred_dc = (a + c) >> 1;
00291 else if (a != 1024)
00292 pred_dc = a;
00293 else
00294 pred_dc = c;
00295 }
00296
00297
00298 block[0]=block[0]*scale + pred_dc;
00299
00300 if (block[0] < 0)
00301 block[0] = 0;
00302 else
00303 block[0] |= 1;
00304
00305
00306 dc_val[(x) + (y) * wrap] = block[0];
00307
00308
00309 for(i=1;i<8;i++)
00310 ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]];
00311
00312 for(i=1;i<8;i++)
00313 ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]];
00314 }
00315
00316 int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
00317 int *px, int *py)
00318 {
00319 int wrap;
00320 int16_t *A, *B, *C, (*mot_val)[2];
00321 static const int off[4]= {2, 1, 1, -1};
00322
00323 wrap = s->b8_stride;
00324 mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
00325
00326 A = mot_val[ - 1];
00327
00328 if (s->first_slice_line && block<3) {
00329
00330
00331 if(block==0){
00332 if(s->mb_x == s->resync_mb_x){
00333 *px= *py = 0;
00334 }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){
00335 C = mot_val[off[block] - wrap];
00336 if(s->mb_x==0){
00337 *px = C[0];
00338 *py = C[1];
00339 }else{
00340 *px = mid_pred(A[0], 0, C[0]);
00341 *py = mid_pred(A[1], 0, C[1]);
00342 }
00343 }else{
00344 *px = A[0];
00345 *py = A[1];
00346 }
00347 }else if(block==1){
00348 if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){
00349 C = mot_val[off[block] - wrap];
00350 *px = mid_pred(A[0], 0, C[0]);
00351 *py = mid_pred(A[1], 0, C[1]);
00352 }else{
00353 *px = A[0];
00354 *py = A[1];
00355 }
00356 }else{
00357 B = mot_val[ - wrap];
00358 C = mot_val[off[block] - wrap];
00359 if(s->mb_x == s->resync_mb_x)
00360 A[0]=A[1]=0;
00361
00362 *px = mid_pred(A[0], B[0], C[0]);
00363 *py = mid_pred(A[1], B[1], C[1]);
00364 }
00365 } else {
00366 B = mot_val[ - wrap];
00367 C = mot_val[off[block] - wrap];
00368 *px = mid_pred(A[0], B[0], C[0]);
00369 *py = mid_pred(A[1], B[1], C[1]);
00370 }
00371 return *mot_val;
00372 }
00373
00374
00378 int ff_h263_get_gob_height(MpegEncContext *s){
00379 if (s->height <= 400)
00380 return 1;
00381 else if (s->height <= 800)
00382 return 2;
00383 else
00384 return 4;
00385 }