comparison mpegvideo.c @ 554:3eb6fe38019a libavcodec

4mv & qpel edge emu
author michaelni
date Mon, 15 Jul 2002 00:25:53 +0000
parents 18ad513d92fe
children 762c67fd4078
comparison
equal deleted inserted replaced
553:18ad513d92fe 554:3eb6fe38019a
922 int start_y, start_x, end_y, end_x; 922 int start_y, start_x, end_y, end_x;
923 923
924 if(src_y>= h){ 924 if(src_y>= h){
925 src+= (h-1-src_y)*linesize; 925 src+= (h-1-src_y)*linesize;
926 src_y=h-1; 926 src_y=h-1;
927 }else if(src_y<=-block_h){
928 src+= (1-block_h-src_y)*linesize;
929 src_y=1-block_h;
927 } 930 }
928 if(src_x>= w){ 931 if(src_x>= w){
929 src+= (w-1-src_x); 932 src+= (w-1-src_x);
930 src_x=w-1; 933 src_x=w-1;
934 }else if(src_x<=-block_w){
935 src+= (1-block_w-src_x);
936 src_x=1-block_w;
931 } 937 }
932 938
933 start_y= MAX(0, -src_y); 939 start_y= MAX(0, -src_y);
934 start_x= MAX(0, -src_x); 940 start_x= MAX(0, -src_x);
935 end_y= MIN(block_h, h-src_y); 941 end_y= MIN(block_h, h-src_y);
1065 qpel_mc_func *qpix_op, 1071 qpel_mc_func *qpix_op,
1066 int motion_x, int motion_y, int h) 1072 int motion_x, int motion_y, int h)
1067 { 1073 {
1068 UINT8 *ptr; 1074 UINT8 *ptr;
1069 int dxy, offset, mx, my, src_x, src_y, height, linesize; 1075 int dxy, offset, mx, my, src_x, src_y, height, linesize;
1076 int emu=0;
1070 1077
1071 dxy = ((motion_y & 3) << 2) | (motion_x & 3); 1078 dxy = ((motion_y & 3) << 2) | (motion_x & 3);
1072 src_x = s->mb_x * 16 + (motion_x >> 2); 1079 src_x = s->mb_x * 16 + (motion_x >> 2);
1073 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); 1080 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
1074 1081
1081 dxy &= ~12; 1088 dxy &= ~12;
1082 linesize = s->linesize << field_based; 1089 linesize = s->linesize << field_based;
1083 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; 1090 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset;
1084 dest_y += dest_offset; 1091 dest_y += dest_offset;
1085 //printf("%d %d %d\n", src_x, src_y, dxy); 1092 //printf("%d %d %d\n", src_x, src_y, dxy);
1093
1094 if(s->flags&CODEC_FLAG_EMU_EDGE){
1095 if(src_x<0 || src_y<0 || src_x + (motion_x&3) + 16 > s->width
1096 || src_y + (motion_y&3) + h > height){
1097 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, h+1, src_x, src_y, s->width, height);
1098 ptr= s->edge_emu_buffer;
1099 emu=1;
1100 }
1101 }
1086 qpix_op[dxy](dest_y , ptr , linesize, linesize, motion_x&3, motion_y&3); 1102 qpix_op[dxy](dest_y , ptr , linesize, linesize, motion_x&3, motion_y&3);
1087 qpix_op[dxy](dest_y + 8, ptr + 8, linesize, linesize, motion_x&3, motion_y&3); 1103 qpix_op[dxy](dest_y + 8, ptr + 8, linesize, linesize, motion_x&3, motion_y&3);
1088 qpix_op[dxy](dest_y + linesize*8 , ptr + linesize*8 , linesize, linesize, motion_x&3, motion_y&3); 1104 qpix_op[dxy](dest_y + linesize*8 , ptr + linesize*8 , linesize, linesize, motion_x&3, motion_y&3);
1089 qpix_op[dxy](dest_y + linesize*8 + 8, ptr + linesize*8 + 8, linesize, linesize, motion_x&3, motion_y&3); 1105 qpix_op[dxy](dest_y + linesize*8 + 8, ptr + linesize*8 + 8, linesize, linesize, motion_x&3, motion_y&3);
1090 1106
1110 if (src_y == (height >> 1)) 1126 if (src_y == (height >> 1))
1111 dxy &= ~2; 1127 dxy &= ~2;
1112 1128
1113 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1); 1129 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1);
1114 ptr = ref_picture[1] + offset; 1130 ptr = ref_picture[1] + offset;
1131 if(emu){
1132 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize>>1, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
1133 ptr= s->edge_emu_buffer;
1134 }
1115 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); 1135 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
1136
1116 ptr = ref_picture[2] + offset; 1137 ptr = ref_picture[2] + offset;
1138 if(emu){
1139 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize>>1, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
1140 ptr= s->edge_emu_buffer;
1141 }
1117 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); 1142 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
1118 } 1143 }
1119 1144
1120 1145
1121 static inline void MPV_motion(MpegEncContext *s, 1146 static inline void MPV_motion(MpegEncContext *s,
1124 op_pixels_func *pix_op, qpel_mc_func *qpix_op) 1149 op_pixels_func *pix_op, qpel_mc_func *qpix_op)
1125 { 1150 {
1126 int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y; 1151 int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y;
1127 int mb_x, mb_y, i; 1152 int mb_x, mb_y, i;
1128 UINT8 *ptr, *dest; 1153 UINT8 *ptr, *dest;
1154 int emu=0;
1129 1155
1130 mb_x = s->mb_x; 1156 mb_x = s->mb_x;
1131 mb_y = s->mb_y; 1157 mb_y = s->mb_y;
1132 1158
1133 switch(s->mv_type) { 1159 switch(s->mv_type) {
1173 src_y = clip(src_y, -16, s->height); 1199 src_y = clip(src_y, -16, s->height);
1174 if (src_y == s->height) 1200 if (src_y == s->height)
1175 dxy &= ~2; 1201 dxy &= ~2;
1176 1202
1177 ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); 1203 ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
1204 if(s->flags&CODEC_FLAG_EMU_EDGE){
1205 if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 8 > s->width
1206 || src_y + (motion_y&1) + 8 > s->height){
1207 emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 9, 9, src_x, src_y, s->width, s->height);
1208 ptr= s->edge_emu_buffer;
1209 }
1210 }
1178 dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; 1211 dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
1179 pix_op[dxy](dest, ptr, s->linesize, 8); 1212 pix_op[dxy](dest, ptr, s->linesize, 8);
1180 } 1213 }
1181 1214
1182 if(s->flags&CODEC_FLAG_GRAY) break; 1215 if(s->flags&CODEC_FLAG_GRAY) break;
1213 if (src_y == s->height/2) 1246 if (src_y == s->height/2)
1214 dxy &= ~2; 1247 dxy &= ~2;
1215 1248
1216 offset = (src_y * (s->linesize >> 1)) + src_x; 1249 offset = (src_y * (s->linesize >> 1)) + src_x;
1217 ptr = ref_picture[1] + offset; 1250 ptr = ref_picture[1] + offset;
1251 if(s->flags&CODEC_FLAG_EMU_EDGE){
1252 if(src_x<0 || src_y<0 || src_x + (dxy &1) + 8 > s->width >>1
1253 || src_y + (dxy>>1) + 8 > s->height>>1){
1254 emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize>>1, 9, 9, src_x, src_y, s->width>>1, s->height>>1);
1255 ptr= s->edge_emu_buffer;
1256 emu=1;
1257 }
1258 }
1218 pix_op[dxy](dest_cb, ptr, s->linesize >> 1, 8); 1259 pix_op[dxy](dest_cb, ptr, s->linesize >> 1, 8);
1260
1219 ptr = ref_picture[2] + offset; 1261 ptr = ref_picture[2] + offset;
1262 if(emu){
1263 emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize>>1, 9, 9, src_x, src_y, s->width>>1, s->height>>1);
1264 ptr= s->edge_emu_buffer;
1265 }
1220 pix_op[dxy](dest_cr, ptr, s->linesize >> 1, 8); 1266 pix_op[dxy](dest_cr, ptr, s->linesize >> 1, 8);
1221 break; 1267 break;
1222 case MV_TYPE_FIELD: 1268 case MV_TYPE_FIELD:
1223 if (s->picture_structure == PICT_FRAME) { 1269 if (s->picture_structure == PICT_FRAME) {
1224 /* top field */ 1270 /* top field */