summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libvdpau/dpb.c158
-rw-r--r--src/libvdpau/dpb.h16
-rw-r--r--src/libvdpau/h264_parser.c85
-rw-r--r--src/libvdpau/h264_parser.h2
-rw-r--r--src/libvdpau/nal.h59
-rw-r--r--src/libvdpau/vdpau_h264.c36
6 files changed, 258 insertions, 98 deletions
diff --git a/src/libvdpau/dpb.c b/src/libvdpau/dpb.c
index d27611e64..0f5970ced 100644
--- a/src/libvdpau/dpb.c
+++ b/src/libvdpau/dpb.c
@@ -18,6 +18,8 @@ struct decoded_picture* init_decoded_picture(struct nal_unit *src_nal,
struct decoded_picture *pic = malloc(sizeof(struct decoded_picture));
pic->nal = init_nal_unit();
copy_nal_unit(pic->nal, src_nal);
+ pic->used_for_reference = 0;
+ pic->delayed_output = 0;
pic->top_is_reference = pic->nal->slc->field_pic_flag
? (pic->nal->slc->bottom_field_flag ? 0 : 1) : 1;
pic->bottom_is_reference = pic->nal->slc->field_pic_flag
@@ -35,6 +37,27 @@ void free_decoded_picture(struct decoded_picture *pic)
free_nal_unit(pic->nal);
}
+struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb)
+{
+ struct decoded_picture *pic = dpb->pictures;
+ struct decoded_picture *outpic = pic;
+
+ printf("dpb used: %d\n", dpb->used);
+
+ if(dpb->used < MAX_DPB_SIZE)
+ return NULL;
+
+ if (pic != NULL)
+ do {
+ if (pic->img->pts < outpic->img->pts)
+ outpic = pic;
+ } while ((pic = pic->next) != NULL);
+
+ if(outpic)
+ printf("OUTPUT: %lld\n", outpic->img->pts);
+ return outpic;
+}
+
struct decoded_picture* dpb_get_picture(struct dpb *dpb, uint32_t picnum)
{
struct decoded_picture *pic = dpb->pictures;
@@ -76,75 +99,114 @@ struct decoded_picture* dpb_get_picture_by_ltidx(struct dpb *dpb,
return NULL;
}
-int dpb_remove_picture(struct dpb *dpb, uint32_t picnum)
+int dpb_set_unused_ref_picture(struct dpb *dpb, uint32_t picnum)
{
struct decoded_picture *pic = dpb->pictures;
- struct decoded_picture *last_pic = NULL;
-
+printf("UNUSED 1\n");
if (pic != NULL)
do {
if (pic->nal->curr_pic_num == picnum) {
- // FIXME: free the picture....
+ pic->used_for_reference = 0;
+ if(!pic->delayed_output)
+ dpb_remove_picture(dpb, pic);
+ return 0;
+ }
+ } while ((pic = pic->next) != NULL);
- if (last_pic != NULL)
- last_pic->next = pic->next;
- else
- dpb->pictures = pic->next;
+ return -1;
+}
- free_decoded_picture(pic);
- dpb->used--;
+int dpb_set_unused_ref_picture_byltpn(struct dpb *dpb, uint32_t longterm_picnum)
+{
+ struct decoded_picture *pic = dpb->pictures;
+ printf("UNUSED 2\n");
+ if (pic != NULL)
+ do {
+ if (pic->nal->long_term_pic_num == longterm_picnum) {
+ pic->used_for_reference = 0;
+ if(!pic->delayed_output)
+ dpb_remove_picture(dpb, pic);
return 0;
}
-
- last_pic = pic;
} while ((pic = pic->next) != NULL);
return -1;
}
-int dpb_remove_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum)
+int dpb_set_unused_ref_picture_bylidx(struct dpb *dpb, uint32_t longterm_idx)
{
struct decoded_picture *pic = dpb->pictures;
- struct decoded_picture *last_pic = NULL;
+ printf("UNUSED 3\n");
+ if (pic != NULL)
+ do {
+ if (pic->nal->long_term_frame_idx == longterm_idx) {
+ pic->used_for_reference = 0;
+ if(!pic->delayed_output)
+ dpb_remove_picture(dpb, pic);
+ return 0;
+ }
+ } while ((pic = pic->next) != NULL);
+
+ return -1;
+}
+int dpb_set_unused_ref_picture_lidx_gt(struct dpb *dpb, uint32_t longterm_idx)
+{
+ struct decoded_picture *pic = dpb->pictures;
+ printf("UNUSED 4\n");
if (pic != NULL)
do {
- if (pic->nal->long_term_pic_num == longterm_picnum) {
- // FIXME: free the picture....
+ if (pic->nal->long_term_frame_idx >= longterm_idx) {
+ pic->used_for_reference = 0;
+ if(!pic->delayed_output) {
+ struct decoded_picture *next_pic = pic->next;
+ dpb_remove_picture(dpb, pic);
+ pic = next_pic;
+ continue;
+ }
+ }
+ } while ((pic = pic->next) != NULL);
- if (last_pic != NULL)
- last_pic->next = pic->next;
- else
- dpb->pictures = pic->next;
+ return -1;
+}
- free_decoded_picture(pic);
- dpb->used--;
+
+int dpb_set_output_picture(struct dpb *dpb, struct decoded_picture *outpic)
+{
+ struct decoded_picture *pic = dpb->pictures;
+printf("DPB set output pic\n");
+ if (pic != NULL)
+ do {
+ if (pic == outpic) {
+ printf("DPB pic num %d output, refuse: %d\n", pic->nal->curr_pic_num, pic->used_for_reference);
+ pic->delayed_output = 0;
+ if(!pic->used_for_reference)
+ dpb_remove_picture(dpb, pic);
return 0;
}
-
- last_pic = pic;
} while ((pic = pic->next) != NULL);
return -1;
}
-int dpb_remove_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx)
+int dpb_remove_picture(struct dpb *dpb, struct decoded_picture *rempic)
{
struct decoded_picture *pic = dpb->pictures;
struct decoded_picture *last_pic = NULL;
-
+printf("DPB remove pic\n");
if (pic != NULL)
do {
- if (pic->nal->long_term_frame_idx == longterm_idx) {
+ if (pic == rempic) {
+ printf("DPB found rempic\n");
// FIXME: free the picture....
if (last_pic != NULL)
last_pic->next = pic->next;
else
dpb->pictures = pic->next;
-
free_decoded_picture(pic);
dpb->used--;
+ printf("DPB Used: %d\n", dpb->used);
return 0;
}
@@ -154,32 +216,21 @@ int dpb_remove_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx)
return -1;
}
-int dpb_remove_ltidx_gt(struct dpb *dpb, uint32_t longterm_max)
+int dpb_remove_picture_by_picnum(struct dpb *dpb, uint32_t picnum)
{
struct decoded_picture *pic = dpb->pictures;
struct decoded_picture *last_pic = NULL;
if (pic != NULL)
do {
- if (pic->nal->long_term_frame_idx > longterm_max) {
- // FIXME: free the picture....
- if (last_pic != NULL)
- last_pic->next = pic->next;
- else
- dpb->pictures = pic->next;
-
-
- free_decoded_picture(pic);
- dpb->used--;
- /* don't increase last_pic to current pic
- * in case we delete current pic */
- continue;
+ if (pic->nal->curr_pic_num == picnum) {
+ dpb_remove_picture(dpb, pic);
}
last_pic = pic;
} while ((pic = pic->next) != NULL);
- return 0;
+ return -1;
}
int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_ref_frames)
@@ -190,17 +241,20 @@ int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_r
pic->next = dpb->pictures;
dpb->pictures = pic;
dpb->used++;
-
+printf("ADD: Used: %d\n", dpb->used);
if(dpb->used > num_ref_frames) {
do {
- i++;
- if(i>num_ref_frames) {
- last_pic->next = pic->next;
- free_decoded_picture(pic);
- pic = last_pic;
- dpb->used--;
+ if(pic->used_for_reference) {
+ i++;
+ if(i>num_ref_frames) {
+ printf("DPB REMOVE REF FRAME\n");
+ pic->used_for_reference = 0;
+ if(!pic->delayed_output)
+ dpb_remove_picture(dpb, pic);
+ pic = last_pic;
+ }
+ last_pic = pic;
}
- last_pic = pic;
} while ((pic = pic->next) != NULL);
}
@@ -234,7 +288,7 @@ void fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist)
if (pic != NULL)
do {
- if (pic->nal->nal_ref_idc != 0) {
+ if (pic->used_for_reference) {
reflist[i].surface = pic->surface;
reflist[i].is_long_term = pic->nal->used_for_long_term_ref;
if(reflist[i].is_long_term)
diff --git a/src/libvdpau/dpb.h b/src/libvdpau/dpb.h
index 06f894e44..c747a38af 100644
--- a/src/libvdpau/dpb.h
+++ b/src/libvdpau/dpb.h
@@ -8,6 +8,8 @@
#ifndef DPB_H_
#define DPB_H_
+#define MAX_DPB_SIZE 10
+
#include "nal.h"
#include "video_out.h"
@@ -21,6 +23,8 @@ struct decoded_picture {
uint8_t top_is_reference;
uint8_t bottom_is_reference;
+ uint8_t delayed_output;
+
struct decoded_picture *next;
};
@@ -34,10 +38,20 @@ struct decoded_picture* init_decoded_picture(struct nal_unit *src_nal,
VdpVideoSurface surface, vo_frame_t *img);
void free_decoded_picture(struct decoded_picture *pic);
+struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb);
+
struct decoded_picture* dpb_get_picture(struct dpb *dpb, uint32_t picnum);
struct decoded_picture* dpb_get_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum);
struct decoded_picture* dpb_get_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx);
-int dpb_remove_picture(struct dpb *dpb, uint32_t picnum);
+
+int dpb_set_unused_ref_picture(struct dpb *dpb, uint32_t picnum);
+int dpb_set_unused_ref_picture_byltpn(struct dpb *dpb, uint32_t longterm_picnum);
+int dpb_set_unused_ref_picture_bylidx(struct dpb *dpb, uint32_t longterm_idx);
+
+int dpb_set_output_picture(struct dpb *dpb, struct decoded_picture *outpic);
+
+int dpb_remove_picture(struct dpb *dpb, struct decoded_picture *rempic);
+int dpb_remove_picture_by_picnum(struct dpb *dpb, uint32_t picnum);
int dpb_remove_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum);
int dpb_remove_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx);
int dpb_remove_ltidx_gt(struct dpb *dpb, uint32_t longterm_max);
diff --git a/src/libvdpau/h264_parser.c b/src/libvdpau/h264_parser.c
index 6d376ae44..e5206a943 100644
--- a/src/libvdpau/h264_parser.c
+++ b/src/libvdpau/h264_parser.c
@@ -39,12 +39,13 @@ void skip_scaling_list(struct buf_reader *buf, int size);
void parse_scaling_list(struct buf_reader *buf, uint8_t *scaling_list,
int length, int index);
int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser);
-uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps);
+uint8_t parse_sps(struct buf_reader *buf, struct nal_parser *parser);
void parse_vui_parameters(struct buf_reader *buf,
struct seq_parameter_set_rbsp *sps);
void parse_hrd_parameters(struct buf_reader *buf, struct hrd_parameters *hrd);
uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps,
struct seq_parameter_set_rbsp *sps);
+void parse_sei(struct buf_reader *buf, struct nal_parser *parser);
uint8_t parse_slice_header(struct buf_reader *buf, struct nal_parser *parser);
void
parse_ref_pic_list_reordering(struct buf_reader *buf, struct nal_unit *nal);
@@ -165,7 +166,6 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser)
nal->nal_ref_idc = (buf->buf[0] >> 5) & 0x03;
nal->nal_unit_type = buf->buf[0] & 0x1f;
- //printf("Unit: %d\n", nal->nal_unit_type);
buf->cur_pos = buf->buf + 1;
//printf("NAL: %d\n", nal->nal_unit_type);
@@ -183,7 +183,7 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser)
memset(nal->sps, 0x00, sizeof(struct seq_parameter_set_rbsp));
- parse_sps(&ibuf, nal->sps);
+ parse_sps(&ibuf, parser);
free(ibuf.buf);
ret = NAL_SPS;
break;
@@ -210,6 +210,10 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser)
ret = nal->nal_unit_type;
}
break;
+ case NAL_SEI:
+ parse_sei(buf, parser);
+ ret = nal->nal_unit_type;
+ break;
default:
ret = nal->nal_unit_type;
break;
@@ -230,7 +234,7 @@ 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");
+ //printf("IDR SLICE\n");
parser->prev_pic_order_cnt_lsb = 0;
parser->prev_pic_order_cnt_msb = 0;
}
@@ -319,8 +323,9 @@ void parse_scaling_list(struct buf_reader *buf, uint8_t *scaling_list,
}
}
-uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps)
+uint8_t parse_sps(struct buf_reader *buf, struct nal_parser *parser)
{
+ struct seq_parameter_set_rbsp *sps = parser->current_nal->sps;
sps->profile_idc = buf->buf[0];
sps->constraint_setN_flag = (buf->buf[1] >> 4) & 0x0f;
sps->level_idc = buf->buf[2];
@@ -339,7 +344,6 @@ uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps)
sps->qpprime_y_zero_transform_bypass_flag = read_bits(buf, 1);
sps->seq_scaling_matrix_present_flag = read_bits(buf, 1);
if (sps->seq_scaling_matrix_present_flag) {
- printf("SCALING LIST PRESENT\n");
int i;
for (i = 0; i < 8; i++) {
sps->seq_scaling_list_present_flag[i] = read_bits(buf, 1);
@@ -403,11 +407,46 @@ uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps)
sps->vui_parameters_present_flag = read_bits(buf, 1);
if (sps->vui_parameters_present_flag) {
parse_vui_parameters(buf, sps);
- }
+ if(sps->vui_parameters.nal_hrd_parameters_present_flag ||
+ sps->vui_parameters.vc1_hrd_parameters_present_flag) {
+ parser->cpb_dpb_delays_present_flag = 1;
+ } else
+ parser->cpb_dpb_delays_present_flag = 0;
+ } else
+ parser->cpb_dpb_delays_present_flag = 0;
return 0;
}
+void parse_sei(struct buf_reader *buf, struct nal_parser *parser)
+{
+ struct sei_message *sei = &(parser->current_nal->sei);
+ uint8_t tmp;
+
+ sei->payload_type = 0;
+ while((tmp = read_bits(buf, 8)) == 0xff) {
+ sei->payload_type += 255;
+ }
+ sei->last_payload_type_byte = tmp;
+ sei->payload_type += sei->last_payload_type_byte;
+
+ sei->payload_size = 0;
+ while((tmp = read_bits(buf, 8)) == 0xff) {
+ sei->payload_size += 255;
+ }
+ sei->last_payload_size_byte = tmp;
+ sei->payload_size += sei->last_payload_size_byte;
+
+ /* pic_timing */
+ if(sei->payload_type == 1) {
+ if(parser->cpb_dpb_delays_present_flag) {
+ sei->pic_timing.cpb_removal_delay = read_bits(buf, 5);
+ sei->pic_timing.dpb_output_delay = read_bits(buf, 5);
+ printf("output delay: %d\n", sei->pic_timing.dpb_output_delay);
+ }
+ }
+}
+
void parse_vui_parameters(struct buf_reader *buf,
struct seq_parameter_set_rbsp *sps)
{
@@ -566,15 +605,15 @@ uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps,
}
if (!pps->pic_scaling_matrix_present_flag && sps != NULL) {
- printf("MEMCPY SCALING LIST\n");
+ //printf("MEMCPY SCALING LIST\n");
memcpy(pps->scaling_lists_4x4, sps->scaling_lists_4x4,
sizeof(pps->scaling_lists_4x4));
memcpy(pps->scaling_lists_8x8, sps->scaling_lists_8x8,
sizeof(pps->scaling_lists_8x8));
}
- else if (sps == NULL) {
+ /*else if (sps == NULL) {
printf("sPS MISSING\n");
- }
+ }*/
return 0;
}
@@ -789,43 +828,46 @@ void decode_ref_pic_marking(uint32_t memory_management_control_operation,
return;
if (memory_management_control_operation == 1) {
+ printf("MMC 1\n");
// short-term -> unused for reference
uint32_t pic_num_x = nal->curr_pic_num
- (slc->dec_ref_pic_marking.difference_of_pic_nums_minus1 + 1);
struct decoded_picture* pic = dpb_get_picture(dpb, pic_num_x);
if (pic != NULL) {
if (pic->nal->slc->field_pic_flag == 0)
- dpb_remove_picture(dpb, pic_num_x);
+ dpb_set_unused_ref_picture(dpb, pic_num_x);
else {
- dpb_remove_picture(dpb, pic_num_x);
+ dpb_set_unused_ref_picture(dpb, pic_num_x);
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) {
+ printf("MMC 2\n");
// long-term -> unused for reference
struct decoded_picture* pic = dpb_get_picture_by_ltpn(dpb,
slc->dec_ref_pic_marking.long_term_pic_num);
if (pic != NULL) {
if (pic->nal->slc->field_pic_flag == 0)
- dpb_remove_picture_by_ltpn(dpb,
+ dpb_set_unused_ref_picture(dpb,
slc->dec_ref_pic_marking.long_term_pic_num);
else {
- dpb_remove_picture_by_ltpn(dpb,
+ dpb_set_unused_ref_picture(dpb,
slc->dec_ref_pic_marking.long_term_pic_num);
printf("FIXME: We might need do delete more from the DPB...\n");
}
}
}
else if (memory_management_control_operation == 3) {
+ printf("MMC 3\n");
// short-term -> long-term, set long-term frame index
uint32_t pic_num_x = nal->curr_pic_num
- (slc->dec_ref_pic_marking.difference_of_pic_nums_minus1 + 1);
struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb,
slc->dec_ref_pic_marking.long_term_pic_num);
if (pic != NULL)
- dpb_remove_picture_by_ltidx(dpb,
+ dpb_set_unused_ref_picture_bylidx(dpb,
slc->dec_ref_pic_marking.long_term_frame_idx);
pic = dpb_get_picture(dpb, pic_num_x);
@@ -844,16 +886,18 @@ void decode_ref_pic_marking(uint32_t memory_management_control_operation,
}
else if (memory_management_control_operation == 4) {
+ printf("MMC 4\n");
// 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
if (slc->dec_ref_pic_marking.max_long_term_frame_idx_plus1 == 0)
- dpb_remove_ltidx_gt(dpb, 0);
+ dpb_set_unused_ref_picture_lidx_gt(dpb, 0);
else
- dpb_remove_ltidx_gt(dpb,
+ dpb_set_unused_ref_picture_lidx_gt(dpb,
slc->dec_ref_pic_marking.max_long_term_frame_idx_plus1 - 1);
}
else if (memory_management_control_operation == 5) {
+ printf("MMC 5\n");
// mark all ref pics as unused for reference,
// set max-long-term frame index = no long-term frame idxs
dpb_flush(dpb);
@@ -862,12 +906,13 @@ void decode_ref_pic_marking(uint32_t memory_management_control_operation,
parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb = 0;
}
else if (memory_management_control_operation == 6) {
+ printf("MMC 6\n");
// 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,
slc->dec_ref_pic_marking.long_term_frame_idx);
if (pic != NULL)
- dpb_remove_picture_by_ltidx(dpb,
+ dpb_set_unused_ref_picture_bylidx(dpb,
slc->dec_ref_pic_marking.long_term_frame_idx);
nal->long_term_frame_idx = slc->dec_ref_pic_marking.long_term_frame_idx;
@@ -961,6 +1006,8 @@ struct nal_parser* init_parser()
*/
parser->prev_pic_order_cnt_msb = parser->pic_order_cnt_lsb = 1 << 16;
+ parser->cpb_dpb_delays_present_flag = 0;
+
return parser;
}
@@ -1044,7 +1091,7 @@ int parse_frame(struct nal_parser *parser, uint8_t *inbuf, int inbuf_len,
return parsed_len;
}
- printf("slice %d size: %d\n", parser->slice_cnt-1, parser->prebuf_len);
+ //printf("slice %d size: %d\n", parser->slice_cnt-1, parser->prebuf_len);
/* this is a SLICE, keep it in the buffer */
xine_fast_memcpy(parser->buf + parser->buf_len, prebuf, parser->prebuf_len);
parser->buf_len += parser->prebuf_len;
diff --git a/src/libvdpau/h264_parser.h b/src/libvdpau/h264_parser.h
index 99691e950..966bf0880 100644
--- a/src/libvdpau/h264_parser.h
+++ b/src/libvdpau/h264_parser.h
@@ -38,6 +38,8 @@ struct nal_parser {
struct nal_unit *current_nal;
struct nal_unit *last_nal;
+ uint8_t cpb_dpb_delays_present_flag;
+
uint32_t pic_order_cnt_lsb;
uint32_t pic_order_cnt_msb;
uint32_t prev_pic_order_cnt_lsb;
diff --git a/src/libvdpau/nal.h b/src/libvdpau/nal.h
index c07c1d9a3..20c1c32dc 100644
--- a/src/libvdpau/nal.h
+++ b/src/libvdpau/nal.h
@@ -63,24 +63,6 @@ static inline uint32_t slice_type(uint32_t slice_type)
return (slice_type < 10 ? slice_type % 5 : slice_type);
}
-struct nal_unit
-{
- uint8_t nal_ref_idc; // 0x03
- uint8_t nal_unit_type; // 0x1f
-
- uint32_t curr_pic_num;
- uint8_t used_for_long_term_ref;
- uint32_t long_term_pic_num;
- uint32_t long_term_frame_idx;
-
- uint32_t top_field_order_cnt;
- uint32_t bottom_field_order_cnt;
-
- struct seq_parameter_set_rbsp *sps;
- struct pic_parameter_set_rbsp *pps;
- struct slice_header *slc;
-};
-
struct hrd_parameters
{
uint32_t cpb_cnt_minus1;
@@ -253,6 +235,27 @@ struct pic_parameter_set_rbsp
int32_t second_chroma_qp_index_offset;
};
+/* sei contains several additional info, we do
+ * only care for pic_timing, to handle display
+ * reordering
+ */
+struct sei_message
+{
+ uint32_t payload_type;
+ uint8_t last_payload_type_byte;
+ uint32_t payload_size;
+ uint8_t last_payload_size_byte;
+
+ union
+ {
+ /* cpb_dpb_delays_present_flag == 1 */
+ uint8_t cpb_removal_delay;
+ uint8_t dpb_output_delay;
+
+ /* ignore the rest */
+ } pic_timing;
+};
+
struct slice_header
{
uint32_t first_mb_in_slice;
@@ -341,10 +344,28 @@ struct slice_header
} dec_ref_pic_marking;
};
+struct nal_unit
+{
+ uint8_t nal_ref_idc; // 0x03
+ uint8_t nal_unit_type; // 0x1f
+
+ uint32_t curr_pic_num;
+ uint8_t used_for_long_term_ref;
+ uint32_t long_term_pic_num;
+ uint32_t long_term_frame_idx;
+
+ uint32_t top_field_order_cnt;
+ uint32_t bottom_field_order_cnt;
+
+ struct sei_message sei;
+
+ struct seq_parameter_set_rbsp *sps;
+ struct pic_parameter_set_rbsp *pps;
+ struct slice_header *slc;
+};
struct nal_unit* init_nal_unit();
void free_nal_unit(struct nal_unit *nal);
void copy_nal_unit(struct nal_unit *dest, struct nal_unit *src);
-
#endif /* NAL_H_ */
diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c
index 9b66e57c5..fbbdbe205 100644
--- a/src/libvdpau/vdpau_h264.c
+++ b/src/libvdpau/vdpau_h264.c
@@ -353,7 +353,7 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
// FIXME: do we really hit all cases here?
if(((uint8_t*)vdp_buffer.bitstream) != NULL) {
- free(vdp_buffer.bitstream);
+ free((uint8_t*)vdp_buffer.bitstream);
}
if(status != VDP_STATUS_OK)
@@ -364,13 +364,17 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
img->pts = buf->pts;
img->bad_frame = 0;
+ struct decoded_picture *decoded_pic = NULL;
if(pic.is_reference) {
if(!slc->field_pic_flag || !this->wait_for_bottom_field) {
- struct decoded_picture *pic = init_decoded_picture(this->nal_parser->current_nal, surface, img);
- this->last_ref_pic = pic;
- dpb_add_picture(&(this->nal_parser->dpb), pic, sps->num_ref_frames);
+ decoded_pic = init_decoded_picture(this->nal_parser->current_nal, surface, img);
+ this->last_ref_pic = decoded_pic;
+ printf("Add ref pic: %d\n", decoded_pic->nal->slc->frame_num);
+ decoded_pic->used_for_reference = 1;
+ dpb_add_picture(&(this->nal_parser->dpb), decoded_pic, sps->num_ref_frames);
} else if(slc->field_pic_flag && this->wait_for_bottom_field) {
if(this->last_ref_pic) {
+ decoded_pic = this->last_ref_pic;
this->last_ref_pic->bottom_is_reference = 1;
}
}
@@ -378,20 +382,38 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
if(!slc->field_pic_flag ||
(slc->field_pic_flag && slc->bottom_field_flag && this->wait_for_bottom_field)) {
+ /*if(!decoded_pic) {
+ decoded_pic = init_decoded_picture(this->nal_parser->current_nal, surface, img);
+ decoded_pic->delayed_output = 1;
+ dpb_add_picture(&(this->nal_parser->dpb), decoded_pic, sps->num_ref_frames);
+ } else
+ decoded_pic->delayed_output = 1;
+
+ img = NULL;
+
+ / * now retrieve the next output frame * /
+ decoded_pic = dpb_get_next_out_picture(&(this->nal_parser->dpb));
+ if(decoded_pic) {
+ printf("DRAW AN IMAGE\n");
+ decoded_pic->img->draw(decoded_pic->img, this->stream);
+
+ dpb_set_output_picture(&(this->nal_parser->dpb), decoded_pic);
+ } else
+ printf("NO IMAGE THIS TIME\n");
+
+ this->wait_for_bottom_field = 0;*/
+
img->draw(img, this->stream);
this->wait_for_bottom_field = 0;
if(!pic.is_reference)
img->free(img);
-
img = NULL;
} else if(slc->field_pic_flag && !slc->bottom_field_flag) {
// don't draw yet, second field is missing.
this->wait_for_bottom_field = 1;
}
}
-
- //this->vdpau_accel->vdp_video_surface_destroy(surface);
}
}
}