Mercurial > libavcodec.hg
comparison h264.c @ 1177:fea03d2c4946 libavcodec
simplified adressing of most mb based arrays (mb_x + mb_y*s->mb_stride) now instead of mb_x + mb_y*mb_width and 1+mb_x + (1+mb_y)*(mb_width+2) and ... mixture
more direct use of the new mb_type stuff instead of codec specific stuff
runtime mb_type debug output h264/h263 variants/mpeg1/2/4
error concealment /resilience for mpeg1/2
various minor optimizations
author | michaelni |
---|---|
date | Thu, 10 Apr 2003 13:18:38 +0000 |
parents | 2de2a847af67 |
children | 05a2ac8978ad |
comparison
equal
deleted
inserted
replaced
1176:a39d55237445 | 1177:fea03d2c4946 |
---|---|
146 #define NAL_PPS 8 | 146 #define NAL_PPS 8 |
147 #define NAL_PICTURE_DELIMITER 9 | 147 #define NAL_PICTURE_DELIMITER 9 |
148 #define NAL_FILTER_DATA 10 | 148 #define NAL_FILTER_DATA 10 |
149 uint8_t *rbsp_buffer; | 149 uint8_t *rbsp_buffer; |
150 int rbsp_buffer_size; | 150 int rbsp_buffer_size; |
151 | |
152 int mb_stride; ///< stride of some mb tables | |
153 | 151 |
154 int chroma_qp; //QPc | 152 int chroma_qp; //QPc |
155 | 153 |
156 int prev_mb_skiped; //FIXME remove (IMHO not used) | 154 int prev_mb_skiped; //FIXME remove (IMHO not used) |
157 | 155 |
353 assert(0); | 351 assert(0); |
354 } | 352 } |
355 | 353 |
356 static inline void fill_caches(H264Context *h, int mb_type){ | 354 static inline void fill_caches(H264Context *h, int mb_type){ |
357 MpegEncContext * const s = &h->s; | 355 MpegEncContext * const s = &h->s; |
358 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 356 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
359 int topleft_xy, top_xy, topright_xy, left_xy[2]; | 357 int topleft_xy, top_xy, topright_xy, left_xy[2]; |
360 int topleft_type, top_type, topright_type, left_type[2]; | 358 int topleft_type, top_type, topright_type, left_type[2]; |
361 int left_block[4]; | 359 int left_block[4]; |
362 int i; | 360 int i; |
363 | 361 |
364 //wow what a mess, why didnt they simplify the interlacing&intra stuff, i cant imagine that these complex rules are worth it | 362 //wow what a mess, why didnt they simplify the interlacing&intra stuff, i cant imagine that these complex rules are worth it |
365 | 363 |
366 if(h->sps.mb_aff){ | 364 if(h->sps.mb_aff){ |
367 //FIXME | 365 //FIXME |
368 }else{ | 366 }else{ |
369 topleft_xy = mb_xy-1 - h->mb_stride; | 367 topleft_xy = mb_xy-1 - s->mb_stride; |
370 top_xy = mb_xy - h->mb_stride; | 368 top_xy = mb_xy - s->mb_stride; |
371 topright_xy= mb_xy+1 - h->mb_stride; | 369 topright_xy= mb_xy+1 - s->mb_stride; |
372 left_xy[0] = mb_xy-1; | 370 left_xy[0] = mb_xy-1; |
373 left_xy[1] = mb_xy-1; | 371 left_xy[1] = mb_xy-1; |
374 left_block[0]= 0; | 372 left_block[0]= 0; |
375 left_block[1]= 1; | 373 left_block[1]= 1; |
376 left_block[2]= 2; | 374 left_block[2]= 2; |
600 #endif | 598 #endif |
601 } | 599 } |
602 | 600 |
603 static inline void write_back_intra_pred_mode(H264Context *h){ | 601 static inline void write_back_intra_pred_mode(H264Context *h){ |
604 MpegEncContext * const s = &h->s; | 602 MpegEncContext * const s = &h->s; |
605 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 603 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
606 | 604 |
607 h->intra4x4_pred_mode[mb_xy][0]= h->intra4x4_pred_mode_cache[7+8*1]; | 605 h->intra4x4_pred_mode[mb_xy][0]= h->intra4x4_pred_mode_cache[7+8*1]; |
608 h->intra4x4_pred_mode[mb_xy][1]= h->intra4x4_pred_mode_cache[7+8*2]; | 606 h->intra4x4_pred_mode[mb_xy][1]= h->intra4x4_pred_mode_cache[7+8*2]; |
609 h->intra4x4_pred_mode[mb_xy][2]= h->intra4x4_pred_mode_cache[7+8*3]; | 607 h->intra4x4_pred_mode[mb_xy][2]= h->intra4x4_pred_mode_cache[7+8*3]; |
610 h->intra4x4_pred_mode[mb_xy][3]= h->intra4x4_pred_mode_cache[7+8*4]; | 608 h->intra4x4_pred_mode[mb_xy][3]= h->intra4x4_pred_mode_cache[7+8*4]; |
691 else return min; | 689 else return min; |
692 } | 690 } |
693 | 691 |
694 static inline void write_back_non_zero_count(H264Context *h){ | 692 static inline void write_back_non_zero_count(H264Context *h){ |
695 MpegEncContext * const s = &h->s; | 693 MpegEncContext * const s = &h->s; |
696 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 694 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
697 | 695 |
698 h->non_zero_count[mb_xy][0]= h->non_zero_count_cache[4+8*4]; | 696 h->non_zero_count[mb_xy][0]= h->non_zero_count_cache[4+8*4]; |
699 h->non_zero_count[mb_xy][1]= h->non_zero_count_cache[5+8*4]; | 697 h->non_zero_count[mb_xy][1]= h->non_zero_count_cache[5+8*4]; |
700 h->non_zero_count[mb_xy][2]= h->non_zero_count_cache[6+8*4]; | 698 h->non_zero_count[mb_xy][2]= h->non_zero_count_cache[6+8*4]; |
701 h->non_zero_count[mb_xy][3]= h->non_zero_count_cache[7+8*4]; | 699 h->non_zero_count[mb_xy][3]= h->non_zero_count_cache[7+8*4]; |
894 return; | 892 return; |
895 } | 893 } |
896 | 894 |
897 static inline void write_back_motion(H264Context *h, int mb_type){ | 895 static inline void write_back_motion(H264Context *h, int mb_type){ |
898 MpegEncContext * const s = &h->s; | 896 MpegEncContext * const s = &h->s; |
899 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 897 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
900 const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; | 898 const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; |
901 const int b8_xy= 2*s->mb_x + 2*s->mb_y*h->b8_stride; | 899 const int b8_xy= 2*s->mb_x + 2*s->mb_y*h->b8_stride; |
902 int list; | 900 int list; |
903 | 901 |
904 for(list=0; list<2; list++){ | 902 for(list=0; list<2; list++){ |
1950 | 1948 |
1951 static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, | 1949 static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, |
1952 qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put), | 1950 qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put), |
1953 qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg)){ | 1951 qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg)){ |
1954 MpegEncContext * const s = &h->s; | 1952 MpegEncContext * const s = &h->s; |
1955 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 1953 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
1956 const int mb_type= s->current_picture.mb_type[mb_xy]; | 1954 const int mb_type= s->current_picture.mb_type[mb_xy]; |
1957 | 1955 |
1958 assert(IS_INTER(mb_type)); | 1956 assert(IS_INTER(mb_type)); |
1959 | 1957 |
1960 if(IS_16X16(mb_type)){ | 1958 if(IS_16X16(mb_type)){ |
2120 * allocates tables. | 2118 * allocates tables. |
2121 * needs widzh/height | 2119 * needs widzh/height |
2122 */ | 2120 */ |
2123 static int alloc_tables(H264Context *h){ | 2121 static int alloc_tables(H264Context *h){ |
2124 MpegEncContext * const s = &h->s; | 2122 MpegEncContext * const s = &h->s; |
2125 const int big_mb_num= h->mb_stride * (s->mb_height+1); | 2123 const int big_mb_num= s->mb_stride * (s->mb_height+1); |
2126 int x,y; | 2124 int x,y; |
2127 | 2125 |
2128 CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t)) | 2126 CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t)) |
2129 CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) | 2127 CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) |
2130 CHECKED_ALLOCZ(h->slice_table_base , big_mb_num * sizeof(uint8_t)) | 2128 CHECKED_ALLOCZ(h->slice_table_base , big_mb_num * sizeof(uint8_t)) |
2131 | 2129 |
2132 memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t)); | 2130 memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t)); |
2133 h->slice_table= h->slice_table_base + h->mb_stride + 1; | 2131 h->slice_table= h->slice_table_base + s->mb_stride + 1; |
2134 | 2132 |
2135 CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint16_t)); | 2133 CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint16_t)); |
2136 CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint16_t)); | 2134 CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint16_t)); |
2137 for(y=0; y<s->mb_height; y++){ | 2135 for(y=0; y<s->mb_height; y++){ |
2138 for(x=0; x<s->mb_width; x++){ | 2136 for(x=0; x<s->mb_width; x++){ |
2139 const int mb_xy= x + y*h->mb_stride; | 2137 const int mb_xy= x + y*s->mb_stride; |
2140 const int b_xy = 4*x + 4*y*h->b_stride; | 2138 const int b_xy = 4*x + 4*y*h->b_stride; |
2141 const int b8_xy= 2*x + 2*y*h->b8_stride; | 2139 const int b8_xy= 2*x + 2*y*h->b8_stride; |
2142 | 2140 |
2143 h->mb2b_xy [mb_xy]= b_xy; | 2141 h->mb2b_xy [mb_xy]= b_xy; |
2144 h->mb2b8_xy[mb_xy]= b8_xy; | 2142 h->mb2b8_xy[mb_xy]= b8_xy; |
2209 | 2207 |
2210 static void hl_decode_mb(H264Context *h){ | 2208 static void hl_decode_mb(H264Context *h){ |
2211 MpegEncContext * const s = &h->s; | 2209 MpegEncContext * const s = &h->s; |
2212 const int mb_x= s->mb_x; | 2210 const int mb_x= s->mb_x; |
2213 const int mb_y= s->mb_y; | 2211 const int mb_y= s->mb_y; |
2214 const int mb_xy= mb_x + mb_y*h->mb_stride; | 2212 const int mb_xy= mb_x + mb_y*s->mb_stride; |
2215 const int mb_type= s->current_picture.mb_type[mb_xy]; | 2213 const int mb_type= s->current_picture.mb_type[mb_xy]; |
2216 uint8_t *dest_y, *dest_cb, *dest_cr; | 2214 uint8_t *dest_y, *dest_cb, *dest_cr; |
2217 int linesize, uvlinesize /*dct_offset*/; | 2215 int linesize, uvlinesize /*dct_offset*/; |
2218 int i; | 2216 int i; |
2219 | 2217 |
2837 return -1; | 2835 return -1; |
2838 } | 2836 } |
2839 | 2837 |
2840 s->mb_width= h->sps.mb_width; | 2838 s->mb_width= h->sps.mb_width; |
2841 s->mb_height= h->sps.mb_height; | 2839 s->mb_height= h->sps.mb_height; |
2842 h->mb_stride= s->mb_width + 1; | |
2843 | 2840 |
2844 h->b_stride= s->mb_width*4; | 2841 h->b_stride= s->mb_width*4; |
2845 h->b8_stride= s->mb_width*2; | 2842 h->b8_stride= s->mb_width*2; |
2846 | 2843 |
2847 s->mb_x = first_mb_in_slice % s->mb_width; | 2844 s->mb_x = first_mb_in_slice % s->mb_width; |
3169 * decodes a macroblock | 3166 * decodes a macroblock |
3170 * @returns 0 if ok, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed | 3167 * @returns 0 if ok, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed |
3171 */ | 3168 */ |
3172 static int decode_mb(H264Context *h){ | 3169 static int decode_mb(H264Context *h){ |
3173 MpegEncContext * const s = &h->s; | 3170 MpegEncContext * const s = &h->s; |
3174 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 3171 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
3175 int mb_type, partition_count, cbp; | 3172 int mb_type, partition_count, cbp; |
3176 | 3173 |
3177 memset(h->mb, 0, sizeof(int16_t)*24*16); //FIXME avoid if allready clear (move after skip handlong? | 3174 memset(h->mb, 0, sizeof(int16_t)*24*16); //FIXME avoid if allready clear (move after skip handlong? |
3178 | 3175 |
3179 tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); | 3176 tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); |
4162 fprintf(stderr, "error, NO frame\n"); | 4159 fprintf(stderr, "error, NO frame\n"); |
4163 return -1; | 4160 return -1; |
4164 } | 4161 } |
4165 | 4162 |
4166 *pict= *(AVFrame*)&s->current_picture; //FIXME | 4163 *pict= *(AVFrame*)&s->current_picture; //FIXME |
4164 ff_print_debug_info(s, s->current_picture_ptr); | |
4167 assert(pict->data[0]); | 4165 assert(pict->data[0]); |
4168 //printf("out %d\n", (int)pict->data[0]); | 4166 //printf("out %d\n", (int)pict->data[0]); |
4169 #if 0 //? | 4167 #if 0 //? |
4170 | 4168 |
4171 /* Return the Picture timestamp as the frame number */ | 4169 /* Return the Picture timestamp as the frame number */ |
4181 return get_consumed_bytes(s, buf_index, buf_size); | 4179 return get_consumed_bytes(s, buf_index, buf_size); |
4182 } | 4180 } |
4183 #if 0 | 4181 #if 0 |
4184 static inline void fill_mb_avail(H264Context *h){ | 4182 static inline void fill_mb_avail(H264Context *h){ |
4185 MpegEncContext * const s = &h->s; | 4183 MpegEncContext * const s = &h->s; |
4186 const int mb_xy= s->mb_x + s->mb_y*h->mb_stride; | 4184 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; |
4187 | 4185 |
4188 if(s->mb_y){ | 4186 if(s->mb_y){ |
4189 h->mb_avail[0]= s->mb_x && h->slice_table[mb_xy - h->mb_stride - 1] == h->slice_num; | 4187 h->mb_avail[0]= s->mb_x && h->slice_table[mb_xy - s->mb_stride - 1] == h->slice_num; |
4190 h->mb_avail[1]= h->slice_table[mb_xy - h->mb_stride ] == h->slice_num; | 4188 h->mb_avail[1]= h->slice_table[mb_xy - s->mb_stride ] == h->slice_num; |
4191 h->mb_avail[2]= s->mb_x+1 < s->mb_width && h->slice_table[mb_xy - h->mb_stride + 1] == h->slice_num; | 4189 h->mb_avail[2]= s->mb_x+1 < s->mb_width && h->slice_table[mb_xy - s->mb_stride + 1] == h->slice_num; |
4192 }else{ | 4190 }else{ |
4193 h->mb_avail[0]= | 4191 h->mb_avail[0]= |
4194 h->mb_avail[1]= | 4192 h->mb_avail[1]= |
4195 h->mb_avail[2]= 0; | 4193 h->mb_avail[2]= 0; |
4196 } | 4194 } |