Mercurial > libavcodec.hg
comparison mpegvideo.c @ 295:6622b0fd036c libavcodec
mpeg4 4MV encoding
author | michaelni |
---|---|
date | Thu, 28 Mar 2002 04:25:35 +0000 |
parents | 944632089814 |
children | a1234c032636 |
comparison
equal
deleted
inserted
replaced
294:944632089814 | 295:6622b0fd036c |
---|---|
13 * GNU General Public License for more details. | 13 * GNU General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU General Public License | 15 * You should have received a copy of the GNU General Public License |
16 * along with this program; if not, write to the Free Software | 16 * along with this program; if not, write to the Free Software |
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 * | |
19 * 4MV & hq encoding stuff by Michael Niedermayer <michaelni@gmx.at> | |
18 */ | 20 */ |
19 #include <stdlib.h> | 21 #include <stdlib.h> |
20 #include <stdio.h> | 22 #include <stdio.h> |
21 #include <math.h> | 23 #include <math.h> |
22 #include <string.h> | 24 #include <string.h> |
358 s->h263_msmpeg4 = 1; | 360 s->h263_msmpeg4 = 1; |
359 s->h263_pred = 1; | 361 s->h263_pred = 1; |
360 s->unrestricted_mv = 1; | 362 s->unrestricted_mv = 1; |
361 break; | 363 break; |
362 default: | 364 default: |
365 return -1; | |
366 } | |
367 | |
368 if((s->flags&CODEC_FLAG_4MV) && !(s->flags&CODEC_FLAG_HQ)){ | |
369 printf("4MV is currently only supported in HQ mode\n"); | |
363 return -1; | 370 return -1; |
364 } | 371 } |
365 | 372 |
366 { /* set up some save defaults, some codecs might override them later */ | 373 { /* set up some save defaults, some codecs might override them later */ |
367 static int done=0; | 374 static int done=0; |
813 motion_x = s->mv[dir][i][0]; | 820 motion_x = s->mv[dir][i][0]; |
814 motion_y = s->mv[dir][i][1]; | 821 motion_y = s->mv[dir][i][1]; |
815 | 822 |
816 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | 823 dxy = ((motion_y & 1) << 1) | (motion_x & 1); |
817 src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8; | 824 src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8; |
818 src_y = mb_y * 16 + (motion_y >> 1) + ((i >> 1) & 1) * 8; | 825 src_y = mb_y * 16 + (motion_y >> 1) + (i >>1) * 8; |
819 | 826 |
820 /* WARNING: do no forget half pels */ | 827 /* WARNING: do no forget half pels */ |
821 src_x = clip(src_x, -16, s->width); | 828 src_x = clip(src_x, -16, s->width); |
822 if (src_x == s->width) | 829 if (src_x == s->width) |
823 dxy &= ~1; | 830 dxy &= ~1; |
1109 get_pixels(s->block[5], ptr, wrap); | 1116 get_pixels(s->block[5], ptr, wrap); |
1110 | 1117 |
1111 /* subtract previous frame if non intra */ | 1118 /* subtract previous frame if non intra */ |
1112 if (!s->mb_intra) { | 1119 if (!s->mb_intra) { |
1113 int dxy, offset, mx, my; | 1120 int dxy, offset, mx, my; |
1114 | 1121 |
1115 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | 1122 if(s->mv_type==MV_TYPE_16X16){ |
1116 ptr = s->last_picture[0] + | 1123 dxy = ((motion_y & 1) << 1) | (motion_x & 1); |
1117 ((mb_y * 16 + (motion_y >> 1)) * s->linesize) + | 1124 ptr = s->last_picture[0] + |
1118 (mb_x * 16 + (motion_x >> 1)); | 1125 ((mb_y * 16 + (motion_y >> 1)) * s->linesize) + |
1119 | 1126 (mb_x * 16 + (motion_x >> 1)); |
1120 sub_pixels_2(s->block[0], ptr, s->linesize, dxy); | 1127 |
1121 sub_pixels_2(s->block[1], ptr + 8, s->linesize, dxy); | 1128 sub_pixels_2(s->block[0], ptr, s->linesize, dxy); |
1122 sub_pixels_2(s->block[2], ptr + s->linesize * 8, s->linesize, dxy); | 1129 sub_pixels_2(s->block[1], ptr + 8, s->linesize, dxy); |
1123 sub_pixels_2(s->block[3], ptr + 8 + s->linesize * 8, s->linesize ,dxy); | 1130 sub_pixels_2(s->block[2], ptr + s->linesize * 8, s->linesize, dxy); |
1124 | 1131 sub_pixels_2(s->block[3], ptr + 8 + s->linesize * 8, s->linesize ,dxy); |
1125 if (s->out_format == FMT_H263) { | 1132 |
1126 /* special rounding for h263 */ | 1133 if (s->out_format == FMT_H263) { |
1127 dxy = 0; | 1134 /* special rounding for h263 */ |
1128 if ((motion_x & 3) != 0) | 1135 dxy = 0; |
1129 dxy |= 1; | 1136 if ((motion_x & 3) != 0) |
1130 if ((motion_y & 3) != 0) | 1137 dxy |= 1; |
1131 dxy |= 2; | 1138 if ((motion_y & 3) != 0) |
1132 mx = motion_x >> 2; | 1139 dxy |= 2; |
1133 my = motion_y >> 2; | 1140 mx = motion_x >> 2; |
1134 } else { | 1141 my = motion_y >> 2; |
1135 mx = motion_x / 2; | 1142 } else { |
1136 my = motion_y / 2; | 1143 mx = motion_x / 2; |
1144 my = motion_y / 2; | |
1145 dxy = ((my & 1) << 1) | (mx & 1); | |
1146 mx >>= 1; | |
1147 my >>= 1; | |
1148 } | |
1149 offset = ((mb_y * 8 + my) * (s->linesize >> 1)) + (mb_x * 8 + mx); | |
1150 ptr = s->last_picture[1] + offset; | |
1151 sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy); | |
1152 ptr = s->last_picture[2] + offset; | |
1153 sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy); | |
1154 }else{ | |
1155 int src_x, src_y; | |
1156 | |
1157 for(i=0;i<4;i++) { | |
1158 int motion_x = s->mv[0][i][0]; | |
1159 int motion_y = s->mv[0][i][1]; | |
1160 | |
1161 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
1162 src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8; | |
1163 src_y = mb_y * 16 + (motion_y >> 1) + (i >>1) * 8; | |
1164 | |
1165 ptr = s->last_picture[0] + (src_y * s->linesize) + (src_x); | |
1166 sub_pixels_2(s->block[i], ptr, s->linesize, dxy); | |
1167 } | |
1168 /* In case of 8X8, we construct a single chroma motion vector | |
1169 with a special rounding */ | |
1170 mx = 0; | |
1171 my = 0; | |
1172 for(i=0;i<4;i++) { | |
1173 mx += s->mv[0][i][0]; | |
1174 my += s->mv[0][i][1]; | |
1175 } | |
1176 if (mx >= 0) | |
1177 mx = (h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1)); | |
1178 else { | |
1179 mx = -mx; | |
1180 mx = -(h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1)); | |
1181 } | |
1182 if (my >= 0) | |
1183 my = (h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1)); | |
1184 else { | |
1185 my = -my; | |
1186 my = -(h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1)); | |
1187 } | |
1137 dxy = ((my & 1) << 1) | (mx & 1); | 1188 dxy = ((my & 1) << 1) | (mx & 1); |
1138 mx >>= 1; | 1189 mx >>= 1; |
1139 my >>= 1; | 1190 my >>= 1; |
1140 } | 1191 |
1141 offset = ((mb_y * 8 + my) * (s->linesize >> 1)) + (mb_x * 8 + mx); | 1192 src_x = mb_x * 8 + mx; |
1142 ptr = s->last_picture[1] + offset; | 1193 src_y = mb_y * 8 + my; |
1143 sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy); | 1194 src_x = clip(src_x, -8, s->width/2); |
1144 ptr = s->last_picture[2] + offset; | 1195 if (src_x == s->width/2) |
1145 sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy); | 1196 dxy &= ~1; |
1197 src_y = clip(src_y, -8, s->height/2); | |
1198 if (src_y == s->height/2) | |
1199 dxy &= ~2; | |
1200 | |
1201 offset = (src_y * (s->linesize >> 1)) + src_x; | |
1202 ptr = s->last_picture[1] + offset; | |
1203 sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy); | |
1204 ptr = s->last_picture[2] + offset; | |
1205 sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy); | |
1206 } | |
1146 } | 1207 } |
1147 | 1208 |
1148 #if 0 | 1209 #if 0 |
1149 { | 1210 { |
1150 float adap_parm; | 1211 float adap_parm; |
1267 UINT8 * fcode_tab= s->fcode_tab; | 1328 UINT8 * fcode_tab= s->fcode_tab; |
1268 | 1329 |
1269 for(i=0; i<8; i++) mv_num[i]=0; | 1330 for(i=0; i<8; i++) mv_num[i]=0; |
1270 | 1331 |
1271 for(i=0; i<s->mb_num; i++){ | 1332 for(i=0; i<s->mb_num; i++){ |
1272 if(s->mb_type[i] & (MB_TYPE_INTER|MB_TYPE_INTER4V)){ | 1333 if(s->mb_type[i] & MB_TYPE_INTER){ |
1273 mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++; | 1334 mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++; |
1274 mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++; | 1335 mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++; |
1275 //printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i); | 1336 //printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i); |
1276 } | 1337 } |
1277 //else printf("I"); | 1338 //else printf("I"); |
1291 } | 1352 } |
1292 | 1353 |
1293 //printf("f_code %d ///\n", s->f_code); | 1354 //printf("f_code %d ///\n", s->f_code); |
1294 /* convert MBs with too long MVs to I-Blocks */ | 1355 /* convert MBs with too long MVs to I-Blocks */ |
1295 if(s->pict_type==P_TYPE){ | 1356 if(s->pict_type==P_TYPE){ |
1296 int i; | 1357 int i, x, y; |
1297 const int f_code= s->f_code; | 1358 const int f_code= s->f_code; |
1298 UINT8 * fcode_tab= s->fcode_tab; | 1359 UINT8 * fcode_tab= s->fcode_tab; |
1299 | 1360 //FIXME try to clip instead of intra izing ;) |
1361 /* clip / convert to intra 16x16 type MVs */ | |
1300 for(i=0; i<s->mb_num; i++){ | 1362 for(i=0; i<s->mb_num; i++){ |
1301 if(s->mb_type[i]&MB_TYPE_INTER){ | 1363 if(s->mb_type[i]&MB_TYPE_INTER){ |
1302 if( fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code | 1364 if( fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code |
1303 || fcode_tab[s->mv_table[0][i] + MAX_MV] == 0 | 1365 || fcode_tab[s->mv_table[0][i] + MAX_MV] == 0 |
1304 || fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code | 1366 || fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code |
1307 s->mb_type[i] |= MB_TYPE_INTRA; | 1369 s->mb_type[i] |= MB_TYPE_INTRA; |
1308 s->mv_table[0][i] = 0; | 1370 s->mv_table[0][i] = 0; |
1309 s->mv_table[1][i] = 0; | 1371 s->mv_table[1][i] = 0; |
1310 } | 1372 } |
1311 } | 1373 } |
1312 if(s->mb_type[i]&MB_TYPE_INTER4V){ | 1374 } |
1313 //FIXME | 1375 |
1376 if(s->flags&CODEC_FLAG_4MV){ | |
1377 int wrap= 2+ s->mb_width*2; | |
1378 | |
1379 /* clip / convert to intra 8x8 type MVs */ | |
1380 for(y=0; y<s->mb_height; y++){ | |
1381 int xy= (y*2 + 1)*wrap + 1; | |
1382 i= y*s->mb_width; | |
1383 | |
1384 for(x=0; x<s->mb_width; x++){ | |
1385 if(s->mb_type[i]&MB_TYPE_INTER4V){ | |
1386 int block; | |
1387 for(block=0; block<4; block++){ | |
1388 int off= (block& 1) + (block>>1)*wrap; | |
1389 int mx= s->motion_val[ xy + off ][0]; | |
1390 int my= s->motion_val[ xy + off ][1]; | |
1391 | |
1392 if( fcode_tab[mx + MAX_MV] > f_code | |
1393 || fcode_tab[mx + MAX_MV] == 0 | |
1394 || fcode_tab[my + MAX_MV] > f_code | |
1395 || fcode_tab[my + MAX_MV] == 0 ){ | |
1396 s->mb_type[i] &= ~MB_TYPE_INTER4V; | |
1397 s->mb_type[i] |= MB_TYPE_INTRA; | |
1398 } | |
1399 } | |
1400 xy+=2; | |
1401 i++; | |
1402 } | |
1403 } | |
1314 } | 1404 } |
1315 } | 1405 } |
1316 } | 1406 } |
1317 | 1407 |
1318 // printf("%d %d\n", s->avg_mb_var, s->mc_mb_var); | 1408 // printf("%d %d\n", s->avg_mb_var, s->mc_mb_var); |
1418 s->block_index[2]+=2; | 1508 s->block_index[2]+=2; |
1419 s->block_index[3]+=2; | 1509 s->block_index[3]+=2; |
1420 s->block_index[4]++; | 1510 s->block_index[4]++; |
1421 s->block_index[5]++; | 1511 s->block_index[5]++; |
1422 | 1512 |
1423 s->mv_type = MV_TYPE_16X16; | |
1424 s->mv_dir = MV_DIR_FORWARD; | 1513 s->mv_dir = MV_DIR_FORWARD; |
1425 if(mb_type & (mb_type-1)){ // more than 1 MB type possible | 1514 if(mb_type & (mb_type-1)){ // more than 1 MB type possible |
1426 pb= s->pb; | 1515 pb= s->pb; |
1427 if(mb_type&MB_TYPE_INTER){ | 1516 if(mb_type&MB_TYPE_INTER){ |
1517 s->mv_type = MV_TYPE_16X16; | |
1428 s->mb_intra= 0; | 1518 s->mb_intra= 0; |
1429 s->mv[0][0][0] = s->mv_table[0][mb_y * s->mb_width + mb_x]; | 1519 s->mv[0][0][0] = s->mv_table[0][mb_y * s->mb_width + mb_x]; |
1430 s->mv[0][0][1] = s->mv_table[1][mb_y * s->mb_width + mb_x]; | 1520 s->mv[0][0][1] = s->mv_table[1][mb_y * s->mb_width + mb_x]; |
1431 init_put_bits(&s->pb, bit_buf[1], 3000, NULL, NULL); | 1521 init_put_bits(&s->pb, bit_buf[1], 3000, NULL, NULL); |
1432 s->block= s->inter_block; | 1522 s->block= s->inter_block; |
1437 flush_put_bits(&s->pb); | 1527 flush_put_bits(&s->pb); |
1438 dmin=d; | 1528 dmin=d; |
1439 best_s.mv[0][0][0]= s->mv[0][0][0]; | 1529 best_s.mv[0][0][0]= s->mv[0][0][0]; |
1440 best_s.mv[0][0][1]= s->mv[0][0][1]; | 1530 best_s.mv[0][0][1]= s->mv[0][0][1]; |
1441 best_s.mb_intra= 0; | 1531 best_s.mb_intra= 0; |
1532 best_s.mv_type = MV_TYPE_16X16; | |
1442 best_s.pb=s->pb; | 1533 best_s.pb=s->pb; |
1443 best_s.block= s->block; | 1534 best_s.block= s->block; |
1444 best=1; | 1535 best=1; |
1445 for(i=0; i<6; i++) | 1536 for(i=0; i<6; i++) |
1446 best_s.block_last_index[i]= s->block_last_index[i]; | 1537 best_s.block_last_index[i]= s->block_last_index[i]; |
1447 } | 1538 } |
1448 } | 1539 } |
1540 if(mb_type&MB_TYPE_INTER4V){ | |
1541 s->mv_type = MV_TYPE_8X8; | |
1542 s->mb_intra= 0; | |
1543 for(i=0; i<4; i++){ | |
1544 s->mv[0][i][0] = s->motion_val[s->block_index[i]][0]; | |
1545 s->mv[0][i][1] = s->motion_val[s->block_index[i]][1]; | |
1546 } | |
1547 init_put_bits(&s->pb, bit_buf[2], 3000, NULL, NULL); | |
1548 s->block= s->inter4v_block; | |
1549 | |
1550 encode_mb(s); | |
1551 d= get_bit_count(&s->pb); | |
1552 if(d<dmin){ | |
1553 flush_put_bits(&s->pb); | |
1554 dmin=d; | |
1555 for(i=0; i<4; i++){ | |
1556 best_s.mv[0][i][0] = s->mv[0][i][0]; | |
1557 best_s.mv[0][i][1] = s->mv[0][i][1]; | |
1558 } | |
1559 best_s.mb_intra= 0; | |
1560 best_s.mv_type = MV_TYPE_8X8; | |
1561 best_s.pb=s->pb; | |
1562 best_s.block= s->block; | |
1563 best=2; | |
1564 for(i=0; i<6; i++) | |
1565 best_s.block_last_index[i]= s->block_last_index[i]; | |
1566 } | |
1567 } | |
1449 if(mb_type&MB_TYPE_INTRA){ | 1568 if(mb_type&MB_TYPE_INTRA){ |
1569 s->mv_type = MV_TYPE_16X16; | |
1450 s->mb_intra= 1; | 1570 s->mb_intra= 1; |
1451 s->mv[0][0][0] = 0; | 1571 s->mv[0][0][0] = 0; |
1452 s->mv[0][0][1] = 0; | 1572 s->mv[0][0][1] = 0; |
1453 init_put_bits(&s->pb, bit_buf[0], 3000, NULL, NULL); | 1573 init_put_bits(&s->pb, bit_buf[0], 3000, NULL, NULL); |
1454 s->block= s->intra_block; | 1574 s->block= s->intra_block; |
1459 flush_put_bits(&s->pb); | 1579 flush_put_bits(&s->pb); |
1460 dmin=d; | 1580 dmin=d; |
1461 best_s.mv[0][0][0]= 0; | 1581 best_s.mv[0][0][0]= 0; |
1462 best_s.mv[0][0][1]= 0; | 1582 best_s.mv[0][0][1]= 0; |
1463 best_s.mb_intra= 1; | 1583 best_s.mb_intra= 1; |
1584 best_s.mv_type = MV_TYPE_16X16; | |
1464 best_s.pb=s->pb; | 1585 best_s.pb=s->pb; |
1465 best_s.block= s->block; | 1586 best_s.block= s->block; |
1466 for(i=0; i<6; i++) | 1587 for(i=0; i<6; i++) |
1467 best_s.block_last_index[i]= s->block_last_index[i]; | 1588 best_s.block_last_index[i]= s->block_last_index[i]; |
1468 best=0; | 1589 best=0; |
1469 } | 1590 } |
1470 /* force cleaning of ac/dc if needed ... */ | 1591 /* force cleaning of ac/dc if needed ... */ |
1471 s->mbintra_table[mb_x + mb_y*s->mb_width]=1; | 1592 s->mbintra_table[mb_x + mb_y*s->mb_width]=1; |
1472 } | 1593 } |
1473 s->mv[0][0][0]= best_s.mv[0][0][0]; | 1594 for(i=0; i<4; i++){ |
1474 s->mv[0][0][1]= best_s.mv[0][0][1]; | 1595 s->mv[0][i][0] = best_s.mv[0][i][0]; |
1596 s->mv[0][i][1] = best_s.mv[0][i][1]; | |
1597 } | |
1475 s->mb_intra= best_s.mb_intra; | 1598 s->mb_intra= best_s.mb_intra; |
1599 s->mv_type= best_s.mv_type; | |
1476 for(i=0; i<6; i++) | 1600 for(i=0; i<6; i++) |
1477 s->block_last_index[i]= best_s.block_last_index[i]; | 1601 s->block_last_index[i]= best_s.block_last_index[i]; |
1478 copy_bits(&pb, bit_buf[best], dmin); | 1602 copy_bits(&pb, bit_buf[best], dmin); |
1479 s->block= best_s.block; | 1603 s->block= best_s.block; |
1480 s->pb= pb; | 1604 s->pb= pb; |