summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmeric Grange <emeric.grange@gmail.com>2012-02-13 22:19:42 +0100
committerEmeric Grange <emeric.grange@gmail.com>2012-06-24 16:57:33 +0200
commit380c3784dac99d8ef46e60ba3ec8c7104cd0813a (patch)
tree16773651f251cd18e83548e8ad0bb2d5b6efeb9e
parente5d2739f86010e7213c223ba4b482bf0c6221f8e (diff)
g3dvl/vp8: Move bitstream sync_code detection to the VDPAU state tracker, simplify the ycbcr buffer upload
Signed-off-by: Emeric Grange <emeric.grange@gmail.com>
-rw-r--r--src/gallium/auxiliary/vl/vl_vp8_decoder.c142
-rw-r--r--src/gallium/auxiliary/vl/vl_vp8_decoder.h3
-rw-r--r--src/gallium/auxiliary/vl/vp8/vp8_decoder.c2
-rw-r--r--src/gallium/auxiliary/vl/vp8/vp8_decoder.h2
-rw-r--r--src/gallium/state_trackers/vdpau/decode.c41
5 files changed, 86 insertions, 104 deletions
diff --git a/src/gallium/auxiliary/vl/vl_vp8_decoder.c b/src/gallium/auxiliary/vl/vl_vp8_decoder.c
index e9f3636015..626feefdce 100644
--- a/src/gallium/auxiliary/vl/vl_vp8_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_vp8_decoder.c
@@ -173,7 +173,6 @@ vl_vp8_begin_frame(struct pipe_video_decoder *decoder,
}
dec->current_buffer = 0;
- dec->img_ready = 0;
}
static void
@@ -208,114 +207,63 @@ vl_vp8_decode_bitstream(struct pipe_video_decoder *decoder,
struct vl_vp8_buffer *buf;
assert(dec && target && picture);
+ assert(num_buffers == 1);
buf = vl_vp8_get_decode_buffer(dec, target);
assert(buf);
- // Try and detect start_code from the first data buffer
- const uint8_t *datab = (const uint8_t *)buffers[dec->current_buffer];
+ // Start bitstream decoding
+ //vl_vp8_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes);
- if (datab[0] == 0x9D &&
- datab[1] == 0x01 &&
- datab[2] == 0x2A)
+ // Start bitstream decoding
+ if (vp8_decoder_start(dec->vp8_dec, desc, (const uint8_t *)buffers[dec->current_buffer], sizes[dec->current_buffer]))
{
- if (sizes[dec->current_buffer] == 3)
- {
- // The start_code [0x9D012A] is present in a dedicated buffer
- ++dec->current_buffer;
- dec->current_buffer %= 4;
- }
- else if (num_buffers == 1)
- {
- // The start_code [0x9D012A] is present in the same buffer as the bistream data
- //buffers[dec->current_buffer] += 3;
+ printf("[G3DVL] Error : VP8 frame decoding error !\n");
+ }
+ else
+ {
+ struct pipe_sampler_view **sampler_views;
+ struct pipe_context *pipe;
+ int i = 0;
+
+ // Get the current decoded frame from the software decoder
+ if (vp8_decoder_get_frame_decoded(dec->vp8_dec, &dec->img_yv12)) {
+ printf("[end_frame] No valid VP8 frame to output !\n");
+ return;
}
- // Start bitstream decoding
- //vl_vp8_bs_decode(&buf->bs, target, desc, num_buffers, buffers, sizes);
+ // VP8 bypass transfert frame
+ pipe = buf->bs.decoder->context;
+ if (!pipe) {
+ return;
+ }
- if (vp8_decoder_start(dec->vp8_dec, desc, (const uint8_t *)buffers[dec->current_buffer], sizes[dec->current_buffer]))
- {
- printf("[G3DVL] Error : decoding error, not a valid VP8 VDPAU frame !\n");
- dec->img_ready = 0;
+ sampler_views = target->get_sampler_view_planes(target);
+ if (!sampler_views) {
+ return;
}
- else
- {
- dec->img_ready = 1;
-
- struct pipe_sampler_view **sampler_views;
- struct pipe_context *pipe;
- int i = 0, j = 0;
-
- // VP8 bypass transfert frame
- pipe = buf->bs.decoder->context;
- if (!pipe) {
- printf("[end_frame] No pipe\n");
- return;
- }
-
- sampler_views = target->get_sampler_view_planes(target);
- if (!sampler_views) {
- printf("[end_frame] No sampler_views\n");
- return;
- }
-
- // Get the decoded frame
- if (vp8_decoder_getframe(dec->vp8_dec, &dec->img_yv12)) {
- printf("[end_frame] No image to output !\n");
- return;
- }
-
- // Load YCbCr planes into a GPU texture
- for (i = 0; i < 3; ++i)
- {
- struct pipe_sampler_view *sv = sampler_views[i];
-
- if (!sv)
- continue;
-
- for (j = 0; j < sv->texture->depth0; ++j)
- {
- struct pipe_box dst_box = {
- 0, 0, j,
- sv->texture->width0, sv->texture->height0, 1
- };
-
- struct pipe_transfer *dst_transfer = pipe->get_transfer(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box);;
-
- if (!dst_transfer) {
- printf("[end_frame] No dst_transfer\n");
- return;
- }
-
- ubyte *src = dec->img_yv12.y_buffer;
- if (i == 1)
- src = dec->img_yv12.v_buffer;
- else if (i == 2)
- src = dec->img_yv12.u_buffer;
-
- void *dst = pipe->transfer_map(pipe, dst_transfer);
- if (dst) {
- util_copy_rect(dst,
- sv->texture->format,
- dst_transfer->stride,
- dst_box.x, dst_box.y,
- dst_box.width, dst_box.height,
- src,
- (i ? dec->img_yv12.uv_stride : dec->img_yv12.y_stride),
- 0, 0);
- }
-
- pipe->transfer_unmap(pipe, dst_transfer);
- pipe->transfer_destroy(pipe, dst_transfer);
- }
- }
+
+ // Load YCbCr planes into a GPU texture
+ for (i = 0; i < 3; ++i) {
+ struct pipe_sampler_view *sv = sampler_views[i];
+
+ if (!sv)
+ continue;
+
+ struct pipe_box dst_box = {0, 0, 0, sv->texture->width0, sv->texture->height0, 1};
+
+ ubyte *src = dec->img_yv12.y_buffer;
+ if (i == 1)
+ src = dec->img_yv12.v_buffer;
+ else if (i == 2)
+ src = dec->img_yv12.u_buffer;
+
+ pipe->transfer_inline_write(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE,
+ &dst_box, src,
+ (i ? dec->img_yv12.uv_stride : dec->img_yv12.y_stride),
+ 0);
}
}
- else
- {
- printf("[G3DVL] Error : the first data buffer does not contain the mandatory start_code [0x9D012A] !\n");
- }
}
static void
diff --git a/src/gallium/auxiliary/vl/vl_vp8_decoder.h b/src/gallium/auxiliary/vl/vl_vp8_decoder.h
index 4903383c6f..d86b573011 100644
--- a/src/gallium/auxiliary/vl/vl_vp8_decoder.h
+++ b/src/gallium/auxiliary/vl/vl_vp8_decoder.h
@@ -81,9 +81,6 @@ struct vl_vp8_decoder
// VP8 decoder context
VP8_COMMON *vp8_dec;
YV12_BUFFER_CONFIG img_yv12;
-
- unsigned startcode;
- unsigned img_ready;
};
struct vl_vp8_buffer
diff --git a/src/gallium/auxiliary/vl/vp8/vp8_decoder.c b/src/gallium/auxiliary/vl/vp8/vp8_decoder.c
index 51a180e574..4aff049dd6 100644
--- a/src/gallium/auxiliary/vl/vp8/vp8_decoder.c
+++ b/src/gallium/auxiliary/vl/vp8/vp8_decoder.c
@@ -208,7 +208,7 @@ int vp8_decoder_start(VP8_COMMON *common,
/**
* Return a decoded VP8 frame in a YV12 framebuffer.
*/
-int vp8_decoder_getframe(VP8_COMMON *common, YV12_BUFFER_CONFIG *sd)
+int vp8_decoder_get_frame_decoded(VP8_COMMON *common, YV12_BUFFER_CONFIG *sd)
{
int ret = -1;
diff --git a/src/gallium/auxiliary/vl/vp8/vp8_decoder.h b/src/gallium/auxiliary/vl/vp8/vp8_decoder.h
index 7043e2f1e5..882a6f25bc 100644
--- a/src/gallium/auxiliary/vl/vp8/vp8_decoder.h
+++ b/src/gallium/auxiliary/vl/vp8/vp8_decoder.h
@@ -190,7 +190,7 @@ int vp8_decoder_start(VP8_COMMON *common,
struct pipe_vp8_picture_desc *frame_header,
const unsigned char *data, unsigned data_size);
-int vp8_decoder_getframe(VP8_COMMON *common, YV12_BUFFER_CONFIG *sd);
+int vp8_decoder_get_frame_decoded(VP8_COMMON *common, YV12_BUFFER_CONFIG *sd);
void vp8_decoder_remove(VP8_COMMON *common);
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
index b0582617cd..e9833b6c4c 100644
--- a/src/gallium/state_trackers/vdpau/decode.c
+++ b/src/gallium/state_trackers/vdpau/decode.c
@@ -462,7 +462,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
struct pipe_screen *screen;
struct pipe_video_decoder *dec;
bool buffer_support[2];
- unsigned i;
+ unsigned i, j;
union {
struct pipe_picture_desc base;
struct pipe_mpeg12_picture_desc mpeg12;
@@ -545,7 +545,7 @@ vlVdpDecoderRender(VdpDecoder decoder,
ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info);
break;
case PIPE_VIDEO_CODEC_VP8:
- ret= vlVdpDecoderRenderVP8(&desc.vp8, (VdpPictureInfoVP8 *)picture_info);
+ ret = vlVdpDecoderRenderVP8(&desc.vp8, (VdpPictureInfoVP8 *)picture_info);
break;
default:
pipe_mutex_unlock(vlsurf->device->mutex);
@@ -557,6 +557,43 @@ vlVdpDecoderRender(VdpDecoder decoder,
return ret;
}
+ // Cleanup start_code (mandatory for some codec) from bitstream buffers
+ if (u_reduce_video_profile(dec->profile) == PIPE_VIDEO_CODEC_MPEG4_AVC ||
+ u_reduce_video_profile(dec->profile) == PIPE_VIDEO_CODEC_VP8) {
+ int start_code_found = 0;
+
+ for (i = 0, j = 0; i < bitstream_buffer_count; ++i) {
+ if (!start_code_found) {
+ const uint8_t *datab = (const uint8_t *)bitstream_buffers[i].bitstream;
+
+ if ((datab[0] == 0x9D && datab[1] == 0x01 && datab[2] == 0x2A) ||
+ (datab[0] == 0x00 && datab[1] == 0x00 && datab[2] == 0x01)) {
+ start_code_found = 1;
+
+ if (bitstream_buffers[i].bitstream_bytes != 3) {
+ buffers[j] = bitstream_buffers[i].bitstream + 3;
+ sizes[j] = bitstream_buffers[i].bitstream_bytes - 3;
+ j++;
+ }
+ } else {
+ VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Error : the first data buffer does not contain the mandatory start_code [0x9D012A]\n");
+ return VDP_STATUS_ERROR;
+ }
+ } else {
+ buffers[j] = bitstream_buffers[i].bitstream;
+ sizes[j] = bitstream_buffers[i].bitstream_bytes;
+ j++;
+ }
+ }
+
+ bitstream_buffer_count = j;
+ } else {
+ for (i = 0; i < bitstream_buffer_count; ++i) {
+ buffers[i] = bitstream_buffers[i].bitstream;
+ sizes[i] = bitstream_buffers[i].bitstream_bytes;
+ }
+ }
+
dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
dec->end_frame(dec, vlsurf->video_buffer, &desc.base);