Mercurial > libavcodec.hg
comparison h263.c @ 1708:dea5b2946999 libavcodec
interlaced motion estimation
interlaced mpeg2 encoding
P & B frames
rate distored interlaced mb decission
alternate scantable support
4mv encoding fixes (thats also why the regression tests change)
passing height to most dsp functions
interlaced mpeg4 encoding (no direct mode MBs yet)
various related cleanups
disabled old motion estimaton algorithms (log, full, ...) they will either be fixed or removed
author | michael |
---|---|
date | Tue, 30 Dec 2003 16:07:57 +0000 |
parents | 95b7ac3344df |
children | 07a484280a82 |
comparison
equal
deleted
inserted
replaced
1707:027545a2fdbe | 1708:dea5b2946999 |
---|---|
477 ff_clean_h263_qscales(s); | 477 ff_clean_h263_qscales(s); |
478 | 478 |
479 for(i=1; i<s->mb_num; i++){ | 479 for(i=1; i<s->mb_num; i++){ |
480 int mb_xy= s->mb_index2xy[i]; | 480 int mb_xy= s->mb_index2xy[i]; |
481 | 481 |
482 if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_INTER4V)){ | 482 if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){ |
483 s->mb_type[mb_xy]&= ~MB_TYPE_INTER4V; | 483 s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V; |
484 s->mb_type[mb_xy]|= MB_TYPE_INTER; | 484 s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER; |
485 } | 485 } |
486 } | 486 } |
487 | 487 |
488 if(s->pict_type== B_TYPE){ | 488 if(s->pict_type== B_TYPE){ |
489 int odd=0; | 489 int odd=0; |
506 qscale_table[mb_xy]= 31; | 506 qscale_table[mb_xy]= 31; |
507 } | 507 } |
508 | 508 |
509 for(i=1; i<s->mb_num; i++){ | 509 for(i=1; i<s->mb_num; i++){ |
510 int mb_xy= s->mb_index2xy[i]; | 510 int mb_xy= s->mb_index2xy[i]; |
511 if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&MB_TYPE_DIRECT)){ | 511 if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ |
512 s->mb_type[mb_xy]&= ~MB_TYPE_DIRECT; | 512 s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_DIRECT; |
513 s->mb_type[mb_xy]|= MB_TYPE_BIDIR; | 513 s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; |
514 } | 514 } |
515 } | 515 } |
516 } | 516 } |
517 } | 517 } |
518 | 518 |
521 * | 521 * |
522 * @return the mb_type | 522 * @return the mb_type |
523 */ | 523 */ |
524 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ | 524 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ |
525 const int mb_index= s->mb_x + s->mb_y*s->mb_stride; | 525 const int mb_index= s->mb_x + s->mb_y*s->mb_stride; |
526 const int colocated_mb_type= s->next_picture.mb_type[mb_index]; //FIXME or next? | 526 const int colocated_mb_type= s->next_picture.mb_type[mb_index]; |
527 int xy= s->block_index[0]; | 527 int xy= s->block_index[0]; |
528 uint16_t time_pp= s->pp_time; | 528 uint16_t time_pp= s->pp_time; |
529 uint16_t time_pb= s->pb_time; | 529 uint16_t time_pb= s->pb_time; |
530 int i; | 530 int i; |
531 | 531 |
545 return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; | 545 return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; |
546 } else if(IS_INTERLACED(colocated_mb_type)){ | 546 } else if(IS_INTERLACED(colocated_mb_type)){ |
547 s->mv_type = MV_TYPE_FIELD; | 547 s->mv_type = MV_TYPE_FIELD; |
548 for(i=0; i<2; i++){ | 548 for(i=0; i<2; i++){ |
549 if(s->top_field_first){ | 549 if(s->top_field_first){ |
550 time_pp= s->pp_field_time - s->field_select_table[mb_index][i] + i; | 550 time_pp= s->pp_field_time - s->p_field_select_table[i][mb_index] + i; |
551 time_pb= s->pb_field_time - s->field_select_table[mb_index][i] + i; | 551 time_pb= s->pb_field_time - s->p_field_select_table[i][mb_index] + i; |
552 }else{ | 552 }else{ |
553 time_pp= s->pp_field_time + s->field_select_table[mb_index][i] - i; | 553 time_pp= s->pp_field_time + s->p_field_select_table[i][mb_index] - i; |
554 time_pb= s->pb_field_time + s->field_select_table[mb_index][i] - i; | 554 time_pb= s->pb_field_time + s->p_field_select_table[i][mb_index] - i; |
555 } | 555 } |
556 s->mv[0][i][0] = s->field_mv_table[mb_index][i][0]*time_pb/time_pp + mx; | 556 s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx; |
557 s->mv[0][i][1] = s->field_mv_table[mb_index][i][1]*time_pb/time_pp + my; | 557 s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my; |
558 s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->field_mv_table[mb_index][i][0] | 558 s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0] |
559 : s->field_mv_table[mb_index][i][0]*(time_pb - time_pp)/time_pp; | 559 : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp; |
560 s->mv[1][i][1] = my ? s->mv[0][i][1] - s->field_mv_table[mb_index][i][1] | 560 s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1] |
561 : s->field_mv_table[mb_index][i][1]*(time_pb - time_pp)/time_pp; | 561 : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp; |
562 } | 562 } |
563 return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; | 563 return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; |
564 }else{ | 564 }else{ |
565 s->mv[0][0][0] = s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp + mx; | 565 s->mv[0][0][0] = s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp + mx; |
566 s->mv[0][0][1] = s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp + my; | 566 s->mv[0][0][1] = s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp + my; |
596 int i; | 596 int i; |
597 motion_x = s->mv[0][0][0] + s->mv[0][1][0]; | 597 motion_x = s->mv[0][0][0] + s->mv[0][1][0]; |
598 motion_y = s->mv[0][0][1] + s->mv[0][1][1]; | 598 motion_y = s->mv[0][0][1] + s->mv[0][1][1]; |
599 motion_x = (motion_x>>1) | (motion_x&1); | 599 motion_x = (motion_x>>1) | (motion_x&1); |
600 for(i=0; i<2; i++){ | 600 for(i=0; i<2; i++){ |
601 s->field_mv_table[mb_xy][i][0]= s->mv[0][i][0]; | 601 s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; |
602 s->field_mv_table[mb_xy][i][1]= s->mv[0][i][1]; | 602 s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; |
603 s->field_select_table[mb_xy][i]= s->field_select[0][i]; | 603 s->p_field_select_table[i][mb_xy]= s->field_select[0][i]; |
604 } | 604 } |
605 } | 605 } |
606 | 606 |
607 /* no update if 8X8 because it has been done during parsing */ | 607 /* no update if 8X8 because it has been done during parsing */ |
608 s->current_picture.motion_val[0][xy][0] = motion_x; | 608 s->current_picture.motion_val[0][xy][0] = motion_x; |
742 int i, cbp; | 742 int i, cbp; |
743 | 743 |
744 if(s->pict_type==B_TYPE){ | 744 if(s->pict_type==B_TYPE){ |
745 static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ | 745 static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ |
746 int mb_type= mb_type_table[s->mv_dir]; | 746 int mb_type= mb_type_table[s->mv_dir]; |
747 | 747 |
748 if(s->mb_x==0){ | 748 if(s->mb_x==0){ |
749 s->last_mv[0][0][0]= | 749 for(i=0; i<2; i++){ |
750 s->last_mv[0][0][1]= | 750 s->last_mv[i][0][0]= |
751 s->last_mv[1][0][0]= | 751 s->last_mv[i][0][1]= |
752 s->last_mv[1][0][1]= 0; | 752 s->last_mv[i][1][0]= |
753 s->last_mv[i][1][1]= 0; | |
754 } | |
753 } | 755 } |
754 | 756 |
755 assert(s->dquant>=-2 && s->dquant<=2); | 757 assert(s->dquant>=-2 && s->dquant<=2); |
756 assert((s->dquant&1)==0); | 758 assert((s->dquant&1)==0); |
757 assert(mb_type>=0); | 759 assert(mb_type>=0); |
801 | 803 |
802 if(!s->progressive_sequence){ | 804 if(!s->progressive_sequence){ |
803 if(cbp) | 805 if(cbp) |
804 put_bits(&s->pb, 1, s->interlaced_dct); | 806 put_bits(&s->pb, 1, s->interlaced_dct); |
805 if(mb_type) // not diect mode | 807 if(mb_type) // not diect mode |
806 put_bits(&s->pb, 1, 0); // no interlaced ME yet | 808 put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD); |
807 } | 809 } |
808 | 810 |
809 if(interleaved_stats){ | 811 if(interleaved_stats){ |
810 s->misc_bits+= get_bits_diff(s); | 812 s->misc_bits+= get_bits_diff(s); |
811 } | 813 } |
812 | 814 |
813 switch(mb_type) | 815 if(mb_type == 0){ |
814 { | 816 assert(s->mv_dir & MV_DIRECT); |
815 case 0: /* direct */ | |
816 h263_encode_motion(s, motion_x, 1); | 817 h263_encode_motion(s, motion_x, 1); |
817 h263_encode_motion(s, motion_y, 1); | 818 h263_encode_motion(s, motion_y, 1); |
818 s->b_count++; | 819 s->b_count++; |
819 s->f_count++; | 820 s->f_count++; |
820 break; | 821 }else{ |
821 case 1: /* bidir */ | 822 assert(mb_type > 0 && mb_type < 4); |
822 h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); | 823 if(s->mv_type != MV_TYPE_FIELD){ |
823 h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); | 824 if(s->mv_dir & MV_DIR_FORWARD){ |
824 h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); | 825 h263_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); |
825 h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); | 826 h263_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); |
826 s->last_mv[0][0][0]= s->mv[0][0][0]; | 827 s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; |
827 s->last_mv[0][0][1]= s->mv[0][0][1]; | 828 s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; |
828 s->last_mv[1][0][0]= s->mv[1][0][0]; | 829 s->f_count++; |
829 s->last_mv[1][0][1]= s->mv[1][0][1]; | 830 } |
830 s->b_count++; | 831 if(s->mv_dir & MV_DIR_BACKWARD){ |
831 s->f_count++; | 832 h263_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); |
832 break; | 833 h263_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); |
833 case 2: /* backward */ | 834 s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; |
834 h263_encode_motion(s, motion_x - s->last_mv[1][0][0], s->b_code); | 835 s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; |
835 h263_encode_motion(s, motion_y - s->last_mv[1][0][1], s->b_code); | 836 s->b_count++; |
836 s->last_mv[1][0][0]= motion_x; | 837 } |
837 s->last_mv[1][0][1]= motion_y; | 838 }else{ |
838 s->b_count++; | 839 if(s->mv_dir & MV_DIR_FORWARD){ |
839 break; | 840 put_bits(&s->pb, 1, s->field_select[0][0]); |
840 case 3: /* forward */ | 841 put_bits(&s->pb, 1, s->field_select[0][1]); |
841 h263_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); | 842 } |
842 h263_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); | 843 if(s->mv_dir & MV_DIR_BACKWARD){ |
843 s->last_mv[0][0][0]= motion_x; | 844 put_bits(&s->pb, 1, s->field_select[1][0]); |
844 s->last_mv[0][0][1]= motion_y; | 845 put_bits(&s->pb, 1, s->field_select[1][1]); |
845 s->f_count++; | 846 } |
846 break; | 847 if(s->mv_dir & MV_DIR_FORWARD){ |
847 default: | 848 for(i=0; i<2; i++){ |
848 av_log(s->avctx, AV_LOG_ERROR, "unknown mb type\n"); | 849 h263_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); |
849 return; | 850 h263_encode_motion(s, s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); |
851 s->last_mv[0][i][0]= s->mv[0][i][0]; | |
852 s->last_mv[0][i][1]= s->mv[0][i][1]*2; | |
853 } | |
854 s->f_count++; | |
855 } | |
856 if(s->mv_dir & MV_DIR_BACKWARD){ | |
857 for(i=0; i<2; i++){ | |
858 h263_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); | |
859 h263_encode_motion(s, s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); | |
860 s->last_mv[1][i][0]= s->mv[1][i][0]; | |
861 s->last_mv[1][i][1]= s->mv[1][i][1]*2; | |
862 } | |
863 s->b_count++; | |
864 } | |
865 } | |
850 } | 866 } |
851 | 867 |
852 if(interleaved_stats){ | 868 if(interleaved_stats){ |
853 s->mv_bits+= get_bits_diff(s); | 869 s->mv_bits+= get_bits_diff(s); |
854 } | 870 } |
859 } | 875 } |
860 | 876 |
861 if(interleaved_stats){ | 877 if(interleaved_stats){ |
862 s->p_tex_bits+= get_bits_diff(s); | 878 s->p_tex_bits+= get_bits_diff(s); |
863 } | 879 } |
880 | |
864 }else{ /* s->pict_type==B_TYPE */ | 881 }else{ /* s->pict_type==B_TYPE */ |
865 cbp= get_p_cbp(s, block, motion_x, motion_y); | 882 cbp= get_p_cbp(s, block, motion_x, motion_y); |
866 | 883 |
867 if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { | 884 if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { |
868 /* check if the B frames can skip it too, as we must skip it if we skip here | 885 /* check if the B frames can skip it too, as we must skip it if we skip here |
887 Picture *pic= s->reordered_input_picture[i+1]; | 904 Picture *pic= s->reordered_input_picture[i+1]; |
888 | 905 |
889 if(pic==NULL || pic->pict_type!=B_TYPE) break; | 906 if(pic==NULL || pic->pict_type!=B_TYPE) break; |
890 | 907 |
891 b_pic= pic->data[0] + offset + 16; //FIXME +16 | 908 b_pic= pic->data[0] + offset + 16; //FIXME +16 |
892 diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); | 909 diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); |
893 if(diff>s->qscale*70){ //FIXME check that 70 is optimal | 910 if(diff>s->qscale*70){ //FIXME check that 70 is optimal |
894 s->mb_skiped=0; | 911 s->mb_skiped=0; |
895 break; | 912 break; |
896 } | 913 } |
897 } | 914 } |
927 put_bits(pb2, 2, dquant_code[s->dquant+2]); | 944 put_bits(pb2, 2, dquant_code[s->dquant+2]); |
928 | 945 |
929 if(!s->progressive_sequence){ | 946 if(!s->progressive_sequence){ |
930 if(cbp) | 947 if(cbp) |
931 put_bits(pb2, 1, s->interlaced_dct); | 948 put_bits(pb2, 1, s->interlaced_dct); |
932 put_bits(pb2, 1, 0); // no interlaced ME yet | 949 put_bits(pb2, 1, 0); |
933 } | 950 } |
934 | 951 |
935 if(interleaved_stats){ | 952 if(interleaved_stats){ |
936 s->misc_bits+= get_bits_diff(s); | 953 s->misc_bits+= get_bits_diff(s); |
937 } | 954 } |
939 /* motion vectors: 16x16 mode */ | 956 /* motion vectors: 16x16 mode */ |
940 h263_pred_motion(s, 0, &pred_x, &pred_y); | 957 h263_pred_motion(s, 0, &pred_x, &pred_y); |
941 | 958 |
942 h263_encode_motion(s, motion_x - pred_x, s->f_code); | 959 h263_encode_motion(s, motion_x - pred_x, s->f_code); |
943 h263_encode_motion(s, motion_y - pred_y, s->f_code); | 960 h263_encode_motion(s, motion_y - pred_y, s->f_code); |
961 }else if(s->mv_type==MV_TYPE_FIELD){ | |
962 if(s->dquant) cbpc+= 8; | |
963 put_bits(&s->pb, | |
964 inter_MCBPC_bits[cbpc], | |
965 inter_MCBPC_code[cbpc]); | |
966 | |
967 put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); | |
968 if(s->dquant) | |
969 put_bits(pb2, 2, dquant_code[s->dquant+2]); | |
970 | |
971 assert(!s->progressive_sequence); | |
972 if(cbp) | |
973 put_bits(pb2, 1, s->interlaced_dct); | |
974 put_bits(pb2, 1, 1); | |
975 | |
976 if(interleaved_stats){ | |
977 s->misc_bits+= get_bits_diff(s); | |
978 } | |
979 | |
980 /* motion vectors: 16x8 interlaced mode */ | |
981 h263_pred_motion(s, 0, &pred_x, &pred_y); | |
982 pred_y /=2; | |
983 | |
984 put_bits(&s->pb, 1, s->field_select[0][0]); | |
985 put_bits(&s->pb, 1, s->field_select[0][1]); | |
986 | |
987 h263_encode_motion(s, s->mv[0][0][0] - pred_x, s->f_code); | |
988 h263_encode_motion(s, s->mv[0][0][1] - pred_y, s->f_code); | |
989 h263_encode_motion(s, s->mv[0][1][0] - pred_x, s->f_code); | |
990 h263_encode_motion(s, s->mv[0][1][1] - pred_y, s->f_code); | |
944 }else{ | 991 }else{ |
992 assert(s->mv_type==MV_TYPE_8X8); | |
945 put_bits(&s->pb, | 993 put_bits(&s->pb, |
946 inter_MCBPC_bits[cbpc+16], | 994 inter_MCBPC_bits[cbpc+16], |
947 inter_MCBPC_code[cbpc+16]); | 995 inter_MCBPC_code[cbpc+16]); |
948 put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); | 996 put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); |
949 | 997 |