📄 mpegvideo_common.h
字号:
} pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); ptr = ref_picture[2] + offset; if(emu){ ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); ptr= s->edge_emu_buffer; } pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);}static _inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ /* fetch pixels for estimated mv 4 macroblocks ahead * optimized for 64byte cache lines */ const int shift = s->quarter_sample ? 2 : 1; const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; s->dsp.prefetch(pix[0]+off, s->linesize, 4); off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);}/** * motion compensation of a single macroblock * @param s context * @param dest_y luma destination pointer * @param dest_cb chroma cb/u destination pointer * @param dest_cr chroma cr/v destination pointer * @param dir direction (0->forward, 1->backward) * @param ref_picture array[3] of pointers to the 3 planes of the reference picture * @param pic_op halfpel motion compensation function (average or put normally) * @param pic_op qpel motion compensation function (average or put normally) * the motion vectors are taken from s->mv and the MV type from s->mv_type */static av_always_inline void MPV_motion_internal(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int dir, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16], int is_mpeg12){ int dxy, mx, my, src_x, src_y, motion_x, motion_y; int mb_x, mb_y, i; uint8_t *ptr, *dest; mb_x = s->mb_x; mb_y = s->mb_y; prefetch_motion(s, ref_picture, dir); if(!is_mpeg12 && s->obmc && s->pict_type != FF_B_TYPE){ int16_t mv_cache[4][4][2]; const int xy= s->mb_x + s->mb_y*s->mb_stride; const int mot_stride= s->b8_stride; const int mot_xy= mb_x*2 + mb_y*2*mot_stride; assert(!s->mb_skipped); memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4); memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){ memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4); }else{ memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4); } if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){ *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1]; *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1]; }else{ *(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1]; *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride]; } if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){ *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2]; *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2]; }else{ *(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2]; *(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride]; } mx = 0; my = 0; for(i=0;i<4;i++) { const int x= (i&1)+1; const int y= (i>>1)+1; int16_t mv[5][2]= { {mv_cache[y][x ][0], mv_cache[y][x ][1]}, {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; //FIXME cleanup obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, ref_picture[0], mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, pix_op[1], mv); mx += mv[0][0]; my += mv[0][1]; } if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); return; } switch(s->mv_type) { case MV_TYPE_16X16: if(s->mcsel){ if(s->real_sprite_warping_points==1){ gmc1_motion(s, dest_y, dest_cb, dest_cr, ref_picture); }else{ gmc_motion(s, dest_y, dest_cb, dest_cr, ref_picture); } }else if(!is_mpeg12 && s->quarter_sample){ qpel_motion(s, dest_y, dest_cb, dest_cr, 0, 0, 0, ref_picture, pix_op, qpix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); }else if(!is_mpeg12 && CONFIG_WMV2 && s->mspel){ }else { mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, 0, ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); } break; case MV_TYPE_8X8: if (!is_mpeg12) { mx = 0; my = 0; if(s->quarter_sample){ for(i=0;i<4;i++) { motion_x = s->mv[dir][i][0]; motion_y = s->mv[dir][i][1]; dxy = ((motion_y & 3) << 2) | (motion_x & 3); src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; /* WARNING: do no forget half pels */ src_x = av_clip(src_x, -16, s->width); if (src_x == s->width) dxy &= ~3; src_y = av_clip(src_y, -16, s->height); if (src_y == s->height) dxy &= ~12; ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); if(s->flags&CODEC_FLAG_EMU_EDGE){ if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8 || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){ ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos); ptr= s->edge_emu_buffer; } } dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; qpix_op[1][dxy](dest, ptr, s->linesize); mx += s->mv[dir][i][0]/2; my += s->mv[dir][i][1]/2; } }else{ for(i=0;i<4;i++) { hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, ref_picture[0], 0, 0, mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, s->width, s->height, s->linesize, s->h_edge_pos, s->v_edge_pos, 8, 8, pix_op[1], s->mv[dir][i][0], s->mv[dir][i][1]); mx += s->mv[dir][i][0]; my += s->mv[dir][i][1]; } } if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)) chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); } break; case MV_TYPE_FIELD: if (s->picture_structure == PICT_FRAME) { if(!is_mpeg12 && s->quarter_sample){ for(i=0; i<2; i++){ qpel_motion(s, dest_y, dest_cb, dest_cr, 1, i, s->field_select[dir][i], ref_picture, pix_op, qpix_op, s->mv[dir][i][0], s->mv[dir][i][1], 8); } }else{ /* top field */ mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, 0, s->field_select[dir][0], ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 8); /* bottom field */ mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, 1, s->field_select[dir][1], ref_picture, pix_op, s->mv[dir][1][0], s->mv[dir][1][1], 8); } } else { if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != FF_B_TYPE && !s->first_field){ ref_picture= s->current_picture_ptr->data; } mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][0], ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); } break; case MV_TYPE_16X8: for(i=0; i<2; i++){ uint8_t ** ref2picture; if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == FF_B_TYPE || s->first_field){ ref2picture= ref_picture; }else{ ref2picture= s->current_picture_ptr->data; } mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->field_select[dir][i], ref2picture, pix_op, s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8); dest_y += 16*s->linesize; dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; } break; case MV_TYPE_DMV: if(s->picture_structure == PICT_FRAME){ for(i=0; i<2; i++){ int j; for(j=0; j<2; j++){ mpeg_motion(s, dest_y, dest_cb, dest_cr, 1, j, j^i, ref_picture, pix_op, s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8); } pix_op = s->dsp.avg_pixels_tab; } }else{ for(i=0; i<2; i++){ mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, 0, s->picture_structure != i+1, ref_picture, pix_op, s->mv[dir][2*i][0],s->mv[dir][2*i][1],16); // after put we make avg of the same block pix_op=s->dsp.avg_pixels_tab; //opposite parity is always in the same frame if this is second field if(!s->first_field){ ref_picture = s->current_picture_ptr->data; } } } break; default: assert(0); }}static _inline void MPV_motion(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int dir, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16]){#if !CONFIG_SMALL if(s->out_format == FMT_MPEG1) MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, ref_picture, pix_op, qpix_op, 1); else#endif MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir, ref_picture, pix_op, qpix_op, 0);}#endif /* AVCODEC_MPEGVIDEO_COMMON_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -