comparison h264.c @ 7398:bcede7e06618 libavcodec

Rewrite fill_default_ref_list(), the old code was obfuscated beyond repair with hacks. new code is ~60lines old was ~200 Fixes at least: FRExt/HCHP2_HHI_A.264 one sample also get decoded much better: FRExt/FRExt1_Panasonic.avc (PSNR 11 -> 80) (no i do not know why, the old code was too a big mess to figure out what it did)
author michael
date Fri, 25 Jul 2008 21:46:15 +0000
parents 535664ced6f0
children fa2d6f49e3ae
comparison
equal deleted inserted replaced
7397:535664ced6f0 7398:bcede7e06618
2768 int parity, int id_add){ 2768 int parity, int id_add){
2769 int match = !!(src->reference & parity); 2769 int match = !!(src->reference & parity);
2770 2770
2771 if (match) { 2771 if (match) {
2772 *dest = *src; 2772 *dest = *src;
2773 if(parity != PICT_FRAME){
2773 pic_as_field(dest, parity); 2774 pic_as_field(dest, parity);
2774 dest->pic_id *= 2; 2775 dest->pic_id *= 2;
2775 dest->pic_id += id_add; 2776 dest->pic_id += id_add;
2777 }
2776 } 2778 }
2777 2779
2778 return match; 2780 return match;
2779 } 2781 }
2780 2782
2781 /** 2783 static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel){
2782 * Split one reference list into field parts, interleaving by parity 2784 int i[2]={0};
2783 * as per H.264 spec section 8.2.4.2.5. Output fields have their data pointers 2785 int index=0;
2784 * set to look at the actual start of data for that field. 2786
2785 * 2787 while(i[0]<len || i[1]<len){
2786 * @param dest output list 2788 while(i[0]<len && !(in[ i[0] ] && (in[ i[0] ]->reference & sel)))
2787 * @param dest_len maximum number of fields to put in dest 2789 i[0]++;
2788 * @param src the source reference list containing fields and/or field pairs 2790 while(i[1]<len && !(in[ i[1] ] && (in[ i[1] ]->reference & (sel^3))))
2789 * (aka short_ref/long_ref, or 2791 i[1]++;
2790 * refFrameListXShortTerm/refFrameListLongTerm in spec-speak) 2792 if(i[0] < len){
2791 * @param src_len number of Picture's in source (pairs and unmatched fields) 2793 in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num;
2792 * @param parity the parity of the picture being decoded/needing 2794 split_field_copy(&def[index++], in[ i[0]++ ], sel , 1);
2793 * these ref pics (PICT_{TOP,BOTTOM}_FIELD) 2795 }
2794 * @return number of fields placed in dest 2796 if(i[1] < len){
2795 */ 2797 in[ i[1] ]->pic_id= is_long ? i[1] : in[ i[1] ]->frame_num;
2796 static int split_field_half_ref_list(Picture *dest, int dest_len, 2798 split_field_copy(&def[index++], in[ i[1]++ ], sel^3, 0);
2797 Picture *src, int src_len, int parity){ 2799 }
2798 int same_parity = 1; 2800 }
2799 int same_i = 0; 2801
2800 int opp_i = 0; 2802 return index;
2801 int out_i; 2803 }
2802 int field_output; 2804
2803 2805 static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int dir){
2804 for (out_i = 0; out_i < dest_len; out_i += field_output) { 2806 int i, best_poc;
2805 if (same_parity && same_i < src_len) { 2807 int out_i= 0;
2806 field_output = split_field_copy(dest + out_i, src + same_i, 2808
2807 parity, 1); 2809 for(;;){
2808 same_parity = !field_output; 2810 best_poc= dir ? INT_MIN : INT_MAX;
2809 same_i++; 2811
2810 2812 for(i=0; i<len; i++){
2811 } else if (opp_i < src_len) { 2813 const int poc= src[i]->poc;
2812 field_output = split_field_copy(dest + out_i, src + opp_i, 2814 if(((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)){
2813 PICT_FRAME - parity, 0); 2815 best_poc= poc;
2814 same_parity = field_output; 2816 sorted[out_i]= src[i];
2815 opp_i++; 2817 }
2816 2818 }
2817 } else { 2819 if(best_poc == (dir ? INT_MIN : INT_MAX))
2818 break; 2820 break;
2819 } 2821 limit= sorted[out_i++]->poc - dir;
2820 } 2822 }
2821
2822 return out_i; 2823 return out_i;
2823 }
2824
2825 /**
2826 * Split the reference frame list into a reference field list.
2827 * This implements H.264 spec 8.2.4.2.5 for a combined input list.
2828 * The input list contains both reference field pairs and
2829 * unmatched reference fields; it is ordered as spec describes
2830 * RefPicListX for frames in 8.2.4.2.1 and 8.2.4.2.3, except that
2831 * unmatched field pairs are also present. Conceptually this is equivalent
2832 * to concatenation of refFrameListXShortTerm with refFrameListLongTerm.
2833 *
2834 * @param dest output reference list where ordered fields are to be placed
2835 * @param dest_len max number of fields to place at dest
2836 * @param src source reference list, as described above
2837 * @param src_len number of pictures (pairs and unmatched fields) in src
2838 * @param parity parity of field being currently decoded
2839 * (one of PICT_{TOP,BOTTOM}_FIELD)
2840 * @param long_i index into src array that holds first long reference picture,
2841 * or src_len if no long refs present.
2842 */
2843 static int split_field_ref_list(Picture *dest, int dest_len,
2844 Picture *src, int src_len,
2845 int parity, int long_i){
2846
2847 int i = split_field_half_ref_list(dest, dest_len, src, long_i, parity);
2848 dest += i;
2849 dest_len -= i;
2850
2851 i += split_field_half_ref_list(dest, dest_len, src + long_i,
2852 src_len - long_i, parity);
2853 return i;
2854 } 2824 }
2855 2825
2856 /** 2826 /**
2857 * fills the default_ref_list. 2827 * fills the default_ref_list.
2858 */ 2828 */
2859 static int fill_default_ref_list(H264Context *h){ 2829 static int fill_default_ref_list(H264Context *h){
2860 MpegEncContext * const s = &h->s; 2830 MpegEncContext * const s = &h->s;
2861 int i; 2831 int i, len;
2862 int smallest_poc_greater_than_current = -1;
2863 int structure_sel;
2864 Picture sorted_short_ref[32];
2865 Picture field_entry_list[2][32];
2866 Picture *frame_list[2];
2867
2868 if (FIELD_PICTURE) {
2869 structure_sel = PICT_FRAME;
2870 frame_list[0] = field_entry_list[0];
2871 frame_list[1] = field_entry_list[1];
2872 } else {
2873 structure_sel = 0;
2874 frame_list[0] = h->default_ref_list[0];
2875 frame_list[1] = h->default_ref_list[1];
2876 }
2877 2832
2878 if(h->slice_type_nos==FF_B_TYPE){ 2833 if(h->slice_type_nos==FF_B_TYPE){
2879 int list; 2834 Picture *sorted[32];
2880 int len[2]; 2835 int cur_poc, list;
2881 int short_len[2]; 2836 int lens[2];
2882 int out_i; 2837
2883 int limit= INT_MIN; 2838 if(FIELD_PICTURE)
2884 2839 cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
2885 /* sort frame according to POC in B slice */ 2840 else
2886 for(out_i=0; out_i<h->short_ref_count; out_i++){ 2841 cur_poc= s->current_picture_ptr->poc;
2887 int best_i=INT_MIN; 2842
2888 int best_poc=INT_MAX; 2843 for(list= 0; list<2; list++){
2889 2844 len= add_sorted(sorted , h->short_ref, h->short_ref_count, cur_poc, 1^list);
2890 for(i=0; i<h->short_ref_count; i++){ 2845 len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list);
2891 const int poc= h->short_ref[i]->poc; 2846 assert(len<=32);
2892 if(poc > limit && poc < best_poc){ 2847 len= build_def_list(h->default_ref_list[list] , sorted , len, 0, s->picture_structure);
2893 best_poc= poc; 2848 len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure);
2894 best_i= i; 2849 assert(len<=32);
2895 } 2850
2896 } 2851 if(len < h->ref_count[list])
2897 2852 memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len));
2898 assert(best_i != INT_MIN); 2853 lens[list]= len;
2899 2854 }
2900 limit= best_poc; 2855
2901 sorted_short_ref[out_i]= *h->short_ref[best_i]; 2856 if(lens[0] == lens[1] && lens[1] > 1){
2902 tprintf(h->s.avctx, "sorted poc: %d->%d poc:%d fn:%d\n", best_i, out_i, sorted_short_ref[out_i].poc, sorted_short_ref[out_i].frame_num); 2857 for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0] && i<lens[0]; i++);
2903 if (-1 == smallest_poc_greater_than_current) { 2858 if(i == lens[0])
2904 if (h->short_ref[best_i]->poc >= s->current_picture_ptr->poc) { 2859 FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
2905 smallest_poc_greater_than_current = out_i; 2860 }
2906 }
2907 }
2908 }
2909
2910 tprintf(h->s.avctx, "current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current);
2911
2912 // find the largest POC
2913 for(list=0; list<2; list++){
2914 int index = 0;
2915 int j= -99;
2916 int step= list ? -1 : 1;
2917
2918 for(i=0; i<h->short_ref_count && index < h->ref_count[list]; i++, j+=step) {
2919 int sel;
2920 while(j<0 || j>= h->short_ref_count){
2921 if(j != -99 && step == (list ? -1 : 1))
2922 return -1;
2923 step = -step;
2924 j= smallest_poc_greater_than_current + (step>>1);
2925 }
2926 sel = sorted_short_ref[j].reference | structure_sel;
2927 if(sel != PICT_FRAME) continue;
2928 frame_list[list][index ]= sorted_short_ref[j];
2929 frame_list[list][index++].pic_id= sorted_short_ref[j].frame_num;
2930 }
2931 short_len[list] = index;
2932
2933 for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){
2934 int sel;
2935 if(h->long_ref[i] == NULL) continue;
2936 sel = h->long_ref[i]->reference | structure_sel;
2937 if(sel != PICT_FRAME) continue;
2938
2939 frame_list[ list ][index ]= *h->long_ref[i];
2940 frame_list[ list ][index++].pic_id= i;
2941 }
2942 len[list] = index;
2943 }
2944
2945 for(list=0; list<2; list++){
2946 if (FIELD_PICTURE)
2947 len[list] = split_field_ref_list(h->default_ref_list[list],
2948 h->ref_count[list],
2949 frame_list[list],
2950 len[list],
2951 s->picture_structure,
2952 short_len[list]);
2953
2954 // swap the two first elements of L1 when L0 and L1 are identical
2955 if(list && len[0] > 1 && len[0] == len[1])
2956 for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0]; i++)
2957 if(i == len[0]){
2958 FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
2959 break;
2960 }
2961
2962 if(len[list] < h->ref_count[ list ])
2963 memset(&h->default_ref_list[list][len[list]], 0, sizeof(Picture)*(h->ref_count[ list ] - len[list]));
2964 }
2965
2966
2967 }else{ 2861 }else{
2968 int index=0; 2862 len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, s->picture_structure);
2969 int short_len; 2863 len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, s->picture_structure);
2970 for(i=0; i<h->short_ref_count; i++){ 2864 assert(len <= 32);
2971 int sel; 2865 if(len < h->ref_count[0])
2972 sel = h->short_ref[i]->reference | structure_sel; 2866 memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len));
2973 if(sel != PICT_FRAME) continue;
2974 frame_list[0][index ]= *h->short_ref[i];
2975 frame_list[0][index++].pic_id= h->short_ref[i]->frame_num;
2976 }
2977 short_len = index;
2978 for(i = 0; i < 16; i++){
2979 int sel;
2980 if(h->long_ref[i] == NULL) continue;
2981 sel = h->long_ref[i]->reference | structure_sel;
2982 if(sel != PICT_FRAME) continue;
2983 frame_list[0][index ]= *h->long_ref[i];
2984 frame_list[0][index++].pic_id= i;
2985 }
2986
2987 if (FIELD_PICTURE)
2988 index = split_field_ref_list(h->default_ref_list[0],
2989 h->ref_count[0], frame_list[0],
2990 index, s->picture_structure,
2991 short_len);
2992
2993 if(index < h->ref_count[0])
2994 memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index));
2995 } 2867 }
2996 #ifdef TRACE 2868 #ifdef TRACE
2997 for (i=0; i<h->ref_count[0]; i++) { 2869 for (i=0; i<h->ref_count[0]; i++) {
2998 tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].data[0]); 2870 tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].data[0]);
2999 } 2871 }