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