Mercurial > libavcodec.hg
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); |