diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libvdpau/dpb.c | 22 | ||||
-rw-r--r-- | src/libvdpau/h264_parser.c | 59 | ||||
-rw-r--r-- | src/libvdpau/h264_parser.h | 3 | ||||
-rw-r--r-- | src/libvdpau/vdpau_h264.c | 10 |
4 files changed, 51 insertions, 43 deletions
diff --git a/src/libvdpau/dpb.c b/src/libvdpau/dpb.c index da10bde0e..25d9041f2 100644 --- a/src/libvdpau/dpb.c +++ b/src/libvdpau/dpb.c @@ -195,9 +195,8 @@ int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_r free_decoded_picture(pic); pic = last_pic; dpb->used--; - } else - last_pic = pic; - last_pic = pic; + } + last_pic = pic; } while ((pic = pic->next) != NULL); } @@ -207,18 +206,17 @@ int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_r int dpb_flush(struct dpb *dpb) { struct decoded_picture *pic = dpb->pictures; - struct decoded_picture *last_pic = NULL; if (pic != NULL) do { - //FIXME: free the picture - free_decoded_picture(last_pic); - last_pic = pic; - } while ((pic = pic->next) != NULL); + dpb->pictures = pic->next; + free_decoded_picture(pic); + pic = dpb->pictures; + dpb->used--; + } while (dpb->pictures != NULL); - free_decoded_picture(last_pic); dpb->pictures = NULL; - dpb->used = NULL; + dpb->used = 0; return 0; } @@ -236,9 +234,9 @@ void fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist) reflist[i].surface = pic->surface; reflist[i].is_long_term = pic->nal->used_for_long_term_ref; if(reflist[i].is_long_term) - reflist[i].frame_idx = pic->nal->long_term_frame_idx; + reflist[i].frame_idx = pic->nal->slc->frame_num; //pic->nal->long_term_frame_idx; else - reflist[i].frame_idx = pic->nal->curr_pic_num; + reflist[i].frame_idx = pic->nal->slc->frame_num; //pic->nal->curr_pic_num; reflist[i].top_is_reference = pic->nal->slc->field_pic_flag ? (pic->nal->slc->bottom_field_flag ? 0 : 1) : 1; reflist[i].bottom_is_reference = pic->nal->slc->field_pic_flag diff --git a/src/libvdpau/h264_parser.c b/src/libvdpau/h264_parser.c index 18456d47a..c41cb5cf6 100644 --- a/src/libvdpau/h264_parser.c +++ b/src/libvdpau/h264_parser.c @@ -226,41 +226,41 @@ void calculate_pic_order(struct nal_parser *parser) if (sps->pic_order_cnt_type == 0) { if (nal->nal_unit_type == NAL_SLICE_IDR) { + printf("IDR SLICE\n"); parser->prev_pic_order_cnt_lsb = 0; parser->prev_pic_order_cnt_msb = 0; } - else { - const int max_poc_lsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); - - if (slc->pic_order_cnt_lsb < parser->prev_pic_order_cnt_lsb - && parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb - >= max_poc_lsb / 2) - parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb - + max_poc_lsb; - else if (slc->pic_order_cnt_lsb > parser->prev_pic_order_cnt_lsb - && parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb - < -max_poc_lsb / 2) - parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb - - max_poc_lsb; - else - parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb; - if (!slc->bottom_field_flag) { - nal->top_field_order_cnt = parser->pic_order_cnt_msb - + slc->pic_order_cnt_lsb; + const int max_poc_lsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); + + if (slc->pic_order_cnt_lsb < parser->prev_pic_order_cnt_lsb + && parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb + >= max_poc_lsb / 2) + parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb + + max_poc_lsb; + else if (slc->pic_order_cnt_lsb > parser->prev_pic_order_cnt_lsb + && parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb + < -max_poc_lsb / 2) + parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb + - max_poc_lsb; + else + parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb; - if (!slc->field_pic_flag) - nal->bottom_field_order_cnt = nal->top_field_order_cnt; - else - nal->bottom_field_order_cnt = 0; - } - else - nal->bottom_field_order_cnt = parser->pic_order_cnt_msb - + slc->pic_order_cnt_lsb; + if (!slc->bottom_field_flag) { + nal->top_field_order_cnt = parser->pic_order_cnt_msb + + slc->pic_order_cnt_lsb; - if (parser->field == -1) - nal->bottom_field_order_cnt += slc->delta_pic_order_cnt_bottom; + if (!slc->field_pic_flag) + nal->bottom_field_order_cnt = nal->top_field_order_cnt; + else + nal->bottom_field_order_cnt = 0; } + else + nal->bottom_field_order_cnt = parser->pic_order_cnt_msb + + slc->pic_order_cnt_lsb; + + if (parser->field == -1) + nal->bottom_field_order_cnt += slc->delta_pic_order_cnt_bottom; } } @@ -1035,8 +1035,9 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) struct nal_unit *last_nal = parser->last_nal; int res = parse_nal_header(&bufr, parser); - if (res == NAL_SLICE_IDR) + if (res == NAL_SLICE_IDR) { parser->is_idr = 1; + } if (res >= NAL_SLICE && res <= NAL_SLICE_IDR) { // now detect if it's a new frame! diff --git a/src/libvdpau/h264_parser.h b/src/libvdpau/h264_parser.h index e067f9741..bfd6d3b35 100644 --- a/src/libvdpau/h264_parser.h +++ b/src/libvdpau/h264_parser.h @@ -16,7 +16,8 @@ struct nal_parser { int found_pps; int last_nal_res; - int is_idr; + uint8_t is_idr; + int field; /* 0=top, 1=bottom, -1=both */ int slice; int slice_cnt; diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c index 112496168..f80396ff5 100644 --- a/src/libvdpau/vdpau_h264.c +++ b/src/libvdpau/vdpau_h264.c @@ -260,6 +260,15 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, struct seq_parameter_set_rbsp *sps = this->nal_parser->current_nal->sps; struct slice_header *slc = this->nal_parser->current_nal->slc; + /* flush the DPB if this frame was an IDR */ + //printf("is_idr: %d\n", this->nal_parser->is_idr); + if(this->nal_parser->current_nal->nal_unit_type == NAL_SLICE_IDR) { + printf("IDR Slice, flush\n"); + dpb_flush(&(this->nal_parser->dpb)); + printf("Emtpy: %s", this->nal_parser->dpb.pictures == NULL ? "Yes" : "No"); + } + this->nal_parser->is_idr = 0; + /* go and decode a frame */ VdpPictureInfoH264 pic; @@ -299,7 +308,6 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, //memcpy(pic.referenceFrames, this->reference_frames, sizeof(pic.referenceFrames)); if(this->decoder_started || pic.is_reference) { - this->nal_parser->is_idr = 0; if(!this->decoder_started) this->decoder_started = 1; |