summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/libvdpau/Makefile.am17
-rw-r--r--src/libvdpau/vdpau_h264.c98
-rw-r--r--src/xine-engine/accel_vdpau.h6
4 files changed, 91 insertions, 31 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6718b4805..cb6236033 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,5 +25,6 @@ SUBDIRS = \
libreal \
libfaad \
libmusepack \
+ libvdpau \
post \
combined
diff --git a/src/libvdpau/Makefile.am b/src/libvdpau/Makefile.am
new file mode 100644
index 000000000..9fb5527bf
--- /dev/null
+++ b/src/libvdpau/Makefile.am
@@ -0,0 +1,17 @@
+include $(top_srcdir)/misc/Makefile.common
+
+AM_CFLAGS = $(VISIBILITY_FLAG)
+AM_LDFLAGS = $(xineplug_ldflags)
+
+EXTRA_DIST = vdpau_h264.c
+
+if HAVE_VDPAU
+vdpau_h264_module = xineplug_decode_vdpau_h264.la
+endif
+
+xineplug_LTLIBRARIES = $(vdpau_h264_module) \
+ xineplug_decode_vdpau_h264.la \
+
+xineplug_decode_image_la_SOURCES = nal_parser.c vdpau_h264.c
+xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS)
+xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(WAND_LIBS)
diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c
index 638eb749a..afd4561c6 100644
--- a/src/libvdpau/vdpau_h264.c
+++ b/src/libvdpau/vdpau_h264.c
@@ -36,6 +36,7 @@
#include "buffer.h"
#include "xineutils.h"
#include "bswap.h"
+#include "accel_vdpau.h"
#define VIDEOBUFSIZE 128*1024
@@ -63,12 +64,14 @@ typedef struct vdpau_h264_decoder_s {
int height; /* the height of a video frame */
double ratio; /* the width to height ratio */
- struct nal_parser *nal_parser /* h264 nal parser. extracts stream data for vdpau */
- VdpPictureInfoH264 vdp_picture_info;
+ struct nal_parser *nal_parser; /* h264 nal parser. extracts stream data for vdpau */
- /* these are variables exclusive to the foo video decoder */
- unsigned char current_yuv_byte;
+ VdpDecoderProfile profile;
+ VdpPictureInfoH264 vdp_picture_info;
+ vdpau_accel_t *vdpau_accel;
+
+ xine_t *xine
} vdpau_h264_decoder_t;
@@ -88,7 +91,9 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
buf_element_t *buf) {
vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *) this_gen;
- xine_bmiheader *bih;
+
+ VdpBitstreamBuffer vdp_buffer;
+ vdp_buffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION;
vo_frame_t *img; /* video out frame */
@@ -102,32 +107,72 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
}
if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */
- (this->stream->video_out->open) (this->stream->video_out, this->stream);
+ return;
+ }
- if(this->buf)
- free(this->buf);
+ if (!this->decoder_ok) {
+ /* parse the first nal packages to retrieve profile type */
+ int len = 0;
- bih = (xine_bmiheader *) buf->content;
- this->width = bih->biWidth;
- this->height = bih->biHeight;
- this->ratio = (double)this->width/(double)this->height;
+ while(len < buf->size) {
+ len += parse_frame(this->parser, buf->content + len, buf->size - len,
+ &vdp_buffer.bitstream, &vdp_buffer.bitstream_bytes);
- if (this->buf)
- free (this->buf);
- this->bufsize = VIDEOBUFSIZE;
- this->buf = malloc(this->bufsize);
- this->size = 0;
+ if(this->nal_parser->current_nal->sps != NULL) {
+ printf("SPS PARSED\n");
- /* take this opportunity to load the stream/meta info */
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo");
+ this->width = this->nal_parser->current_nal->sps->pic_width;
+ this->height = this->nal_parser->current_nal->sps->pic_height;
- /* do anything else relating to initializing this decoder */
- this->current_yuv_byte = 0;
+ /* FIXME: ratio should be calculated in some other way to
+ * support anamorph codings...
+ */
+ this->ratio = (double)this->width / (double)this->height;
- this->decoder_ok = 1;
+ switch(this->nal_parser->current_nal->sps->profile_idc) {
+ case 100:
+ this->profile = VDP_DECODER_PROFILE_H264_HIGH;
+ break;
+ case 77:
+ this->profile = VDP_DECODER_PROFILE_H264_MAIN;
+ break;
+ case 66:
+ default:
+ this->profile = VDP_DECODER_PROFILE_H264_BASELINE;
+ break;
+ }
- return;
- } else if (this->decoder_ok) {
+ /* get the vdpau context from vo */
+ (this->stream->video_out->open) (this->stream->video_out, this->stream);
+ 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;
+
+ VdpBool is_supported;
+ uint32_t max_level, max_references, max_width, max_height;
+
+ VdpStatus status = this->vdpau_accel->vdp_decoder_create(this->vdpau_accel->vdp_device,
+ this->profile, &is_supported, &max_level, &max_references,
+ &max_width, &max_height);
+
+ if(status != OK)
+ xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: ERROR: VdpDecoderCreate returned status != OK (%d)\n", status);
+
+ 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_ok) {
if (this->size + buf->size > this->bufsize) {
this->bufsize = this->size + 2 * buf->size;
@@ -143,7 +188,7 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
img = this->stream->video_out->get_frame (this->stream->video_out,
this->width, this->height,
this->ratio,
- XINE_IMGFMT_YUY2, VO_BOTH_FIELDS);
+ XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS);
img->duration = this->video_step;
img->pts = buf->pts;
@@ -226,9 +271,12 @@ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stre
this->size = 0;
this->stream = stream;
+ this->xine = stream->xine;
this->class = (vdpau_h264_class_t *) class_gen;
this->decoder_ok = 0;
+ this->decoder_initialized = 0;
+ this->nal_parser = init_parser();
this->buf = NULL;
return &this->video_decoder;
diff --git a/src/xine-engine/accel_vdpau.h b/src/xine-engine/accel_vdpau.h
index 39231314c..ef76fe5ee 100644
--- a/src/xine-engine/accel_vdpau.h
+++ b/src/xine-engine/accel_vdpau.h
@@ -49,12 +49,6 @@ typedef struct {
VdpVideoSurface surface;
- union _VdpPictureInfo {
- VdpPictureInfoMPEG1Or2 mpeg;
- VdpPictureInfoH264 h264;
- VdpPictureInfoVC1 vc1;
- } info;
-
} vdpau_accel_t;
#ifdef __cplusplus