Mercurial > libavcodec.hg
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 |