diff options
author | Emeric Grange <emeric.grange@gmail.com> | 2012-02-13 22:19:42 +0100 |
---|---|---|
committer | Emeric Grange <emeric.grange@gmail.com> | 2012-06-24 16:57:33 +0200 |
commit | 380c3784dac99d8ef46e60ba3ec8c7104cd0813a (patch) | |
tree | 16773651f251cd18e83548e8ad0bb2d5b6efeb9e | |
parent | e5d2739f86010e7213c223ba4b482bf0c6221f8e (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.c | 142 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_vp8_decoder.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vp8/vp8_decoder.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vp8/vp8_decoder.h | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/vdpau/decode.c | 41 |
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); |