Mercurial > libavcodec.hg
comparison h264.c @ 5778:c4984d69d373 libavcodec
Support functions and changes to default reference list creation for PAFF.
patch by Jeff Downs, heydowns a borg d com
original thread:
Subject: [FFmpeg-devel] [PATCH] Implement PAFF in H.264
Date: 18/09/07 20:30
author | andoma |
---|---|
date | Fri, 05 Oct 2007 13:41:27 +0000 |
parents | e71de81878c4 |
children | ad3168a70fbe |
comparison
equal
deleted
inserted
replaced
5777:95916a621536 | 5778:c4984d69d373 |
---|---|
2762 if (is_complex) | 2762 if (is_complex) |
2763 hl_decode_mb_complex(h); | 2763 hl_decode_mb_complex(h); |
2764 else hl_decode_mb_simple(h); | 2764 else hl_decode_mb_simple(h); |
2765 } | 2765 } |
2766 | 2766 |
2767 static void pic_as_field(Picture *pic, const int bottom){ | |
2768 int i; | |
2769 for (i = 0; i < 4; ++i) { | |
2770 if (bottom) | |
2771 pic->data[i] += pic->linesize[i]; | |
2772 pic->linesize[i] *= 2; | |
2773 } | |
2774 } | |
2775 | |
2776 static int split_field_copy(Picture *dest, Picture *src, | |
2777 int parity, int id_add){ | |
2778 int match = !!(src->reference & parity); | |
2779 | |
2780 if (match) { | |
2781 *dest = *src; | |
2782 pic_as_field(dest, parity == PICT_BOTTOM_FIELD); | |
2783 dest->pic_id *= 2; | |
2784 dest->pic_id += id_add; | |
2785 } | |
2786 | |
2787 return match; | |
2788 } | |
2789 | |
2790 /** | |
2791 * Split one reference list into field parts, interleaving by parity | |
2792 * as per H.264 spec section 8.2.4.2.5. Output fields have their data pointers | |
2793 * set to look at the actual start of data for that field. | |
2794 * | |
2795 * @param dest output list | |
2796 * @param dest_len maximum number of fields to put in dest | |
2797 * @param src the source reference list containing fields and/or field pairs | |
2798 * (aka short_ref/long_ref, or | |
2799 * refFrameListXShortTerm/refFrameListLongTerm in spec-speak) | |
2800 * @param src_len number of Picture's in source (pairs and unmatched fields) | |
2801 * @param parity the parity of the picture being decoded/needing | |
2802 * these ref pics (PICT_{TOP,BOTTOM}_FIELD) | |
2803 * @return number of fields placed in dest | |
2804 */ | |
2805 static int split_field_half_ref_list(Picture *dest, int dest_len, | |
2806 Picture *src, int src_len, int parity){ | |
2807 int same_parity = 1; | |
2808 int same_i = 0; | |
2809 int opp_i = 0; | |
2810 int out_i; | |
2811 int field_output; | |
2812 | |
2813 for (out_i = 0; out_i < dest_len; out_i += field_output) { | |
2814 if (same_parity && same_i < src_len) { | |
2815 field_output = split_field_copy(dest + out_i, src + same_i, | |
2816 parity, 1); | |
2817 same_parity = !field_output; | |
2818 same_i++; | |
2819 | |
2820 } else if (opp_i < src_len) { | |
2821 field_output = split_field_copy(dest + out_i, src + opp_i, | |
2822 PICT_FRAME - parity, 0); | |
2823 same_parity = field_output; | |
2824 opp_i++; | |
2825 | |
2826 } else { | |
2827 break; | |
2828 } | |
2829 } | |
2830 | |
2831 return out_i; | |
2832 } | |
2833 | |
2834 /** | |
2835 * Split the reference frame list into a reference field list. | |
2836 * This implements H.264 spec 8.2.4.2.5 for a combined input list. | |
2837 * The input list contains both reference field pairs and | |
2838 * unmatched reference fields; it is ordered as spec describes | |
2839 * RefPicListX for frames in 8.2.4.2.1 and 8.2.4.2.3, except that | |
2840 * unmatched field pairs are also present. Conceptually this is equivalent | |
2841 * to concatenation of refFrameListXShortTerm with refFrameListLongTerm. | |
2842 * | |
2843 * @param dest output reference list where ordered fields are to be placed | |
2844 * @param dest_len max number of fields to place at dest | |
2845 * @param src source reference list, as described above | |
2846 * @param src_len number of pictures (pairs and unmatched fields) in src | |
2847 * @param parity parity of field being currently decoded | |
2848 * (one of PICT_{TOP,BOTTOM}_FIELD) | |
2849 * @param long_i index into src array that holds first long reference picture, | |
2850 * or src_len if no long refs present. | |
2851 */ | |
2852 static int split_field_ref_list(Picture *dest, int dest_len, | |
2853 Picture *src, int src_len, | |
2854 int parity, int long_i){ | |
2855 | |
2856 int i = split_field_half_ref_list(dest, dest_len, src, long_i, parity); | |
2857 dest += i; | |
2858 dest_len -= i; | |
2859 | |
2860 i += split_field_half_ref_list(dest, dest_len, src + long_i, | |
2861 src_len - long_i, parity); | |
2862 return i; | |
2863 } | |
2864 | |
2767 /** | 2865 /** |
2768 * fills the default_ref_list. | 2866 * fills the default_ref_list. |
2769 */ | 2867 */ |
2770 static int fill_default_ref_list(H264Context *h){ | 2868 static int fill_default_ref_list(H264Context *h){ |
2771 MpegEncContext * const s = &h->s; | 2869 MpegEncContext * const s = &h->s; |
2772 int i; | 2870 int i; |
2773 int smallest_poc_greater_than_current = -1; | 2871 int smallest_poc_greater_than_current = -1; |
2872 int structure_sel; | |
2774 Picture sorted_short_ref[32]; | 2873 Picture sorted_short_ref[32]; |
2874 Picture field_entry_list[2][32]; | |
2875 Picture *frame_list[2]; | |
2876 | |
2877 if (FIELD_PICTURE) { | |
2878 structure_sel = PICT_FRAME; | |
2879 frame_list[0] = field_entry_list[0]; | |
2880 frame_list[1] = field_entry_list[1]; | |
2881 } else { | |
2882 structure_sel = 0; | |
2883 frame_list[0] = h->default_ref_list[0]; | |
2884 frame_list[1] = h->default_ref_list[1]; | |
2885 } | |
2775 | 2886 |
2776 if(h->slice_type==B_TYPE){ | 2887 if(h->slice_type==B_TYPE){ |
2888 int list; | |
2889 int len[2]; | |
2890 int short_len[2]; | |
2777 int out_i; | 2891 int out_i; |
2778 int limit= INT_MIN; | 2892 int limit= INT_MIN; |
2779 | 2893 |
2780 /* sort frame according to poc in B slice */ | 2894 /* sort frame according to poc in B slice */ |
2781 for(out_i=0; out_i<h->short_ref_count; out_i++){ | 2895 for(out_i=0; out_i<h->short_ref_count; out_i++){ |
2799 if (h->short_ref[best_i]->poc >= s->current_picture_ptr->poc) { | 2913 if (h->short_ref[best_i]->poc >= s->current_picture_ptr->poc) { |
2800 smallest_poc_greater_than_current = out_i; | 2914 smallest_poc_greater_than_current = out_i; |
2801 } | 2915 } |
2802 } | 2916 } |
2803 } | 2917 } |
2804 } | 2918 |
2805 | |
2806 if(s->picture_structure == PICT_FRAME){ | |
2807 if(h->slice_type==B_TYPE){ | |
2808 int list; | |
2809 tprintf(h->s.avctx, "current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current); | 2919 tprintf(h->s.avctx, "current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current); |
2810 | 2920 |
2811 // find the largest poc | 2921 // find the largest poc |
2812 for(list=0; list<2; list++){ | 2922 for(list=0; list<2; list++){ |
2813 int index = 0; | 2923 int index = 0; |
2814 int j= -99; | 2924 int j= -99; |
2815 int step= list ? -1 : 1; | 2925 int step= list ? -1 : 1; |
2816 | 2926 |
2817 for(i=0; i<h->short_ref_count && index < h->ref_count[list]; i++, j+=step) { | 2927 for(i=0; i<h->short_ref_count && index < h->ref_count[list]; i++, j+=step) { |
2928 int sel; | |
2818 while(j<0 || j>= h->short_ref_count){ | 2929 while(j<0 || j>= h->short_ref_count){ |
2819 if(j != -99 && step == (list ? -1 : 1)) | 2930 if(j != -99 && step == (list ? -1 : 1)) |
2820 return -1; | 2931 return -1; |
2821 step = -step; | 2932 step = -step; |
2822 j= smallest_poc_greater_than_current + (step>>1); | 2933 j= smallest_poc_greater_than_current + (step>>1); |
2823 } | 2934 } |
2824 if(sorted_short_ref[j].reference != 3) continue; | 2935 sel = sorted_short_ref[j].reference | structure_sel; |
2825 h->default_ref_list[list][index ]= sorted_short_ref[j]; | 2936 if(sel != PICT_FRAME) continue; |
2826 h->default_ref_list[list][index++].pic_id= sorted_short_ref[j].frame_num; | 2937 frame_list[list][index ]= sorted_short_ref[j]; |
2827 } | 2938 frame_list[list][index++].pic_id= sorted_short_ref[j].frame_num; |
2939 } | |
2940 short_len[list] = index; | |
2828 | 2941 |
2829 for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){ | 2942 for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){ |
2943 int sel; | |
2830 if(h->long_ref[i] == NULL) continue; | 2944 if(h->long_ref[i] == NULL) continue; |
2831 if(h->long_ref[i]->reference != 3) continue; | 2945 sel = h->long_ref[i]->reference | structure_sel; |
2832 | 2946 if(sel != PICT_FRAME) continue; |
2833 h->default_ref_list[ list ][index ]= *h->long_ref[i]; | 2947 |
2834 h->default_ref_list[ list ][index++].pic_id= i;; | 2948 frame_list[ list ][index ]= *h->long_ref[i]; |
2835 } | 2949 frame_list[ list ][index++].pic_id= i;; |
2950 } | |
2951 len[list] = index; | |
2836 | 2952 |
2837 if(list && (smallest_poc_greater_than_current<=0 || smallest_poc_greater_than_current>=h->short_ref_count) && (1 < index)){ | 2953 if(list && (smallest_poc_greater_than_current<=0 || smallest_poc_greater_than_current>=h->short_ref_count) && (1 < index)){ |
2838 // swap the two first elements of L1 when | 2954 // swap the two first elements of L1 when |
2839 // L0 and L1 are identical | 2955 // L0 and L1 are identical |
2840 Picture temp= h->default_ref_list[1][0]; | 2956 Picture temp= frame_list[1][0]; |
2841 h->default_ref_list[1][0] = h->default_ref_list[1][1]; | 2957 frame_list[1][0] = frame_list[1][1]; |
2842 h->default_ref_list[1][1] = temp; | 2958 frame_list[1][1] = temp; |
2843 } | 2959 } |
2844 | 2960 |
2845 if(index < h->ref_count[ list ]) | 2961 } |
2846 memset(&h->default_ref_list[list][index], 0, sizeof(Picture)*(h->ref_count[ list ] - index)); | 2962 |
2847 } | 2963 for(list=0; list<2; list++){ |
2964 if (FIELD_PICTURE) | |
2965 len[list] = split_field_ref_list(h->default_ref_list[list], | |
2966 h->ref_count[list], | |
2967 frame_list[list], | |
2968 len[list], | |
2969 s->picture_structure, | |
2970 short_len[list]); | |
2971 | |
2972 if(len[list] < h->ref_count[ list ]) | |
2973 memset(&h->default_ref_list[list][len[list]], 0, sizeof(Picture)*(h->ref_count[ list ] - len[list])); | |
2974 } | |
2975 | |
2976 | |
2848 }else{ | 2977 }else{ |
2849 int index=0; | 2978 int index=0; |
2979 int short_len; | |
2850 for(i=0; i<h->short_ref_count; i++){ | 2980 for(i=0; i<h->short_ref_count; i++){ |
2851 if(h->short_ref[i]->reference != 3) continue; //FIXME refernce field shit | 2981 int sel; |
2852 h->default_ref_list[0][index ]= *h->short_ref[i]; | 2982 sel = h->short_ref[i]->reference | structure_sel; |
2853 h->default_ref_list[0][index++].pic_id= h->short_ref[i]->frame_num; | 2983 if(sel != PICT_FRAME) continue; |
2854 } | 2984 frame_list[0][index ]= *h->short_ref[i]; |
2985 frame_list[0][index++].pic_id= h->short_ref[i]->frame_num; | |
2986 } | |
2987 short_len = index; | |
2855 for(i = 0; i < 16; i++){ | 2988 for(i = 0; i < 16; i++){ |
2989 int sel; | |
2856 if(h->long_ref[i] == NULL) continue; | 2990 if(h->long_ref[i] == NULL) continue; |
2857 if(h->long_ref[i]->reference != 3) continue; | 2991 sel = h->long_ref[i]->reference | structure_sel; |
2858 h->default_ref_list[0][index ]= *h->long_ref[i]; | 2992 if(sel != PICT_FRAME) continue; |
2859 h->default_ref_list[0][index++].pic_id= i;; | 2993 frame_list[0][index ]= *h->long_ref[i]; |
2860 } | 2994 frame_list[0][index++].pic_id= i;; |
2995 } | |
2996 | |
2997 if (FIELD_PICTURE) | |
2998 index = split_field_ref_list(h->default_ref_list[0], | |
2999 h->ref_count[0], frame_list[0], | |
3000 index, s->picture_structure, | |
3001 short_len); | |
3002 | |
2861 if(index < h->ref_count[0]) | 3003 if(index < h->ref_count[0]) |
2862 memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index)); | 3004 memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index)); |
2863 } | |
2864 }else{ //FIELD | |
2865 if(h->slice_type==B_TYPE){ | |
2866 }else{ | |
2867 //FIXME second field balh | |
2868 } | |
2869 } | 3005 } |
2870 #ifdef TRACE | 3006 #ifdef TRACE |
2871 for (i=0; i<h->ref_count[0]; i++) { | 3007 for (i=0; i<h->ref_count[0]; i++) { |
2872 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]); | 3008 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]); |
2873 } | 3009 } |