comparison h264.c @ 2392:299f2d85d27d libavcodec

add multi slice support for main profile H.264 streams. I have tested this on all H264 conformance streams and comparing the result with the current CVS version, there is 8 streams which decode correctly more frames and 2 streams which are now completely correct with my patch. This patch also correct some typo in comments. patch by (Loic Le Loarer <lll+ffmpeg >at< m4x org>)
author michael
date Sat, 18 Dec 2004 03:49:07 +0000
parents 6ffcdd96ae99
children 81516be6d0e4
comparison
equal deleted inserted replaced
2391:336a239ad9a4 2392:299f2d85d27d
338 #endif 338 #endif
339 } 339 }
340 340
341 /** 341 /**
342 * fill a rectangle. 342 * fill a rectangle.
343 * @param h height of the recatangle, should be a constant 343 * @param h height of the rectangle, should be a constant
344 * @param w width of the recatangle, should be a constant 344 * @param w width of the rectangle, should be a constant
345 * @param size the size of val (1 or 4), should be a constant 345 * @param size the size of val (1 or 4), should be a constant
346 */ 346 */
347 static inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){ //FIXME ensure this IS inlined 347 static inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){ //FIXME ensure this IS inlined
348 uint8_t *p= (uint8_t*)vp; 348 uint8_t *p= (uint8_t*)vp;
349 assert(size==1 || size==4); 349 assert(size==1 || size==4);
758 static inline int check_intra_pred_mode(H264Context *h, int mode){ 758 static inline int check_intra_pred_mode(H264Context *h, int mode){
759 MpegEncContext * const s = &h->s; 759 MpegEncContext * const s = &h->s;
760 static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1}; 760 static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1};
761 static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8}; 761 static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8};
762 762
763 if(mode < 0 || mode > 6) 763 if(mode < 0 || mode > 6) {
764 av_log(h->s.avctx, AV_LOG_ERROR, "out of range intra chroma pred mode at %d %d\n", s->mb_x, s->mb_y);
764 return -1; 765 return -1;
766 }
765 767
766 if(!(h->top_samples_available&0x8000)){ 768 if(!(h->top_samples_available&0x8000)){
767 mode= top[ mode ]; 769 mode= top[ mode ];
768 if(mode<0){ 770 if(mode<0){
769 av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y); 771 av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);
978 980
979 static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my){ 981 static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my){
980 const int top_ref = h->ref_cache[0][ scan8[0] - 8 ]; 982 const int top_ref = h->ref_cache[0][ scan8[0] - 8 ];
981 const int left_ref= h->ref_cache[0][ scan8[0] - 1 ]; 983 const int left_ref= h->ref_cache[0][ scan8[0] - 1 ];
982 984
983 tprintf("pred_pskip: (%d) (%d) at %2d %2d", top_ref, left_ref, h->s.mb_x, h->s.mb_y); 985 tprintf("pred_pskip: (%d) (%d) at %2d %2d\n", top_ref, left_ref, h->s.mb_x, h->s.mb_y);
984 986
985 if(top_ref == PART_NOT_AVAILABLE || left_ref == PART_NOT_AVAILABLE 987 if(top_ref == PART_NOT_AVAILABLE || left_ref == PART_NOT_AVAILABLE
986 || (top_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 8 ] == 0) 988 || (top_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 8 ] == 0)
987 || (left_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 1 ] == 0)){ 989 || (left_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 1 ] == 0)){
988 990
2694 } 2696 }
2695 return 0; 2697 return 0;
2696 } 2698 }
2697 2699
2698 /** 2700 /**
2699 * instantaneos decoder refresh. 2701 * instantaneous decoder refresh.
2700 */ 2702 */
2701 static void idr(H264Context *h){ 2703 static void idr(H264Context *h){
2702 int i; 2704 int i;
2703 2705
2704 for(i=0; i<h->long_ref_count; i++){ 2706 for(i=0; i<h->long_ref_count; i++){
2999 first_mb_in_slice= get_ue_golomb(&s->gb); 3001 first_mb_in_slice= get_ue_golomb(&s->gb);
3000 3002
3001 h->slice_type= get_ue_golomb(&s->gb); 3003 h->slice_type= get_ue_golomb(&s->gb);
3002 if(h->slice_type > 9){ 3004 if(h->slice_type > 9){
3003 av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y); 3005 av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y);
3006 return -1;
3004 } 3007 }
3005 if(h->slice_type > 4){ 3008 if(h->slice_type > 4){
3006 h->slice_type -= 5; 3009 h->slice_type -= 5;
3007 h->slice_type_fixed=1; 3010 h->slice_type_fixed=1;
3008 }else 3011 }else
3033 s->mb_height= h->sps.mb_height; 3036 s->mb_height= h->sps.mb_height;
3034 3037
3035 h->b_stride= s->mb_width*4; 3038 h->b_stride= s->mb_width*4;
3036 h->b8_stride= s->mb_width*2; 3039 h->b8_stride= s->mb_width*2;
3037 3040
3038 s->mb_x = first_mb_in_slice % s->mb_width; 3041 s->resync_mb_x = s->mb_x = first_mb_in_slice % s->mb_width;
3039 s->mb_y = first_mb_in_slice / s->mb_width; //FIXME AFFW 3042 s->resync_mb_y = s->mb_y = first_mb_in_slice / s->mb_width; //FIXME AFFW
3040 3043
3041 s->width = 16*s->mb_width - 2*(h->sps.crop_left + h->sps.crop_right ); 3044 s->width = 16*s->mb_width - 2*(h->sps.crop_left + h->sps.crop_right );
3042 if(h->sps.frame_mbs_only_flag) 3045 if(h->sps.frame_mbs_only_flag)
3043 s->height= 16*s->mb_height - 2*(h->sps.crop_top + h->sps.crop_bottom); 3046 s->height= 16*s->mb_height - 2*(h->sps.crop_top + h->sps.crop_bottom);
3044 else 3047 else
3063 s->avctx->frame_rate = h->sps.time_scale; 3066 s->avctx->frame_rate = h->sps.time_scale;
3064 s->avctx->frame_rate_base = h->sps.num_units_in_tick; 3067 s->avctx->frame_rate_base = h->sps.num_units_in_tick;
3065 } 3068 }
3066 } 3069 }
3067 3070
3068 if(first_mb_in_slice == 0){ 3071 if(h->slice_num == 0){
3069 frame_start(h); 3072 frame_start(h);
3070 } 3073 }
3071 3074
3072 s->current_picture_ptr->frame_num= //FIXME frame_num cleanup 3075 s->current_picture_ptr->frame_num= //FIXME frame_num cleanup
3073 h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); 3076 h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
3134 return -1; 3137 return -1;
3135 } 3138 }
3136 } 3139 }
3137 } 3140 }
3138 3141
3139 if(first_mb_in_slice == 0){ 3142 if(h->slice_num == 0){
3140 fill_default_ref_list(h); 3143 fill_default_ref_list(h);
3141 } 3144 }
3142 3145
3143 decode_ref_pic_list_reordering(h); 3146 decode_ref_pic_list_reordering(h);
3144 3147
3183 #if 0 //FMO 3186 #if 0 //FMO
3184 if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) 3187 if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)
3185 slice_group_change_cycle= get_bits(&s->gb, ?); 3188 slice_group_change_cycle= get_bits(&s->gb, ?);
3186 #endif 3189 #endif
3187 3190
3191 h->slice_num++;
3192
3188 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 3193 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
3189 av_log(h->s.avctx, AV_LOG_DEBUG, "mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d\n", 3194 av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d\n",
3190 first_mb_in_slice, 3195 h->slice_num, first_mb_in_slice,
3191 av_get_pict_type_char(h->slice_type), 3196 av_get_pict_type_char(h->slice_type),
3192 pps_id, h->frame_num, 3197 pps_id, h->frame_num,
3193 s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1], 3198 s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],
3194 h->ref_count[0], h->ref_count[1], 3199 h->ref_count[0], h->ref_count[1],
3195 s->qscale, 3200 s->qscale,
3617 }else if(!IS_DIRECT(mb_type)){ 3622 }else if(!IS_DIRECT(mb_type)){
3618 int list, mx, my, i; 3623 int list, mx, my, i;
3619 //FIXME we should set ref_idx_l? to 0 if we use that later ... 3624 //FIXME we should set ref_idx_l? to 0 if we use that later ...
3620 if(IS_16X16(mb_type)){ 3625 if(IS_16X16(mb_type)){
3621 for(list=0; list<2; list++){ 3626 for(list=0; list<2; list++){
3622 if(h->ref_count[0]>0){ 3627 if(h->ref_count[list]>0){
3623 if(IS_DIR(mb_type, 0, list)){ 3628 if(IS_DIR(mb_type, 0, list)){
3624 const int val= get_te0_golomb(&s->gb, h->ref_count[list]); 3629 const int val= get_te0_golomb(&s->gb, h->ref_count[list]);
3625 fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1); 3630 fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
3626 } 3631 }
3627 } 3632 }
5124 } 5129 }
5125 5130
5126 if( ++s->mb_x >= s->mb_width ) { 5131 if( ++s->mb_x >= s->mb_width ) {
5127 s->mb_x = 0; 5132 s->mb_x = 0;
5128 ff_draw_horiz_band(s, 16*s->mb_y, 16); 5133 ff_draw_horiz_band(s, 16*s->mb_y, 16);
5129 if( ++s->mb_y >= s->mb_height ) { 5134 ++s->mb_y;
5130 tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
5131 }
5132 } 5135 }
5133 5136
5134 if( eos || s->mb_y >= s->mb_height ) { 5137 if( eos || s->mb_y >= s->mb_height ) {
5138 tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
5135 ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); 5139 ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
5136 return 0; 5140 return 0;
5137 } 5141 }
5138 #if 0 5142 #if 0
5139 /* TODO test over-reading in cabac code */ 5143 /* TODO test over-reading in cabac code */
5182 } 5186 }
5183 } 5187 }
5184 } 5188 }
5185 5189
5186 if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){ 5190 if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){
5191 tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
5187 if(get_bits_count(&s->gb) == s->gb.size_in_bits ){ 5192 if(get_bits_count(&s->gb) == s->gb.size_in_bits ){
5188 ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); 5193 ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
5189 5194
5190 return 0; 5195 return 0;
5191 }else{ 5196 }else{
5490 5495
5491 /** 5496 /**
5492 * finds the end of the current frame in the bitstream. 5497 * finds the end of the current frame in the bitstream.
5493 * @return the position of the first byte of the next frame, or -1 5498 * @return the position of the first byte of the next frame, or -1
5494 */ 5499 */
5495 static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ 5500 static int find_frame_end(H264Context *h, const uint8_t *buf, int buf_size){
5496 int i; 5501 int i;
5497 uint32_t state; 5502 uint32_t state;
5503 ParseContext *pc = &(h->s.parse_context);
5498 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); 5504 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
5499 // mb_addr= pc->mb_addr - 1; 5505 // mb_addr= pc->mb_addr - 1;
5500 state= pc->state; 5506 state= pc->state;
5501 //FIXME this will fail with slices 5507 for(i=0; i<=buf_size; i++){
5502 for(i=0; i<buf_size; i++){
5503 state= (state<<8) | buf[i];
5504 if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ 5508 if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
5509 tprintf("find_frame_end new startcode = %08x, frame_start_found = %d, pos = %d\n", state, pc->frame_start_found, i);
5505 if(pc->frame_start_found){ 5510 if(pc->frame_start_found){
5506 pc->state=-1; 5511 // If there isn't one more byte in the buffer
5507 pc->frame_start_found= 0; 5512 // the test on first_mb_in_slice cannot be done yet
5508 return i-3; 5513 // do it at next call.
5509 } 5514 if (i >= buf_size) break;
5510 pc->frame_start_found= 1; 5515 if (buf[i] & 0x80) {
5511 } 5516 // first_mb_in_slice is 0, probably the first nal of a new
5517 // slice
5518 tprintf("find_frame_end frame_end_found, state = %08x, pos = %d\n", state, i);
5519 pc->state=-1;
5520 pc->frame_start_found= 0;
5521 return i-4;
5522 }
5523 }
5524 pc->frame_start_found = 1;
5525 }
5526 if (i<buf_size)
5527 state= (state<<8) | buf[i];
5512 } 5528 }
5513 5529
5514 pc->state= state; 5530 pc->state= state;
5515 return END_NOT_FOUND; 5531 return END_NOT_FOUND;
5516 } 5532 }
5518 static int h264_parse(AVCodecParserContext *s, 5534 static int h264_parse(AVCodecParserContext *s,
5519 AVCodecContext *avctx, 5535 AVCodecContext *avctx,
5520 uint8_t **poutbuf, int *poutbuf_size, 5536 uint8_t **poutbuf, int *poutbuf_size,
5521 const uint8_t *buf, int buf_size) 5537 const uint8_t *buf, int buf_size)
5522 { 5538 {
5523 ParseContext *pc = s->priv_data; 5539 H264Context *h = s->priv_data;
5540 ParseContext *pc = &h->s.parse_context;
5524 int next; 5541 int next;
5525 5542
5526 next= find_frame_end(pc, buf, buf_size); 5543 next= find_frame_end(h, buf, buf_size);
5527 5544
5528 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { 5545 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
5529 *poutbuf = NULL; 5546 *poutbuf = NULL;
5530 *poutbuf_size = 0; 5547 *poutbuf_size = 0;
5531 return buf_size; 5548 return buf_size;
5544 int i; 5561 int i;
5545 for(i=0; i<32; i++){ 5562 for(i=0; i<32; i++){
5546 printf("%X ", buf[i]); 5563 printf("%X ", buf[i]);
5547 } 5564 }
5548 #endif 5565 #endif
5566 h->slice_num = 0;
5549 for(;;){ 5567 for(;;){
5550 int consumed; 5568 int consumed;
5551 int dst_length; 5569 int dst_length;
5552 int bit_length; 5570 int bit_length;
5553 uint8_t *ptr; 5571 uint8_t *ptr;
5702 if (buf_size == 0) { 5720 if (buf_size == 0) {
5703 return 0; 5721 return 0;
5704 } 5722 }
5705 5723
5706 if(s->flags&CODEC_FLAG_TRUNCATED){ 5724 if(s->flags&CODEC_FLAG_TRUNCATED){
5707 int next= find_frame_end(&s->parse_context, buf, buf_size); 5725 int next= find_frame_end(h, buf, buf_size);
5708 5726
5709 if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 ) 5727 if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )
5710 return buf_size; 5728 return buf_size;
5711 //printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index); 5729 //printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index);
5712 } 5730 }
5787 avctx->frame_number = s->picture_number - 1; 5805 avctx->frame_number = s->picture_number - 1;
5788 #endif 5806 #endif
5789 #if 0 5807 #if 0
5790 /* dont output the last pic after seeking */ 5808 /* dont output the last pic after seeking */
5791 if(s->last_picture_ptr || s->low_delay) 5809 if(s->last_picture_ptr || s->low_delay)
5792 //Note this isnt a issue as a IDR pic should flush teh buffers 5810 //Note this isnt a issue as a IDR pic should flush the buffers
5793 #endif 5811 #endif
5794 *data_size = sizeof(AVFrame); 5812 *data_size = sizeof(AVFrame);
5795 return get_consumed_bytes(s, buf_index, buf_size); 5813 return get_consumed_bytes(s, buf_index, buf_size);
5796 } 5814 }
5797 #if 0 5815 #if 0
6014 /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, 6032 /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
6015 }; 6033 };
6016 6034
6017 AVCodecParser h264_parser = { 6035 AVCodecParser h264_parser = {
6018 { CODEC_ID_H264 }, 6036 { CODEC_ID_H264 },
6019 sizeof(ParseContext), 6037 sizeof(H264Context),
6020 NULL, 6038 NULL,
6021 h264_parse, 6039 h264_parse,
6022 ff_parse_close, 6040 ff_parse_close,
6023 }; 6041 };
6024 6042