diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libvdpau/nal_parser.c | 37 | ||||
-rw-r--r-- | src/libvdpau/nal_parser.h | 22 | ||||
-rw-r--r-- | src/libvdpau/vdpau_h264.c | 49 |
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; } |