summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libvdpau/nal_parser.c37
-rw-r--r--src/libvdpau/nal_parser.h22
-rw-r--r--src/libvdpau/vdpau_h264.c49
3 files changed, 72 insertions, 36 deletions
diff --git a/src/libvdpau/nal_parser.c b/src/libvdpau/nal_parser.c
index 9835cb1a4..ef380db36 100644
--- a/src/libvdpau/nal_parser.c
+++ b/src/libvdpau/nal_parser.c
@@ -229,7 +229,11 @@ int parse_nal_header(struct buf_reader *buf, struct nal_unit *nal)
void calculate_pic_order(struct nal_parser *parser)
{
+ return;
+
+
struct nal_unit *nal = parser->current_nal;
+ struct dpb *dpb = parser->dpb;
struct seq_parameter_set_rbsp *sps = nal->sps;
struct pic_parameter_set_rbsp *pps = nal->pps;
@@ -237,6 +241,34 @@ void calculate_pic_order(struct nal_parser *parser)
if(!sps || !pps)
return;
+ uint32_t max_frame_num = pow(2, sps->log2_max_frame_num_minus4+4);
+ if(dpb->max_frame_num == 0)
+ dpb->max_frame_num = max_frame_num;
+
+ if(dpb->max_frame_num != max_frame_num && dpb->max_frame_num != 0)
+ printf("ERROR, FIXME, max_frame_num changed");
+
+ /* calculate frame_num based stuff */
+ if(nal->nal_unit_type == NAL_SLICE_IDR) {
+ dpb->prev_ref_frame_number = 0;
+ } else {
+ // FIXME: understand p92 in h264 spec
+ }
+
+ if(slc->frame_num != dpb->prev_ref_frame_number) {
+ memset(dpb->non_existing_pictures, 0, 32);
+ int i = 0;
+ dpb->unused_short_term_frame_num = (dpb->prev_ref_frame_number + 1) % dpb->max_frame_num;
+ dpb->non_existing_pictures[i] = dpb->unused_short_term_frame_num;
+ i++;
+
+ while(dpb->unused_short_term_frame_num != slc->frame_num) {
+ dpb->unused_short_term_frame_num = (dpb->unused_short_term_frame_num + 1) % dpb->max_frame_num;
+ dpb->non_existing_pictures[i] = dpb->unused_short_term_frame_num;
+ i++;
+ }
+ }
+
if(sps->pic_order_cnt_type == 0) {
if(nal->nal_unit_type == NAL_SLICE_IDR) {
parser->prev_pic_order_cnt_lsb = 0;
@@ -809,6 +841,9 @@ int parse_frame(struct nal_parser *parser, uint8_t *inbuf, int inbuf_len,
if((parser->last_nal_res = parse_nal(inbuf+4, inbuf_len-parsed_len, parser)) == 1
&& parser->buf_len>0) {
// parse_nal returned 1 --> detected a frame_boundary
+ // do the extended parsing stuff...
+ calculate_pic_order(parser);
+
*ret_buf = malloc(parser->buf_len);
xine_fast_memcpy(*ret_buf, parser->buf, parser->buf_len);
*ret_len = parser->buf_len;
@@ -852,8 +887,6 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser)
int res = parse_nal_header(&bufr, nal);
- calculate_pic_order(parser);
-
if(res >= NAL_SLICE && res <= NAL_SLICE_IDR) {
// now detect if it's a new frame!
int ret = 0;
diff --git a/src/libvdpau/nal_parser.h b/src/libvdpau/nal_parser.h
index 792f2e0f2..d8195c987 100644
--- a/src/libvdpau/nal_parser.h
+++ b/src/libvdpau/nal_parser.h
@@ -318,6 +318,22 @@ struct slice_header {
};
+struct decoded_picture {
+ //VdpReferenceFrameH264 surface;
+ struct nal_unit *nal;
+};
+
+/* Decoded Picture Buffer */
+struct dpb {
+ uint32_t max_frame_num;
+
+ uint32_t prev_ref_frame_number;
+ uint32_t unused_short_term_frame_num;
+ uint32_t non_existing_pictures[32];
+
+ struct decoded_picture *pictures;
+};
+
#define MAX_FRAME_SIZE 1024*1024
struct nal_parser {
@@ -343,12 +359,8 @@ struct nal_parser {
int32_t bottom_field_oder_cnt;
int32_t prev_pic_order_cnt_msb;
int32_t prev_pic_order_cnt_lsb;
-};
-
-/* Decoded Picture Buffer */
-struct dpb {
- uint32_t max_frame_number;
+ struct dpb *dpb;
};
int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser);
diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c
index 10577bc59..961e8da81 100644
--- a/src/libvdpau/vdpau_h264.c
+++ b/src/libvdpau/vdpau_h264.c
@@ -53,7 +53,7 @@ typedef struct vdpau_h264_decoder_s {
/* these are traditional variables in a video decoder object */
uint64_t video_step; /* frame duration in pts units */
- int decoder_ok; /* current decoder status */
+ int decoder_started; /* current decoder status */
int decoder_initialized; /* vdpau init state */
int skipframes;
@@ -74,6 +74,9 @@ typedef struct vdpau_h264_decoder_s {
VdpPictureInfoH264 vdp_picture_info;
vdpau_accel_t *vdpau_accel;
+ VdpReferenceFrameH264 reference_frames[16];
+ int reference_frames_used;
+
xine_t *xine;
} vdpau_h264_decoder_t;
@@ -169,12 +172,6 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
this->decoder_initialized = 1;
img->free(img);
-
- /*if(!is_supported)
- xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: ERROR: Profile not supported by VDPAU decoder.\n");
-
- if(max_width < this->width || max_height < this->height)
- xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: ERROR: Image size not supported by VDPAU decoder.\n");*/
}
if(this->decoder_initialized) {
@@ -183,12 +180,6 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
this->nal_parser->current_nal->sps != NULL &&
this->nal_parser->current_nal->pps != NULL) {
- img = this->stream->video_out->get_frame (this->stream->video_out,
- this->width, this->height,
- this->ratio,
- XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS);
- this->vdpau_accel = (vdpau_accel_t*)img->accel_data;
-
struct pic_parameter_set_rbsp *pps = this->nal_parser->current_nal->pps;
struct seq_parameter_set_rbsp *sps = this->nal_parser->current_nal->sps;
struct slice_header *slc = this->nal_parser->current_nal->slc;
@@ -231,27 +222,24 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
img->pts = buf->pts;
img->bad_frame = 0;
- printf("Decode pts: %lld, %d\n", img->pts, vdp_buffer.bitstream_bytes);
- /* create surface if needed */
- if(this->vdpau_accel->surface == VDP_INVALID_HANDLE) {
- VdpStatus status = this->vdpau_accel->vdp_video_surface_create(this->vdpau_accel->vdp_device,
- VDP_CHROMA_TYPE_420, this->width, this->height,
- &this->vdpau_accel->surface);
- if(status != VDP_STATUS_OK)
- xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Surface creation failed\n");
- }
+ VdpVideoSurface surface;
+ VdpStatus status = this->vdpau_accel->vdp_video_surface_create(this->vdpau_accel->vdp_device,
+ VDP_CHROMA_TYPE_420, this->width, this->height,
+ &surface);
- VdpStatus status = this->vdpau_accel->vdp_decoder_render(this->decoder,
- this->vdpau_accel->surface, (VdpPictureInfo*)&pic, 1, &vdp_buffer);
+ if(status != VDP_STATUS_OK)
+ xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Surface creation failed\n");
+
+ status = this->vdpau_accel->vdp_decoder_render(this->decoder,
+ surface, (VdpPictureInfo*)&pic, 1, &vdp_buffer);
if(status != VDP_STATUS_OK)
xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Decoder failure: %d\n", status);
else
printf("DECODING SUCCESS\n");
- img->draw(img, this->stream);
- img->free(img);
+ this->vdpau_accel->vdp_video_surface_destroy(surface);
}
}
}
@@ -293,8 +281,8 @@ static void vdpau_h264_dispose (video_decoder_t *this_gen) {
this->buf = NULL;
}
- if (this->decoder_ok) {
- this->decoder_ok = 0;
+ if (this->decoder_initialized) {
+ this->decoder_initialized = 0;
this->stream->video_out->close(this->stream->video_out, this->stream);
}
@@ -326,11 +314,14 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
this->xine = stream->xine;
this->class = (vdpau_h264_class_t *) class_gen;
- this->decoder_ok = 0;
+ this->decoder_started = 0;
this->decoder_initialized = 0;
this->nal_parser = init_parser();
this->buf = NULL;
+ memset(this->reference_frames, 0x00, sizeof(this->reference_frames));
+ this->reference_frames_used = 0;
+
return &this->video_decoder;
}