summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Scheel <julian@jusst.de>2009-01-25 16:45:12 +0000
committerJulian Scheel <julian@jusst.de>2009-01-25 16:45:12 +0000
commitbb85753bac351eadf6e8735403f250f000464611 (patch)
treea0bad94717fab191824dd9153b62b401ab284e09
parent183b9fb01f43bfd4b4877e2509a0cfe58fb7738a (diff)
downloadxine-lib-bb85753bac351eadf6e8735403f250f000464611.tar.gz
xine-lib-bb85753bac351eadf6e8735403f250f000464611.tar.bz2
fFix ref pic marking process on frame_num wraps.
-rw-r--r--src/libvdpau/h264_parser.c35
-rw-r--r--src/libvdpau/nal.h1
-rw-r--r--src/libvdpau/vdpau_h264.c5
3 files changed, 22 insertions, 19 deletions
diff --git a/src/libvdpau/h264_parser.c b/src/libvdpau/h264_parser.c
index 043ca3818..916c40c1a 100644
--- a/src/libvdpau/h264_parser.c
+++ b/src/libvdpau/h264_parser.c
@@ -799,10 +799,13 @@ uint8_t parse_slice_header(struct buf_reader *buf, struct nal_parser *parser)
slc->bottom_field_flag = 0;
}
- if (slc->field_pic_flag == 0)
+ if (slc->field_pic_flag == 0) {
+ nal->max_pic_num = 1 << (sps->log2_max_frame_num_minus4+4);
nal->curr_pic_num = slc->frame_num;
- else
+ } else {
nal->curr_pic_num = 2 * slc->frame_num + 1;
+ nal->max_pic_num = 2 * (1 << (sps->log2_max_frame_num_minus4+4));
+ }
if (nal->nal_unit_type == NAL_SLICE_IDR)
slc->idr_pic_id = read_exp_golomb(buf);
@@ -986,10 +989,10 @@ void decode_ref_pic_marking(struct nal_unit *nal,
if (memory_management_control_operation == 1) {
// short-term -> unused for reference
- uint32_t pic_num_x = nal->curr_pic_num
- - (slc->dec_ref_pic_marking[marking_nr].difference_of_pic_nums_minus1 + 1);
- struct decoded_picture* pic = dpb_get_picture(dpb, pic_num_x);
- if (pic != NULL) {
+ uint32_t pic_num_x = (nal->curr_pic_num
+ - (slc->dec_ref_pic_marking[marking_nr].difference_of_pic_nums_minus1 + 1))%nal->max_pic_num;
+ struct decoded_picture* pic = NULL;
+ if ((pic = dpb_get_picture(dpb, pic_num_x)) != NULL) {
if (pic->nal->slc->field_pic_flag == 0) {
printf("Set %d as unused for ref\n", pic_num_x);
dpb_set_unused_ref_picture_a(dpb, pic);
@@ -1001,9 +1004,9 @@ void decode_ref_pic_marking(struct nal_unit *nal,
//printf("FIXME: We might need do delete more from the DPB...\n");
// FIXME: some more handling needed here?! See 8.2.5.4.1, p. 120
}
- }
- }
- else if (memory_management_control_operation == 2) {
+ } else
+ printf("Can't set %d as unused for ref\n", pic_num_x);
+ } else if (memory_management_control_operation == 2) {
// long-term -> unused for reference
struct decoded_picture* pic = dpb_get_picture_by_ltpn(dpb,
slc->dec_ref_pic_marking[marking_nr].long_term_pic_num);
@@ -1017,8 +1020,7 @@ void decode_ref_pic_marking(struct nal_unit *nal,
printf("FIXME: We might need do delete more from the DPB...\n");
}
}
- }
- else if (memory_management_control_operation == 3) {
+ } else if (memory_management_control_operation == 3) {
// short-term -> long-term, set long-term frame index
uint32_t pic_num_x = nal->curr_pic_num
- (slc->dec_ref_pic_marking[marking_nr].difference_of_pic_nums_minus1 + 1);
@@ -1042,8 +1044,7 @@ void decode_ref_pic_marking(struct nal_unit *nal,
printf("memory_management_control_operation: 3 failed. No such picture.\n");
}
- }
- else if (memory_management_control_operation == 4) {
+ } else if (memory_management_control_operation == 4) {
// set max-long-term frame index,
// mark all long-term pictures with long-term frame idx
// greater max-long-term farme idx as unused for ref
@@ -1052,8 +1053,7 @@ void decode_ref_pic_marking(struct nal_unit *nal,
else
dpb_set_unused_ref_picture_lidx_gt(dpb,
slc->dec_ref_pic_marking[marking_nr].max_long_term_frame_idx_plus1 - 1);
- }
- else if (memory_management_control_operation == 5) {
+ } else if (memory_management_control_operation == 5) {
// mark all ref pics as unused for reference,
// set max-long-term frame index = no long-term frame idxs
dpb_flush(dpb);
@@ -1061,8 +1061,7 @@ void decode_ref_pic_marking(struct nal_unit *nal,
parser->pic_order_cnt_msb = 0;
parser->prev_pic_order_cnt_lsb = 0;
parser->prev_pic_order_cnt_msb = 0;
- }
- else if (memory_management_control_operation == 6) {
+ } else if (memory_management_control_operation == 6) {
// mark current picture as used for long-term ref,
// assing long-term frame idx to it
struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb,
@@ -1079,6 +1078,7 @@ void decode_ref_pic_marking(struct nal_unit *nal,
else
printf("FIXME: BY Set frame to long-term ref\n");
}
+ /* FIXME: Do we need to care about MMC=0? */
}
void parse_dec_ref_pic_marking(struct buf_reader *buf,
@@ -1252,6 +1252,7 @@ int parse_frame(struct nal_parser *parser, uint8_t *inbuf, int inbuf_len,
i,
parser);
}
+
if (parser->last_nal->slc != NULL)
parser->prev_pic_order_cnt_lsb
= parser->last_nal->slc->pic_order_cnt_lsb;
diff --git a/src/libvdpau/nal.h b/src/libvdpau/nal.h
index f892e1a3a..e03a69242 100644
--- a/src/libvdpau/nal.h
+++ b/src/libvdpau/nal.h
@@ -439,6 +439,7 @@ struct nal_unit
uint8_t nal_ref_idc; // 0x03
uint8_t nal_unit_type; // 0x1f
+ uint32_t max_pic_num;
uint32_t curr_pic_num;
uint8_t used_for_long_term_ref;
uint32_t long_term_pic_num;
diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c
index de3cf5d81..906c65f4c 100644
--- a/src/libvdpau/vdpau_h264.c
+++ b/src/libvdpau/vdpau_h264.c
@@ -247,7 +247,7 @@ static void fill_vdpau_pictureinfo_h264(video_decoder_t *this_gen, uint32_t slic
pic->frame_num = slc->frame_num;
pic->field_pic_flag = slc->field_pic_flag;
pic->bottom_field_flag = slc->bottom_field_flag;
- //pic->num_ref_frames = sps->num_ref_frames;
+ pic->num_ref_frames = sps->num_ref_frames;
pic->mb_adaptive_frame_field_flag = sps->mb_adaptive_frame_field_flag;
pic->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
pic->weighted_pred_flag = pps->weighted_pred_flag;
@@ -274,7 +274,8 @@ static void fill_vdpau_pictureinfo_h264(video_decoder_t *this_gen, uint32_t slic
/* set num_ref_frames to the number of actually available reference frames,
* if this is not set generation 3 decoders will fail. */
- pic->num_ref_frames = fill_vdpau_reference_list(&(this->nal_parser->dpb), pic->referenceFrames);
+ /*pic->num_ref_frames =*/
+ fill_vdpau_reference_list(&(this->nal_parser->dpb), pic->referenceFrames);
}