comparison mpegvideo.c @ 753:8e1f0939d15d libavcodec

complete mpeg4 GMC decoding support
author michaelni
date Wed, 16 Oct 2002 19:55:49 +0000
parents 25d7fb7c89be
children b2767c9d6455
comparison
equal deleted inserted replaced
752:97077dd24bfa 753:8e1f0939d15d
1030 } 1030 }
1031 1031
1032 static inline void gmc1_motion(MpegEncContext *s, 1032 static inline void gmc1_motion(MpegEncContext *s,
1033 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, 1033 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
1034 int dest_offset, 1034 int dest_offset,
1035 UINT8 **ref_picture, int src_offset, 1035 UINT8 **ref_picture, int src_offset)
1036 int h)
1037 { 1036 {
1038 UINT8 *ptr; 1037 UINT8 *ptr;
1039 int offset, src_x, src_y, linesize, uvlinesize; 1038 int offset, src_x, src_y, linesize, uvlinesize;
1040 int motion_x, motion_y; 1039 int motion_x, motion_y;
1041 int emu=0; 1040 int emu=0;
1042 1041
1043 if(s->real_sprite_warping_points>1) printf("more than 1 warp point isnt supported\n");
1044 motion_x= s->sprite_offset[0][0]; 1042 motion_x= s->sprite_offset[0][0];
1045 motion_y= s->sprite_offset[0][1]; 1043 motion_y= s->sprite_offset[0][1];
1046 src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); 1044 src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
1047 src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); 1045 src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
1048 motion_x<<=(3-s->sprite_warping_accuracy); 1046 motion_x<<=(3-s->sprite_warping_accuracy);
1051 if (src_x == s->width) 1049 if (src_x == s->width)
1052 motion_x =0; 1050 motion_x =0;
1053 src_y = clip(src_y, -16, s->height); 1051 src_y = clip(src_y, -16, s->height);
1054 if (src_y == s->height) 1052 if (src_y == s->height)
1055 motion_y =0; 1053 motion_y =0;
1056 1054
1057 linesize = s->linesize; 1055 linesize = s->linesize;
1058 uvlinesize = s->uvlinesize; 1056 uvlinesize = s->uvlinesize;
1057
1059 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset; 1058 ptr = ref_picture[0] + (src_y * linesize) + src_x + src_offset;
1060 1059
1061 dest_y+=dest_offset; 1060 dest_y+=dest_offset;
1062 if(s->flags&CODEC_FLAG_EMU_EDGE){ 1061 if(s->flags&CODEC_FLAG_EMU_EDGE){
1063 if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos 1062 if(src_x<0 || src_y<0 || src_x + (motion_x&15) + 16 > s->h_edge_pos
1064 || src_y + (motion_y&15) + h > s->v_edge_pos){ 1063 || src_y + (motion_y&15) + 16 > s->v_edge_pos){
1065 emulated_edge_mc(s, ptr, linesize, 17, h+1, src_x, src_y, s->h_edge_pos, s->v_edge_pos); 1064 emulated_edge_mc(s, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
1066 ptr= s->edge_emu_buffer; 1065 ptr= s->edge_emu_buffer;
1067 emu=1; 1066 emu=1;
1068 } 1067 }
1069 } 1068 }
1070 gmc1(dest_y , ptr , linesize, h, motion_x&15, motion_y&15, s->no_rounding); 1069
1071 gmc1(dest_y+8, ptr+8, linesize, h, motion_x&15, motion_y&15, s->no_rounding); 1070 if((motion_x|motion_y)&7){
1071 ff_gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
1072 ff_gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
1073 }else{
1074 int dxy;
1075
1076 dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
1077 if (s->no_rounding){
1078 put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
1079 }else{
1080 put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16);
1081 }
1082 }
1083
1084 if(s->flags&CODEC_FLAG_GRAY) return;
1072 1085
1073 motion_x= s->sprite_offset[1][0]; 1086 motion_x= s->sprite_offset[1][0];
1074 motion_y= s->sprite_offset[1][1]; 1087 motion_y= s->sprite_offset[1][1];
1075 src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); 1088 src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
1076 src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); 1089 src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
1084 motion_y =0; 1097 motion_y =0;
1085 1098
1086 offset = (src_y * uvlinesize) + src_x + (src_offset>>1); 1099 offset = (src_y * uvlinesize) + src_x + (src_offset>>1);
1087 ptr = ref_picture[1] + offset; 1100 ptr = ref_picture[1] + offset;
1088 if(emu){ 1101 if(emu){
1089 emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); 1102 emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
1090 ptr= s->edge_emu_buffer; 1103 ptr= s->edge_emu_buffer;
1091 } 1104 }
1092 gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding); 1105 ff_gmc1(dest_cb + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
1093 1106
1094 ptr = ref_picture[2] + offset; 1107 ptr = ref_picture[2] + offset;
1095 if(emu){ 1108 if(emu){
1096 emulated_edge_mc(s, ptr, uvlinesize, 9, (h>>1)+1, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); 1109 emulated_edge_mc(s, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
1097 ptr= s->edge_emu_buffer; 1110 ptr= s->edge_emu_buffer;
1098 } 1111 }
1099 gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, h>>1, motion_x&15, motion_y&15, s->no_rounding); 1112 ff_gmc1(dest_cr + (dest_offset>>1), ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
1100 1113
1101 return; 1114 return;
1102 } 1115 }
1116
1117 static inline void gmc_motion(MpegEncContext *s,
1118 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
1119 int dest_offset,
1120 UINT8 **ref_picture, int src_offset)
1121 {
1122 UINT8 *ptr;
1123 int linesize, uvlinesize;
1124 const int a= s->sprite_warping_accuracy;
1125 int ox, oy;
1126
1127 linesize = s->linesize;
1128 uvlinesize = s->uvlinesize;
1129
1130 ptr = ref_picture[0] + src_offset;
1131
1132 dest_y+=dest_offset;
1133
1134 ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
1135 oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
1136
1137 ff_gmc(dest_y, ptr, linesize, 16,
1138 ox,
1139 oy,
1140 s->sprite_delta[0][0], s->sprite_delta[0][1],
1141 s->sprite_delta[1][0], s->sprite_delta[1][1],
1142 a+1, (1<<(2*a+1)) - s->no_rounding,
1143 s->h_edge_pos, s->v_edge_pos);
1144 ff_gmc(dest_y+8, ptr, linesize, 16,
1145 ox + s->sprite_delta[0][0]*8,
1146 oy + s->sprite_delta[1][0]*8,
1147 s->sprite_delta[0][0], s->sprite_delta[0][1],
1148 s->sprite_delta[1][0], s->sprite_delta[1][1],
1149 a+1, (1<<(2*a+1)) - s->no_rounding,
1150 s->h_edge_pos, s->v_edge_pos);
1151
1152 if(s->flags&CODEC_FLAG_GRAY) return;
1153
1154
1155 dest_cb+=dest_offset>>1;
1156 dest_cr+=dest_offset>>1;
1157
1158 ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
1159 oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
1160
1161 ptr = ref_picture[1] + (src_offset>>1);
1162 ff_gmc(dest_cb, ptr, uvlinesize, 8,
1163 ox,
1164 oy,
1165 s->sprite_delta[0][0], s->sprite_delta[0][1],
1166 s->sprite_delta[1][0], s->sprite_delta[1][1],
1167 a+1, (1<<(2*a+1)) - s->no_rounding,
1168 s->h_edge_pos>>1, s->v_edge_pos>>1);
1169
1170 ptr = ref_picture[2] + (src_offset>>1);
1171 ff_gmc(dest_cr, ptr, uvlinesize, 8,
1172 ox,
1173 oy,
1174 s->sprite_delta[0][0], s->sprite_delta[0][1],
1175 s->sprite_delta[1][0], s->sprite_delta[1][1],
1176 a+1, (1<<(2*a+1)) - s->no_rounding,
1177 s->h_edge_pos>>1, s->v_edge_pos>>1);
1178 }
1179
1103 1180
1104 static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, 1181 static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h,
1105 int src_x, int src_y, int w, int h){ 1182 int src_x, int src_y, int w, int h){
1106 int x, y; 1183 int x, y;
1107 int start_y, start_x, end_y, end_x; 1184 int start_y, start_x, end_y, end_x;
1355 mb_y = s->mb_y; 1432 mb_y = s->mb_y;
1356 1433
1357 switch(s->mv_type) { 1434 switch(s->mv_type) {
1358 case MV_TYPE_16X16: 1435 case MV_TYPE_16X16:
1359 if(s->mcsel){ 1436 if(s->mcsel){
1360 gmc1_motion(s, dest_y, dest_cb, dest_cr, 0, 1437 if(s->real_sprite_warping_points==1){
1361 ref_picture, 0, 1438 gmc1_motion(s, dest_y, dest_cb, dest_cr, 0,
1362 16); 1439 ref_picture, 0);
1440 }else{
1441 gmc_motion(s, dest_y, dest_cb, dest_cr, 0,
1442 ref_picture, 0);
1443 }
1363 }else if(s->quarter_sample){ 1444 }else if(s->quarter_sample){
1364 qpel_motion(s, dest_y, dest_cb, dest_cr, 0, 1445 qpel_motion(s, dest_y, dest_cb, dest_cr, 0,
1365 ref_picture, 0, 1446 ref_picture, 0,
1366 0, pix_op, qpix_op, 1447 0, pix_op, qpix_op,
1367 s->mv[dir][0][0], s->mv[dir][0][1], 16); 1448 s->mv[dir][0][0], s->mv[dir][0][1], 16);