Mercurial > libavcodec.hg
comparison h264.c @ 5798:7b058e5183ab libavcodec
Manage Picture buffers for fields as well as frames. Pair complementary fields into one MPV Picture.
Part of PAFF implementation.
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 | Mon, 08 Oct 2007 17:44:38 +0000 |
parents | cd21fd29cf7c |
children | 0be16259b7d8 |
comparison
equal
deleted
inserted
replaced
5797:cd21fd29cf7c | 5798:7b058e5183ab |
---|---|
3337 h->delayed_output_pic->reference= 0; | 3337 h->delayed_output_pic->reference= 0; |
3338 h->delayed_output_pic= NULL; | 3338 h->delayed_output_pic= NULL; |
3339 idr(h); | 3339 idr(h); |
3340 if(h->s.current_picture_ptr) | 3340 if(h->s.current_picture_ptr) |
3341 h->s.current_picture_ptr->reference= 0; | 3341 h->s.current_picture_ptr->reference= 0; |
3342 h->s.first_field= 0; | |
3342 } | 3343 } |
3343 | 3344 |
3344 /** | 3345 /** |
3345 * Find a Picture in the short term reference list by frame number. | 3346 * Find a Picture in the short term reference list by frame number. |
3346 * @param frame_num frame number to search for | 3347 * @param frame_num frame number to search for |
3828 memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset)); | 3829 memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset)); |
3829 dst->s.current_picture_ptr = src->s.current_picture_ptr; | 3830 dst->s.current_picture_ptr = src->s.current_picture_ptr; |
3830 dst->s.current_picture = src->s.current_picture; | 3831 dst->s.current_picture = src->s.current_picture; |
3831 dst->s.linesize = src->s.linesize; | 3832 dst->s.linesize = src->s.linesize; |
3832 dst->s.uvlinesize = src->s.uvlinesize; | 3833 dst->s.uvlinesize = src->s.uvlinesize; |
3834 dst->s.first_field = src->s.first_field; | |
3833 | 3835 |
3834 dst->prev_poc_msb = src->prev_poc_msb; | 3836 dst->prev_poc_msb = src->prev_poc_msb; |
3835 dst->prev_poc_lsb = src->prev_poc_lsb; | 3837 dst->prev_poc_lsb = src->prev_poc_lsb; |
3836 dst->prev_frame_num_offset = src->prev_frame_num_offset; | 3838 dst->prev_frame_num_offset = src->prev_frame_num_offset; |
3837 dst->prev_frame_num = src->prev_frame_num; | 3839 dst->prev_frame_num = src->prev_frame_num; |
3855 * | 3857 * |
3856 * @return 0 if okay, <0 if an error occured, 1 if decoding must not be multithreaded | 3858 * @return 0 if okay, <0 if an error occured, 1 if decoding must not be multithreaded |
3857 */ | 3859 */ |
3858 static int decode_slice_header(H264Context *h, H264Context *h0){ | 3860 static int decode_slice_header(H264Context *h, H264Context *h0){ |
3859 MpegEncContext * const s = &h->s; | 3861 MpegEncContext * const s = &h->s; |
3862 MpegEncContext * const s0 = &h0->s; | |
3860 unsigned int first_mb_in_slice; | 3863 unsigned int first_mb_in_slice; |
3861 unsigned int pps_id; | 3864 unsigned int pps_id; |
3862 int num_ref_idx_active_override_flag; | 3865 int num_ref_idx_active_override_flag; |
3863 static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; | 3866 static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; |
3864 unsigned int slice_type, tmp, i; | 3867 unsigned int slice_type, tmp, i; |
3865 int default_ref_list_done = 0; | 3868 int default_ref_list_done = 0; |
3869 int last_pic_structure; | |
3866 | 3870 |
3867 s->dropable= h->nal_ref_idc == 0; | 3871 s->dropable= h->nal_ref_idc == 0; |
3868 | 3872 |
3869 first_mb_in_slice= get_ue_golomb(&s->gb); | 3873 first_mb_in_slice= get_ue_golomb(&s->gb); |
3870 | 3874 |
3871 if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){ | 3875 if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){ |
3872 h0->current_slice = 0; | 3876 h0->current_slice = 0; |
3877 if (!s0->first_field) | |
3873 s->current_picture_ptr= NULL; | 3878 s->current_picture_ptr= NULL; |
3874 } | 3879 } |
3875 | 3880 |
3876 slice_type= get_ue_golomb(&s->gb); | 3881 slice_type= get_ue_golomb(&s->gb); |
3877 if(slice_type > 9){ | 3882 if(slice_type > 9){ |
3937 if (!s->context_initialized) { | 3942 if (!s->context_initialized) { |
3938 if(h != h0) | 3943 if(h != h0) |
3939 return -1; // we cant (re-)initialize context during parallel decoding | 3944 return -1; // we cant (re-)initialize context during parallel decoding |
3940 if (MPV_common_init(s) < 0) | 3945 if (MPV_common_init(s) < 0) |
3941 return -1; | 3946 return -1; |
3947 s->first_field = 0; | |
3942 | 3948 |
3943 init_scan_tables(h); | 3949 init_scan_tables(h); |
3944 alloc_tables(h); | 3950 alloc_tables(h); |
3945 | 3951 |
3946 for(i = 1; i < s->avctx->thread_count; i++) { | 3952 for(i = 1; i < s->avctx->thread_count; i++) { |
3975 | 3981 |
3976 h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); | 3982 h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); |
3977 | 3983 |
3978 h->mb_mbaff = 0; | 3984 h->mb_mbaff = 0; |
3979 h->mb_aff_frame = 0; | 3985 h->mb_aff_frame = 0; |
3986 last_pic_structure = s0->picture_structure; | |
3980 if(h->sps.frame_mbs_only_flag){ | 3987 if(h->sps.frame_mbs_only_flag){ |
3981 s->picture_structure= PICT_FRAME; | 3988 s->picture_structure= PICT_FRAME; |
3982 }else{ | 3989 }else{ |
3983 if(get_bits1(&s->gb)) { //field_pic_flag | 3990 if(get_bits1(&s->gb)) { //field_pic_flag |
3984 s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag | 3991 s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag |
3988 h->mb_aff_frame = h->sps.mb_aff; | 3995 h->mb_aff_frame = h->sps.mb_aff; |
3989 } | 3996 } |
3990 } | 3997 } |
3991 | 3998 |
3992 if(h0->current_slice == 0){ | 3999 if(h0->current_slice == 0){ |
3993 if(frame_start(h) < 0) | 4000 /* See if we have a decoded first field looking for a pair... */ |
4001 if (s0->first_field) { | |
4002 assert(s0->current_picture_ptr); | |
4003 assert(s0->current_picture_ptr->data[0]); | |
4004 assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF); | |
4005 | |
4006 /* figure out if we have a complementary field pair */ | |
4007 if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) { | |
4008 /* | |
4009 * Previous field is unmatched. Don't display it, but let it | |
4010 * remain for reference if marked as such. | |
4011 */ | |
4012 s0->current_picture_ptr = NULL; | |
4013 s0->first_field = FIELD_PICTURE; | |
4014 | |
4015 } else { | |
4016 if (h->nal_ref_idc && | |
4017 s0->current_picture_ptr->reference && | |
4018 s0->current_picture_ptr->frame_num != h->frame_num) { | |
4019 /* | |
4020 * This and previous field were reference, but had | |
4021 * different frame_nums. Consider this field first in | |
4022 * pair. Throw away previous field except for reference | |
4023 * purposes. | |
4024 */ | |
4025 s0->first_field = 1; | |
4026 s0->current_picture_ptr = NULL; | |
4027 | |
4028 } else { | |
4029 /* Second field in complementary pair */ | |
4030 s0->first_field = 0; | |
4031 } | |
4032 } | |
4033 | |
4034 } else { | |
4035 /* Frame or first field in a potentially complementary pair */ | |
4036 assert(!s0->current_picture_ptr); | |
4037 s0->first_field = FIELD_PICTURE; | |
4038 } | |
4039 | |
4040 if((!FIELD_PICTURE || s0->first_field) && frame_start(h) < 0) { | |
4041 s0->first_field = 0; | |
3994 return -1; | 4042 return -1; |
4043 } | |
3995 } | 4044 } |
3996 if(h != h0) | 4045 if(h != h0) |
3997 clone_slice(h, h0); | 4046 clone_slice(h, h0); |
3998 | 4047 |
3999 s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup | 4048 s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup |
7361 | 7410 |
7362 /* pull back stuff from slices to master context */ | 7411 /* pull back stuff from slices to master context */ |
7363 hx = h->thread_context[context_count - 1]; | 7412 hx = h->thread_context[context_count - 1]; |
7364 s->mb_x = hx->s.mb_x; | 7413 s->mb_x = hx->s.mb_x; |
7365 s->mb_y = hx->s.mb_y; | 7414 s->mb_y = hx->s.mb_y; |
7415 s->dropable = hx->s.dropable; | |
7416 s->picture_structure = hx->s.picture_structure; | |
7366 for(i = 1; i < context_count; i++) | 7417 for(i = 1; i < context_count; i++) |
7367 h->s.error_count += h->thread_context[i]->s.error_count; | 7418 h->s.error_count += h->thread_context[i]->s.error_count; |
7368 } | 7419 } |
7369 } | 7420 } |
7370 | 7421 |
7383 av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]); | 7434 av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]); |
7384 } | 7435 } |
7385 #endif | 7436 #endif |
7386 if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ | 7437 if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ |
7387 h->current_slice = 0; | 7438 h->current_slice = 0; |
7439 if (!s->first_field) | |
7388 s->current_picture_ptr= NULL; | 7440 s->current_picture_ptr= NULL; |
7389 } | 7441 } |
7390 | 7442 |
7391 for(;;){ | 7443 for(;;){ |
7392 int consumed; | 7444 int consumed; |
7680 s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264; | 7732 s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264; |
7681 s->current_picture_ptr->pict_type= s->pict_type; | 7733 s->current_picture_ptr->pict_type= s->pict_type; |
7682 | 7734 |
7683 h->prev_frame_num_offset= h->frame_num_offset; | 7735 h->prev_frame_num_offset= h->frame_num_offset; |
7684 h->prev_frame_num= h->frame_num; | 7736 h->prev_frame_num= h->frame_num; |
7685 if(s->current_picture_ptr->reference & s->picture_structure){ | 7737 if(!s->dropable) { |
7686 h->prev_poc_msb= h->poc_msb; | 7738 h->prev_poc_msb= h->poc_msb; |
7687 h->prev_poc_lsb= h->poc_lsb; | 7739 h->prev_poc_lsb= h->poc_lsb; |
7688 execute_ref_pic_marking(h, h->mmco, h->mmco_index); | 7740 execute_ref_pic_marking(h, h->mmco, h->mmco_index); |
7689 } | 7741 } |
7690 | 7742 |
7743 /* | |
7744 * FIXME: Error handling code does not seem to support interlaced | |
7745 * when slices span multiple rows | |
7746 * The ff_er_add_slice calls don't work right for bottom | |
7747 * fields; they cause massive erroneous error concealing | |
7748 * Error marking covers both fields (top and bottom). | |
7749 * This causes a mismatched s->error_count | |
7750 * and a bad error table. Further, the error count goes to | |
7751 * INT_MAX when called for bottom field, because mb_y is | |
7752 * past end by one (callers fault) and resync_mb_y != 0 | |
7753 * causes problems for the first MB line, too. | |
7754 */ | |
7755 if (!FIELD_PICTURE) | |
7691 ff_er_frame_end(s); | 7756 ff_er_frame_end(s); |
7692 | 7757 |
7693 MPV_frame_end(s); | 7758 MPV_frame_end(s); |
7694 | 7759 |
7760 if (s->first_field) { | |
7761 /* Wait for second field. */ | |
7762 *data_size = 0; | |
7763 | |
7764 } else { | |
7695 //FIXME do something with unavailable reference frames | 7765 //FIXME do something with unavailable reference frames |
7696 | 7766 |
7697 #if 0 //decode order | 7767 #if 0 //decode order |
7698 *data_size = sizeof(AVFrame); | 7768 *data_size = sizeof(AVFrame); |
7699 #else | 7769 #else |
7760 | 7830 |
7761 if(out) | 7831 if(out) |
7762 *pict= *(AVFrame*)out; | 7832 *pict= *(AVFrame*)out; |
7763 else | 7833 else |
7764 av_log(avctx, AV_LOG_DEBUG, "no picture\n"); | 7834 av_log(avctx, AV_LOG_DEBUG, "no picture\n"); |
7835 } | |
7765 } | 7836 } |
7766 | 7837 |
7767 assert(pict->data[0] || !*data_size); | 7838 assert(pict->data[0] || !*data_size); |
7768 ff_print_debug_info(s, pict); | 7839 ff_print_debug_info(s, pict); |
7769 //printf("out %d\n", (int)pict->data[0]); | 7840 //printf("out %d\n", (int)pict->data[0]); |