summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <[email protected]>2011-10-31 11:45:37 +0100
committerChristian König <[email protected]>2011-11-03 13:52:01 +0100
commit12bf452945ae64da69f474298758f9a7c8b94af5 (patch)
treefe015795c0649e837faa0b3efeb7d9113f43800b
parent1eb48c5500e5b3e3319108a1cecf63524fdede0d (diff)
state_trackers/vdpau: Add support for MPEG4 Part 2
Just the support patch, no decoder implements it currently. Signed-off-by: Maarten Lankhorst <[email protected]>
-rw-r--r--src/gallium/include/pipe/p_video_state.h27
-rw-r--r--src/gallium/state_trackers/vdpau/decode.c98
2 files changed, 105 insertions, 20 deletions
diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h
index 53da1d85119..0530b4a21ad 100644
--- a/src/gallium/include/pipe/p_video_state.h
+++ b/src/gallium/include/pipe/p_video_state.h
@@ -185,6 +185,33 @@ struct pipe_mpeg12_macroblock
unsigned short num_skipped_macroblocks;
};
+struct pipe_mpeg4_picture_desc
+{
+ struct pipe_picture_desc base;
+ int32_t trd[2];
+ int32_t trb[2];
+ uint16_t vop_time_increment_resolution;
+ uint8_t vop_coding_type;
+ uint8_t vop_fcode_forward;
+ uint8_t vop_fcode_backward;
+ uint8_t resync_marker_disable;
+ uint8_t interlaced;
+ uint8_t quant_type;
+ uint8_t quarter_sample;
+ uint8_t short_video_header;
+ uint8_t rounding_control;
+ uint8_t alternate_vertical_scan_flag;
+ uint8_t top_field_first;
+};
+
+struct pipe_mpeg4_quant_matrix
+{
+ struct pipe_quant_matrix base;
+
+ const uint8_t *intra_matrix;
+ const uint8_t *non_intra_matrix;
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
index 2b23dfde9c5..c39c365cc8d 100644
--- a/src/gallium/state_trackers/vdpau/decode.c
+++ b/src/gallium/state_trackers/vdpau/decode.c
@@ -28,6 +28,7 @@
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_debug.h"
+#include "util/u_video.h"
#include "vdpau_private.h"
@@ -201,9 +202,7 @@ vlVdpDecoderGetParameters(VdpDecoder decoder,
*/
static VdpStatus
vlVdpDecoderRenderMpeg12(struct pipe_video_decoder *decoder,
- VdpPictureInfoMPEG1Or2 *picture_info,
- uint32_t bitstream_buffer_count,
- VdpBitstreamBuffer const *bitstream_buffers)
+ VdpPictureInfoMPEG1Or2 *picture_info)
{
struct pipe_mpeg12_picture_desc picture;
struct pipe_mpeg12_quant_matrix quant;
@@ -255,15 +254,62 @@ vlVdpDecoderRenderMpeg12(struct pipe_video_decoder *decoder,
quant.non_intra_matrix = picture_info->non_intra_quantizer_matrix;
decoder->set_quant_matrix(decoder, &quant.base);
+ return VDP_STATUS_OK;
+}
+
+/**
+ * Decode a mpeg 1/2 video.
+ */
+static VdpStatus
+vlVdpDecoderRenderMpeg4(struct pipe_video_decoder *decoder,
+ VdpPictureInfoMPEG4Part2 *picture_info)
+{
+ struct pipe_mpeg4_picture_desc picture;
+ struct pipe_mpeg4_quant_matrix quant;
+ struct pipe_video_buffer *ref_frames[2] = {};
+ unsigned i;
- decoder->begin_frame(decoder);
+ VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG4\n");
- for (i = 0; i < bitstream_buffer_count; ++i)
- decoder->decode_bitstream(decoder, bitstream_buffers[i].bitstream_bytes,
- bitstream_buffers[i].bitstream);
+ /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
+ if (picture_info->forward_reference != VDP_INVALID_HANDLE) {
+ ref_frames[0] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->forward_reference))->video_buffer;
+ if (!ref_frames[0])
+ return VDP_STATUS_INVALID_HANDLE;
+ }
+
+ if (picture_info->backward_reference != VDP_INVALID_HANDLE) {
+ ref_frames[1] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->backward_reference))->video_buffer;
+ if (!ref_frames[1])
+ return VDP_STATUS_INVALID_HANDLE;
+ }
+ decoder->set_reference_frames(decoder, ref_frames, 2);
- decoder->end_frame(decoder);
+ memset(&picture, 0, sizeof(picture));
+ picture.base.profile = decoder->profile;
+ for (i = 0; i < 2; ++i) {
+ picture.trd[i] = picture_info->trd[i];
+ picture.trb[i] = picture_info->trb[i];
+ }
+ picture.vop_time_increment_resolution = picture_info->vop_time_increment_resolution;
+ picture.vop_coding_type = picture_info->vop_coding_type;
+ picture.vop_fcode_forward = picture_info->vop_fcode_forward;
+ picture.vop_fcode_backward = picture_info->vop_fcode_backward;
+ picture.resync_marker_disable = picture_info->resync_marker_disable;
+ picture.interlaced = picture_info->interlaced;
+ picture.quant_type = picture_info->quant_type;
+ picture.quarter_sample = picture_info->quarter_sample;
+ picture.short_video_header = picture_info->short_video_header;
+ picture.rounding_control = picture_info->rounding_control;
+ picture.alternate_vertical_scan_flag = picture_info->alternate_vertical_scan_flag;
+ picture.top_field_first = picture_info->top_field_first;
+ decoder->set_picture_parameters(decoder, &picture.base);
+ memset(&quant, 0, sizeof(quant));
+ quant.base.codec = PIPE_VIDEO_CODEC_MPEG4;
+ quant.intra_matrix = picture_info->intra_quantizer_matrix;
+ quant.non_intra_matrix = picture_info->non_intra_quantizer_matrix;
+ decoder->set_quant_matrix(decoder, &quant.base);
return VDP_STATUS_OK;
}
@@ -279,6 +325,9 @@ vlVdpDecoderRender(VdpDecoder decoder,
{
vlVdpDecoder *vldecoder;
vlVdpSurface *vlsurf;
+ VdpStatus ret;
+ struct pipe_video_decoder *dec;
+ unsigned i;
VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding\n");
@@ -288,6 +337,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
if (!vldecoder)
return VDP_STATUS_INVALID_HANDLE;
+ dec = vldecoder->decoder;
vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
if (!vlsurf)
@@ -296,26 +346,34 @@ vlVdpDecoderRender(VdpDecoder decoder,
if (vlsurf->device != vldecoder->device)
return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
- if (vlsurf->video_buffer->chroma_format != vldecoder->decoder->chroma_format)
+ if (vlsurf->video_buffer->chroma_format != dec->chroma_format)
// TODO: Recreate decoder with correct chroma
return VDP_STATUS_INVALID_CHROMA_TYPE;
- // TODO: Right now only mpeg 1 & 2 videos are supported.
- switch (vldecoder->decoder->profile) {
- case PIPE_VIDEO_PROFILE_MPEG1:
- case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
- case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
- ++vldecoder->cur_buffer;
- vldecoder->cur_buffer %= vldecoder->num_buffers;
+ ++vldecoder->cur_buffer;
+ vldecoder->cur_buffer %= vldecoder->num_buffers;
- vldecoder->decoder->set_decode_buffer(vldecoder->decoder, vldecoder->buffers[vldecoder->cur_buffer]);
- vldecoder->decoder->set_decode_target(vldecoder->decoder, vlsurf->video_buffer);
+ dec->set_decode_buffer(dec, vldecoder->buffers[vldecoder->cur_buffer]);
+ dec->set_decode_target(dec, vlsurf->video_buffer);
- return vlVdpDecoderRenderMpeg12(vldecoder->decoder, (VdpPictureInfoMPEG1Or2 *)picture_info,
- bitstream_buffer_count, bitstream_buffers);
+ switch (u_reduce_video_profile(dec->profile)) {
+ case PIPE_VIDEO_CODEC_MPEG12:
+ ret = vlVdpDecoderRenderMpeg12(dec, (VdpPictureInfoMPEG1Or2 *)picture_info);
+ break;
+ case PIPE_VIDEO_CODEC_MPEG4:
+ ret = vlVdpDecoderRenderMpeg4(dec, (VdpPictureInfoMPEG4Part2 *)picture_info);
break;
default:
return VDP_STATUS_INVALID_DECODER_PROFILE;
}
+ if (ret != VDP_STATUS_OK)
+ return ret;
+
+ dec->begin_frame(dec);
+ for (i = 0; i < bitstream_buffer_count; ++i)
+ dec->decode_bitstream(dec, bitstream_buffers[i].bitstream_bytes,
+ bitstream_buffers[i].bitstream);
+ dec->end_frame(dec);
+ return ret;
}