From d0e203f1f00b0f760acc7fab07cd7ce8cca34000 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thomas=20Balling=20S=C3=B8rensen?= Date: Wed, 6 Oct 2010 00:19:53 +0200 Subject: [PATCH] vl: initial commit of the bitstream parser --- src/gallium/state_trackers/vdpau/decode.c | 14 +++- .../vdpau/mpeg2_bitstream_parser.c | 83 +++++++++++++++++-- .../vdpau/mpeg2_bitstream_parser.h | 21 ++++- .../state_trackers/xorg/xvmc/subpicture.c | 2 +- 4 files changed, 108 insertions(+), 12 deletions(-) diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c index 3e7cb4a3cab..03764a7f33d 100644 --- a/src/gallium/state_trackers/vdpau/decode.c +++ b/src/gallium/state_trackers/vdpau/decode.c @@ -211,11 +211,19 @@ vlVdpDecoderRenderMpeg2 (vlVdpDecoder *vldecoder, ret = vlVdpCreateSurfaceTarget(vldecoder,t_vdp_surf); - vlVdpBitstreamToMacroblock(vpipe->screen, bitstream_buffers, - &num_macroblocks, &pipe_macroblocks); + if (vlVdpMPEG2BitstreamToMacroblock(vpipe->screen, bitstream_buffers, bitstream_buffer_count, + &num_macroblocks, &pipe_macroblocks)) + { + debug_printf("[VDPAU] Error in frame-header. Skipping.\n"); + + ret = VDP_STATUS_OK; + goto skip_frame; + } vpipe->set_decode_target(vpipe,t_surf); - vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks, pipe_macroblocks, NULL); + vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks, (struct pipe_macroblock *)pipe_macroblocks, NULL); + + skip_frame: return ret; } diff --git a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c index 39019660edd..d88afb495f7 100644 --- a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c +++ b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c @@ -27,18 +27,89 @@ #include "mpeg2_bitstream_parser.h" -void -vlVdpBitstreamToMacroblock ( +int +vlVdpMPEG2NextStartCode(struct vdpMPEG2BitstreamParser *parser) +{ + uint32_t integer = 0; + uint32_t bytes_to_end; + + /* Move cursor to the start of a byte */ + while(parser->cursor % 8) + parser->cursor++; + + bytes_to_end = parser->cur_bitstream_length - parser->cursor/8 - 1; + + /* Read byte after byte, until startcode is found */ + while(integer != 0x00000100) + { + if (bytes_to_end < 0) + { + parser->state = MPEG2_HEADER_DONE; + return 1; + } + + integer << 8; + integer = integer & (unsigned char)(parser->ptr_bitstream + parser->cursor/8)[0]; + + bytes_to_end--; + parser->cursor += 8; + + } + + /* start_code found. rewind cursor a byte */ + parser->cursor -= 8; + + return 0; +} + +int +vlVdpMPEG2BitstreamToMacroblock ( struct pipe_screen *screen, VdpBitstreamBuffer const *bitstream_buffers, + uint32_t bitstream_buffer_count, unsigned int *num_macroblocks, struct pipe_mpeg12_macroblock **pipe_macroblocks) { - debug_printf("[VDPAU] BitstreamToMacroblock not implemented yet"); - assert(0); - + bool b_header_done = false; + struct vdpMPEG2BitstreamParser parser; + + num_macroblocks[0] = 0; + + memset(&parser,0,sizeof(parser)); + parser.state = MPEG2_HEADER_START_CODE; + parser.cur_bitstream_length = bitstream_buffers[0].bitstream_bytes; + parser.ptr_bitstream = (unsigned char *)bitstream_buffers[0].bitstream; + + /* Main header parser loop */ + while(!b_header_done) + { + switch (parser.state) + { + case MPEG2_HEADER_START_CODE: + if (vlVdpMPEG2NextStartCode(&parser)) + continue; + + /* Start_code found */ + switch ((parser.ptr_bitstream + parser.cursor/8)[0]) + { + /* sequence_header_code */ + case 0xB3: + debug_printf("[VDPAU][Bitstream parser] Sequence header code found at cursor pos: %d\n", parser.cursor); + exit(1); + break; + } + + break; + case MPEG2_HEADER_DONE: + debug_printf("[VDPAU][Bitstream parser] Done parsing current header\n"); + break; + + } + + + } - return; + return 0; } diff --git a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h index 534503df53f..74a216a4d81 100644 --- a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h +++ b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h @@ -32,10 +32,27 @@ #include #include "vdpau_private.h" -void -vlVdpBitstreamToMacroblock(struct pipe_screen *screen, +enum vdpMPEG2States +{ + MPEG2_HEADER_START_CODE, + MPEG2_HEADER_DONE +}; + +struct vdpMPEG2BitstreamParser +{ + enum vdpMPEG2States state; + uint32_t cursor; // current bit cursor + uint32_t cur_bitstream; + uint32_t cur_bitstream_length; + unsigned char *ptr_bitstream; +}; + +int +vlVdpMPEG2BitstreamToMacroblock(struct pipe_screen *screen, VdpBitstreamBuffer const *bitstream_buffers, + uint32_t bitstream_buffer_count, unsigned int *num_macroblocks, struct pipe_mpeg12_macroblock **pipe_macroblocks); + #endif // MPEG2_BITSTREAM_PARSER_H diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c index 4f6c80d4bee..7e82cd17288 100644 --- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c +++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c @@ -219,7 +219,7 @@ Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, sh if (!subpicture) return XvMCBadSubpicture; - /* Convert color to */ + /* Convert color to float */ util_format_read_4f(PIPE_FORMAT_B8G8R8A8_UNORM, color_f, 1, &color, 4, -- 2.30.2