comparison msmpeg4.c @ 745:25d7fb7c89be libavcodec

better/cleaner error resilience (done in a 2nd pass after decoding) h263/mpeg4 out of order slice decoding
author michaelni
date Sun, 13 Oct 2002 13:16:04 +0000
parents 4cf7173a004e
children fccad7166d5a
comparison
equal deleted inserted replaced
744:2f7da29ede37 745:25d7fb7c89be
59 int *mx_ptr, int *my_ptr); 59 int *mx_ptr, int *my_ptr);
60 static void msmpeg4v2_encode_motion(MpegEncContext * s, int val); 60 static void msmpeg4v2_encode_motion(MpegEncContext * s, int val);
61 static void init_h263_dc_for_msmpeg4(void); 61 static void init_h263_dc_for_msmpeg4(void);
62 static inline void msmpeg4_memsetw(short *tab, int val, int n); 62 static inline void msmpeg4_memsetw(short *tab, int val, int n);
63 static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra); 63 static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra);
64 64 static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
65 static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
65 66
66 extern UINT32 inverse[256]; 67 extern UINT32 inverse[256];
67 68
68 69
69 #ifdef DEBUG 70 #ifdef DEBUG
502 503
503 static inline void handle_slices(MpegEncContext *s){ 504 static inline void handle_slices(MpegEncContext *s){
504 if (s->mb_x == 0) { 505 if (s->mb_x == 0) {
505 if (s->slice_height && (s->mb_y % s->slice_height) == 0) { 506 if (s->slice_height && (s->mb_y % s->slice_height) == 0) {
506 if(s->msmpeg4_version != 4){ 507 if(s->msmpeg4_version != 4){
507 int wrap; 508 ff_mpeg4_clean_buffers(s);
508 /* reset DC pred (set previous line to 1024) */
509 wrap = 2 * s->mb_width + 2;
510 msmpeg4_memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],
511 1024, 2 * s->mb_width);
512 wrap = s->mb_width + 2;
513 msmpeg4_memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],
514 1024, s->mb_width);
515 msmpeg4_memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap],
516 1024, s->mb_width);
517
518 /* reset AC pred (set previous line to 0) */
519 wrap = s->mb_width * 2 + 2;
520 msmpeg4_memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16,
521 0, 2 * s->mb_width*16);
522 wrap = s->mb_width + 2;
523 msmpeg4_memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16,
524 0, s->mb_width*16);
525 msmpeg4_memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16,
526 0, s->mb_width*16);
527 } 509 }
528 s->first_slice_line = 1; 510 s->first_slice_line = 1;
529 } else { 511 } else {
530 s->first_slice_line = 0; 512 s->first_slice_line = 0;
531 } 513 }
708 * A X 690 * A X
709 */ 691 */
710 a = dc_val[ - 1]; 692 a = dc_val[ - 1];
711 b = dc_val[ - 1 - wrap]; 693 b = dc_val[ - 1 - wrap];
712 c = dc_val[ - wrap]; 694 c = dc_val[ - wrap];
695
696 if(s->first_slice_line && (n&2)==0){
697 b=c=1024;
698 }
713 699
714 /* XXX: the following solution consumes divisions, but it does not 700 /* XXX: the following solution consumes divisions, but it does not
715 necessitate to modify mpegvideo.c. The problem comes from the 701 necessitate to modify mpegvideo.c. The problem comes from the
716 fact they decided to store the quantized DC (which would lead 702 fact they decided to store the quantized DC (which would lead
717 to problems if Q could vary !) */ 703 to problems if Q could vary !) */
939 /* recalculate block_last_index for M$ wmv1 */ 925 /* recalculate block_last_index for M$ wmv1 */
940 if(s->msmpeg4_version==4 && s->block_last_index[n]>0){ 926 if(s->msmpeg4_version==4 && s->block_last_index[n]>0){
941 for(last_index=63; last_index>=0; last_index--){ 927 for(last_index=63; last_index>=0; last_index--){
942 if(block[scantable[last_index]]) break; 928 if(block[scantable[last_index]]) break;
943 } 929 }
930 s->block_last_index[n]= last_index;
944 }else 931 }else
945 last_index = s->block_last_index[n]; 932 last_index = s->block_last_index[n];
946 /* AC coefs */ 933 /* AC coefs */
947 last_non_zero = i - 1; 934 last_non_zero = i - 1;
948 for (; i <= last_index; i++) { 935 for (; i <= last_index; i++) {
1168 1155
1169 init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, 1156 init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
1170 &table_inter_intra[0][1], 2, 1, 1157 &table_inter_intra[0][1], 2, 1,
1171 &table_inter_intra[0][0], 2, 1); 1158 &table_inter_intra[0][0], 2, 1);
1172 } 1159 }
1160
1161 switch(s->msmpeg4_version){
1162 case 1:
1163 case 2:
1164 s->decode_mb= msmpeg4v12_decode_mb;
1165 break;
1166 case 3:
1167 case 4:
1168 s->decode_mb= msmpeg4v34_decode_mb;
1169 break;
1170 }
1171
1173 return 0; 1172 return 0;
1174 } 1173 }
1175 1174
1176 static int decode012(GetBitContext *gb) 1175 static int decode012(GetBitContext *gb)
1177 { 1176 {
1442 val -= 64; 1441 val -= 64;
1443 1442
1444 return val; 1443 return val;
1445 } 1444 }
1446 1445
1447 1446 static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1448 static int msmpeg4v12_decode_mb(MpegEncContext *s,
1449 DCTELEM block[6][64])
1450 { 1447 {
1451 int cbp, code, i; 1448 int cbp, code, i;
1449
1450 s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
1451
1452 if (s->pict_type == P_TYPE) { 1452 if (s->pict_type == P_TYPE) {
1453 if (s->use_skip_mb_code) { 1453 if (s->use_skip_mb_code) {
1454 if (get_bits1(&s->gb)) { 1454 if (get_bits1(&s->gb)) {
1455 /* skip mb */ 1455 /* skip mb */
1456 s->mb_intra = 0; 1456 s->mb_intra = 0;
1528 } 1528 }
1529 } 1529 }
1530 return 0; 1530 return 0;
1531 } 1531 }
1532 1532
1533 int msmpeg4_decode_mb(MpegEncContext *s, 1533 static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
1534 DCTELEM block[6][64])
1535 { 1534 {
1536 int cbp, code, i; 1535 int cbp, code, i;
1537 UINT8 *coded_val; 1536 UINT8 *coded_val;
1538 1537
1539 #ifdef PRINT_MB 1538 #ifdef PRINT_MB
1540 if(s->mb_x==0){ 1539 if(s->mb_x==0){
1541 printf("\n"); 1540 printf("\n");
1542 if(s->mb_y==0) printf("\n"); 1541 if(s->mb_y==0) printf("\n");
1543 } 1542 }
1544 #endif 1543 #endif
1545 /* special slice handling */ 1544
1546 handle_slices(s); 1545 s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
1547
1548 if(s->msmpeg4_version<=2) return msmpeg4v12_decode_mb(s, block); //FIXME export function & call from outside perhaps
1549 1546
1550 if (s->pict_type == P_TYPE) { 1547 if (s->pict_type == P_TYPE) {
1551 set_stat(ST_INTER_MB); 1548 set_stat(ST_INTER_MB);
1552 if (s->use_skip_mb_code) { 1549 if (s->use_skip_mb_code) {
1553 if (get_bits1(&s->gb)) { 1550 if (get_bits1(&s->gb)) {
1864 } 1861 }
1865 if (i > 62){ 1862 if (i > 62){
1866 i-= 192; 1863 i-= 192;
1867 if(i&(~63)){ 1864 if(i&(~63)){
1868 const int left= s->gb.size*8 - get_bits_count(&s->gb); 1865 const int left= s->gb.size*8 - get_bits_count(&s->gb);
1869 if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<0) && left>=0){ 1866 if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<=1) && left>=0){
1870 fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); 1867 fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
1871 break; 1868 break;
1872 }else{ 1869 }else{
1873 fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); 1870 fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
1874 return -1; 1871 return -1;