• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/h264_direct.c

Go to the documentation of this file.
00001 /*
00002  * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
00003  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00028 #include "internal.h"
00029 #include "dsputil.h"
00030 #include "avcodec.h"
00031 #include "mpegvideo.h"
00032 #include "h264.h"
00033 #include "rectangle.h"
00034 
00035 //#undef NDEBUG
00036 #include <assert.h>
00037 
00038 
00039 static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){
00040     int poc0 = h->ref_list[0][i].poc;
00041     int td = av_clip(poc1 - poc0, -128, 127);
00042     if(td == 0 || h->ref_list[0][i].long_ref){
00043         return 256;
00044     }else{
00045         int tb = av_clip(poc - poc0, -128, 127);
00046         int tx = (16384 + (FFABS(td) >> 1)) / td;
00047         return av_clip((tb*tx + 32) >> 6, -1024, 1023);
00048     }
00049 }
00050 
00051 void ff_h264_direct_dist_scale_factor(H264Context * const h){
00052     MpegEncContext * const s = &h->s;
00053     const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
00054     const int poc1 = h->ref_list[1][0].poc;
00055     int i, field;
00056     for(field=0; field<2; field++){
00057         const int poc  = h->s.current_picture_ptr->field_poc[field];
00058         const int poc1 = h->ref_list[1][0].field_poc[field];
00059         for(i=0; i < 2*h->ref_count[0]; i++)
00060             h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16);
00061     }
00062 
00063     for(i=0; i<h->ref_count[0]; i++){
00064         h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
00065     }
00066 }
00067 
00068 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
00069     MpegEncContext * const s = &h->s;
00070     Picture * const ref1 = &h->ref_list[1][0];
00071     int j, old_ref, rfield;
00072     int start= mbafi ? 16                      : 0;
00073     int end  = mbafi ? 16+2*h->ref_count[0]    : h->ref_count[0];
00074     int interl= mbafi || s->picture_structure != PICT_FRAME;
00075 
00076     /* bogus; fills in for missing frames */
00077     memset(map[list], 0, sizeof(map[list]));
00078 
00079     for(rfield=0; rfield<2; rfield++){
00080         for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){
00081             int poc = ref1->ref_poc[colfield][list][old_ref];
00082 
00083             if     (!interl)
00084                 poc |= 3;
00085             else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed
00086                 poc= (poc&~3) + rfield + 1;
00087 
00088             for(j=start; j<end; j++){
00089                 if(4*h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference&3) == poc){
00090                     int cur_ref= mbafi ? (j-16)^field : j;
00091                     map[list][2*old_ref + (rfield^field) + 16] = cur_ref;
00092                     if(rfield == field || !interl)
00093                         map[list][old_ref] = cur_ref;
00094                     break;
00095                 }
00096             }
00097         }
00098     }
00099 }
00100 
00101 void ff_h264_direct_ref_list_init(H264Context * const h){
00102     MpegEncContext * const s = &h->s;
00103     Picture * const ref1 = &h->ref_list[1][0];
00104     Picture * const cur = s->current_picture_ptr;
00105     int list, j, field;
00106     int sidx= (s->picture_structure&1)^1;
00107     int ref1sidx= (ref1->reference&1)^1;
00108 
00109     for(list=0; list<2; list++){
00110         cur->ref_count[sidx][list] = h->ref_count[list];
00111         for(j=0; j<h->ref_count[list]; j++)
00112             cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3);
00113     }
00114 
00115     if(s->picture_structure == PICT_FRAME){
00116         memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
00117         memcpy(cur->ref_poc  [1], cur->ref_poc  [0], sizeof(cur->ref_poc  [0]));
00118     }
00119 
00120     cur->mbaff= FRAME_MBAFF;
00121 
00122     h->col_fieldoff= 0;
00123     if(s->picture_structure == PICT_FRAME){
00124         int cur_poc = s->current_picture_ptr->poc;
00125         int *col_poc = h->ref_list[1]->field_poc;
00126         h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
00127         ref1sidx=sidx= h->col_parity;
00128     }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){ // FL -> FL & differ parity
00129         h->col_fieldoff= s->mb_stride*(2*(h->ref_list[1][0].reference) - 3);
00130     }
00131 
00132     if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred)
00133         return;
00134 
00135     for(list=0; list<2; list++){
00136         fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0);
00137         if(FRAME_MBAFF)
00138         for(field=0; field<2; field++)
00139             fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1);
00140     }
00141 }
00142 
00143 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
00144     MpegEncContext * const s = &h->s;
00145     int b8_stride = 2;
00146     int b4_stride = h->b_stride;
00147     int mb_xy = h->mb_xy;
00148     int mb_type_col[2];
00149     const int16_t (*l1mv0)[2], (*l1mv1)[2];
00150     const int8_t *l1ref0, *l1ref1;
00151     const int is_b8x8 = IS_8X8(*mb_type);
00152     unsigned int sub_mb_type= MB_TYPE_L0L1;
00153     int i8, i4;
00154     int ref[2];
00155     int mv[2];
00156     int list;
00157 
00158     assert(h->ref_list[1][0].reference&3);
00159 
00160 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
00161 
00162 
00163     /* ref = min(neighbors) */
00164     for(list=0; list<2; list++){
00165         int left_ref = h->ref_cache[list][scan8[0] - 1];
00166         int top_ref  = h->ref_cache[list][scan8[0] - 8];
00167         int refc = h->ref_cache[list][scan8[0] - 8 + 4];
00168         const int16_t *C= h->mv_cache[list][ scan8[0] - 8 + 4];
00169         if(refc == PART_NOT_AVAILABLE){
00170             refc = h->ref_cache[list][scan8[0] - 8 - 1];
00171             C    = h-> mv_cache[list][scan8[0] - 8 - 1];
00172         }
00173         ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, (unsigned)refc);
00174         if(ref[list] >= 0){
00175             //this is just pred_motion() but with the cases removed that cannot happen for direct blocks
00176             const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ];
00177             const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ];
00178 
00179             int match_count= (left_ref==ref[list]) + (top_ref==ref[list]) + (refc==ref[list]);
00180             if(match_count > 1){ //most common
00181                 mv[list]= pack16to32(mid_pred(A[0], B[0], C[0]),
00182                                      mid_pred(A[1], B[1], C[1]) );
00183             }else {
00184                 assert(match_count==1);
00185                 if(left_ref==ref[list]){
00186                     mv[list]= AV_RN32A(A);
00187                 }else if(top_ref==ref[list]){
00188                     mv[list]= AV_RN32A(B);
00189                 }else{
00190                     mv[list]= AV_RN32A(C);
00191                 }
00192             }
00193         }else{
00194             int mask= ~(MB_TYPE_L0 << (2*list));
00195             mv[list] = 0;
00196             ref[list] = -1;
00197             if(!is_b8x8)
00198                 *mb_type &= mask;
00199             sub_mb_type &= mask;
00200         }
00201     }
00202     if(ref[0] < 0 && ref[1] < 0){
00203         ref[0] = ref[1] = 0;
00204         if(!is_b8x8)
00205             *mb_type |= MB_TYPE_L0L1;
00206         sub_mb_type |= MB_TYPE_L0L1;
00207     }
00208 
00209     if(!(is_b8x8|mv[0]|mv[1])){
00210         fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
00211         fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
00212         fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
00213         fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);
00214         *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2;
00215         return;
00216     }
00217 
00218     if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
00219         if(!IS_INTERLACED(*mb_type)){                    //     AFR/FR    -> AFL/FL
00220             mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
00221             b8_stride = 0;
00222         }else{
00223             mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity
00224         }
00225         goto single_col;
00226     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
00227         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
00228             mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
00229             mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
00230             mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride];
00231             b8_stride = 2+4*s->mb_stride;
00232             b4_stride *= 6;
00233 
00234             sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
00235             if(    (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)
00236                 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA)
00237                 && !is_b8x8){
00238                 *mb_type   |= MB_TYPE_16x8 |MB_TYPE_DIRECT2; /* B_16x8 */
00239             }else{
00240                 *mb_type   |= MB_TYPE_8x8;
00241             }
00242         }else{                                           //     AFR/FR    -> AFR/FR
00243 single_col:
00244             mb_type_col[0] =
00245             mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
00246 
00247             sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
00248             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
00249                 *mb_type   |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_16x16 */
00250             }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){
00251                 *mb_type   |= MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16));
00252             }else{
00253                 if(!h->sps.direct_8x8_inference_flag){
00254                     /* FIXME save sub mb types from previous frames (or derive from MVs)
00255                     * so we know exactly what block size to use */
00256                     sub_mb_type += (MB_TYPE_8x8-MB_TYPE_16x16); /* B_SUB_4x4 */
00257                 }
00258                 *mb_type   |= MB_TYPE_8x8;
00259             }
00260         }
00261     }
00262 
00263     l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
00264     l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
00265     l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy];
00266     l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy];
00267     if(!b8_stride){
00268         if(s->mb_y&1){
00269             l1ref0 += 2;
00270             l1ref1 += 2;
00271             l1mv0  +=  2*b4_stride;
00272             l1mv1  +=  2*b4_stride;
00273         }
00274     }
00275 
00276 
00277         if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
00278             int n=0;
00279             for(i8=0; i8<4; i8++){
00280                 int x8 = i8&1;
00281                 int y8 = i8>>1;
00282                 int xy8 = x8+y8*b8_stride;
00283                 int xy4 = 3*x8+y8*b4_stride;
00284                 int a,b;
00285 
00286                 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
00287                     continue;
00288                 h->sub_mb_type[i8] = sub_mb_type;
00289 
00290                 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1);
00291                 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1);
00292                 if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref
00293                    && (   (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1)
00294                        || (l1ref0[xy8]  < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[xy4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){
00295                     a=b=0;
00296                     if(ref[0] > 0)
00297                         a= mv[0];
00298                     if(ref[1] > 0)
00299                         b= mv[1];
00300                     n++;
00301                 }else{
00302                     a= mv[0];
00303                     b= mv[1];
00304                 }
00305                 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4);
00306                 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4);
00307             }
00308             if(!is_b8x8 && !(n&3))
00309                 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2;
00310         }else if(IS_16X16(*mb_type)){
00311             int a,b;
00312 
00313             fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
00314             fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
00315             if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref
00316                && (   (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1)
00317                    || (l1ref0[0]  < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1
00318                        && h->x264_build>33U))){
00319                 a=b=0;
00320                 if(ref[0] > 0)
00321                     a= mv[0];
00322                 if(ref[1] > 0)
00323                     b= mv[1];
00324             }else{
00325                 a= mv[0];
00326                 b= mv[1];
00327             }
00328             fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
00329             fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
00330         }else{
00331             int n=0;
00332             for(i8=0; i8<4; i8++){
00333                 const int x8 = i8&1;
00334                 const int y8 = i8>>1;
00335 
00336                 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
00337                     continue;
00338                 h->sub_mb_type[i8] = sub_mb_type;
00339 
00340                 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, mv[0], 4);
00341                 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, mv[1], 4);
00342                 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1);
00343                 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1);
00344 
00345                 assert(b8_stride==2);
00346                 /* col_zero_flag */
00347                 if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && (   l1ref0[i8] == 0
00348                                               || (l1ref0[i8] < 0 && l1ref1[i8] == 0
00349                                                   && h->x264_build>33U))){
00350                     const int16_t (*l1mv)[2]= l1ref0[i8] == 0 ? l1mv0 : l1mv1;
00351                     if(IS_SUB_8X8(sub_mb_type)){
00352                         const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride];
00353                         if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){
00354                             if(ref[0] == 0)
00355                                 fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
00356                             if(ref[1] == 0)
00357                                 fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);
00358                             n+=4;
00359                         }
00360                     }else{
00361                         int m=0;
00362                     for(i4=0; i4<4; i4++){
00363                         const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride];
00364                         if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){
00365                             if(ref[0] == 0)
00366                                 AV_ZERO32(h->mv_cache[0][scan8[i8*4+i4]]);
00367                             if(ref[1] == 0)
00368                                 AV_ZERO32(h->mv_cache[1][scan8[i8*4+i4]]);
00369                             m++;
00370                         }
00371                     }
00372                     if(!(m&3))
00373                         h->sub_mb_type[i8]+= MB_TYPE_16x16 - MB_TYPE_8x8;
00374                     n+=m;
00375                     }
00376                 }
00377             }
00378             if(!is_b8x8 && !(n&15))
00379                 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2;
00380         }
00381 }
00382 
00383 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
00384     MpegEncContext * const s = &h->s;
00385     int b8_stride = 2;
00386     int b4_stride = h->b_stride;
00387     int mb_xy = h->mb_xy;
00388     int mb_type_col[2];
00389     const int16_t (*l1mv0)[2], (*l1mv1)[2];
00390     const int8_t *l1ref0, *l1ref1;
00391     const int is_b8x8 = IS_8X8(*mb_type);
00392     unsigned int sub_mb_type;
00393     int i8, i4;
00394 
00395     assert(h->ref_list[1][0].reference&3);
00396 
00397     if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
00398         if(!IS_INTERLACED(*mb_type)){                    //     AFR/FR    -> AFL/FL
00399             mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
00400             b8_stride = 0;
00401         }else{
00402             mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity
00403         }
00404         goto single_col;
00405     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
00406         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
00407             mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
00408             mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
00409             mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride];
00410             b8_stride = 2+4*s->mb_stride;
00411             b4_stride *= 6;
00412 
00413             sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
00414 
00415             if(    (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)
00416                 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA)
00417                 && !is_b8x8){
00418                 *mb_type   |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */
00419             }else{
00420                 *mb_type   |= MB_TYPE_8x8|MB_TYPE_L0L1;
00421             }
00422         }else{                                           //     AFR/FR    -> AFR/FR
00423 single_col:
00424             mb_type_col[0] =
00425             mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
00426 
00427             sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
00428             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
00429                 *mb_type   |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */
00430             }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){
00431                 *mb_type   |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16));
00432             }else{
00433                 if(!h->sps.direct_8x8_inference_flag){
00434                     /* FIXME save sub mb types from previous frames (or derive from MVs)
00435                     * so we know exactly what block size to use */
00436                     sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */
00437                 }
00438                 *mb_type   |= MB_TYPE_8x8|MB_TYPE_L0L1;
00439             }
00440         }
00441     }
00442 
00443     l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
00444     l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
00445     l1ref0 = &h->ref_list[1][0].ref_index [0][4*mb_xy];
00446     l1ref1 = &h->ref_list[1][0].ref_index [1][4*mb_xy];
00447     if(!b8_stride){
00448         if(s->mb_y&1){
00449             l1ref0 += 2;
00450             l1ref1 += 2;
00451             l1mv0  +=  2*b4_stride;
00452             l1mv1  +=  2*b4_stride;
00453         }
00454     }
00455 
00456     {
00457         const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]};
00458         const int *dist_scale_factor = h->dist_scale_factor;
00459         int ref_offset;
00460 
00461         if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
00462             map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
00463             map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
00464             dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];
00465         }
00466         ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0
00467 
00468         if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
00469             int y_shift  = 2*!IS_INTERLACED(*mb_type);
00470             assert(h->sps.direct_8x8_inference_flag);
00471 
00472             for(i8=0; i8<4; i8++){
00473                 const int x8 = i8&1;
00474                 const int y8 = i8>>1;
00475                 int ref0, scale;
00476                 const int16_t (*l1mv)[2]= l1mv0;
00477 
00478                 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
00479                     continue;
00480                 h->sub_mb_type[i8] = sub_mb_type;
00481 
00482                 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);
00483                 if(IS_INTRA(mb_type_col[y8])){
00484                     fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);
00485                     fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
00486                     fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);
00487                     continue;
00488                 }
00489 
00490                 ref0 = l1ref0[x8 + y8*b8_stride];
00491                 if(ref0 >= 0)
00492                     ref0 = map_col_to_list0[0][ref0 + ref_offset];
00493                 else{
00494                     ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];
00495                     l1mv= l1mv1;
00496                 }
00497                 scale = dist_scale_factor[ref0];
00498                 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);
00499 
00500                 {
00501                     const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride];
00502                     int my_col = (mv_col[1]<<y_shift)/2;
00503                     int mx = (scale * mv_col[0] + 128) >> 8;
00504                     int my = (scale * my_col + 128) >> 8;
00505                     fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);
00506                     fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4);
00507                 }
00508             }
00509             return;
00510         }
00511 
00512         /* one-to-one mv scaling */
00513 
00514         if(IS_16X16(*mb_type)){
00515             int ref, mv0, mv1;
00516 
00517             fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);
00518             if(IS_INTRA(mb_type_col[0])){
00519                 ref=mv0=mv1=0;
00520             }else{
00521                 const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
00522                                                 : map_col_to_list0[1][l1ref1[0] + ref_offset];
00523                 const int scale = dist_scale_factor[ref0];
00524                 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
00525                 int mv_l0[2];
00526                 mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
00527                 mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
00528                 ref= ref0;
00529                 mv0= pack16to32(mv_l0[0],mv_l0[1]);
00530                 mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]);
00531             }
00532             fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
00533             fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
00534             fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
00535         }else{
00536             for(i8=0; i8<4; i8++){
00537                 const int x8 = i8&1;
00538                 const int y8 = i8>>1;
00539                 int ref0, scale;
00540                 const int16_t (*l1mv)[2]= l1mv0;
00541 
00542                 if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
00543                     continue;
00544                 h->sub_mb_type[i8] = sub_mb_type;
00545                 fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);
00546                 if(IS_INTRA(mb_type_col[0])){
00547                     fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);
00548                     fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);
00549                     fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);
00550                     continue;
00551                 }
00552 
00553                 assert(b8_stride == 2);
00554                 ref0 = l1ref0[i8];
00555                 if(ref0 >= 0)
00556                     ref0 = map_col_to_list0[0][ref0 + ref_offset];
00557                 else{
00558                     ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];
00559                     l1mv= l1mv1;
00560                 }
00561                 scale = dist_scale_factor[ref0];
00562 
00563                 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);
00564                 if(IS_SUB_8X8(sub_mb_type)){
00565                     const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride];
00566                     int mx = (scale * mv_col[0] + 128) >> 8;
00567                     int my = (scale * mv_col[1] + 128) >> 8;
00568                     fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);
00569                     fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4);
00570                 }else
00571                 for(i4=0; i4<4; i4++){
00572                     const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride];
00573                     int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]];
00574                     mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
00575                     mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
00576                     AV_WN32A(h->mv_cache[1][scan8[i8*4+i4]],
00577                         pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]));
00578                 }
00579             }
00580         }
00581     }
00582 }
00583 
00584 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){
00585     if(h->direct_spatial_mv_pred){
00586         pred_spatial_direct_motion(h, mb_type);
00587     }else{
00588         pred_temp_direct_motion(h, mb_type);
00589     }
00590 }

Generated on Fri Sep 16 2011 17:17:37 for FFmpeg by  doxygen 1.7.1