Am Montag, den 29.08.2011, 23:29 +0100 schrieb Andy Furniss:
> Ironically your question made me search to see if I had any other mpeg2 
> HD not from w6rz - I found one and it has issues with -vf ffmpeg12vdpau :-)
Looks like there is some garbage at the end of the stream, mplayer is
also complaining nicely about "TS_PARSE: COULDN'T SYNC".

> I've never tested with this before so don't know if it's a regression, 
> it renders OK but hangs at the end and then may or may not segfault.
> 
> If it doesn't segfault then ddd will show it looping round int the same 
> function as shown in my screenshot, which shows the bt and value of 
> num_skipped_macroblocks.
I can't reproduce the crash, maybe my version of mplayer isn't feeding
the garbage to the decoder any more. Anyway attached is a patch that
adds some extra checks to the macroblock decoding, please give it a try.

Christian.
>From 54c9b1e526a2f1cef29f270fa2ea75634d03277f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <deathsim...@vodafone.de>
Date: Thu, 1 Sep 2011 16:24:33 +0200
Subject: [PATCH] g3dvl: check macroblock x,y for validity

---
 src/gallium/auxiliary/vl/vl_mpeg12_decoder.c |    7 +++++++
 src/gallium/auxiliary/vl/vl_mpeg12_decoder.h |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index 9ea84dc..0fa187d 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -640,6 +640,8 @@ vl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder,
 
    for (; num_macroblocks > 0; --num_macroblocks) {
       unsigned mb_addr = mb->y * dec->width_in_macroblocks + mb->x;
+      if (mb->x >= dec->width_in_macroblocks || mb_addr >= dec->macroblocks_in_frame)
+         return; /* x,y out of frame size */
 
       if (mb->macroblock_type & (PIPE_MPEG12_MB_TYPE_PATTERN | PIPE_MPEG12_MB_TYPE_INTRA))
          UploadYcbcrBlocks(dec, buf, mb);
@@ -676,6 +678,9 @@ vl_mpeg12_decode_macroblock(struct pipe_video_decoder *decoder,
 
          ++mb_addr;
          for (i = 0; i < mb->num_skipped_macroblocks; ++i, ++mb_addr) {
+            if (mb_addr >= dec->macroblocks_in_frame)
+               break;
+
             for (j = 0; j < 2; ++j) {
                if (!dec->ref_frames[j][0]) continue;
                buf->mv_stream[j][mb_addr] = skipped_mv[j];
@@ -1072,6 +1077,8 @@ vl_create_mpeg12_decoder(struct pipe_context *context,
    dec->blocks_per_line = MAX2(util_next_power_of_two(dec->base.width) / block_size_pixels, 4);
    dec->num_blocks = (dec->base.width * dec->base.height) / block_size_pixels;
    dec->width_in_macroblocks = align(dec->base.width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
+   dec->macroblocks_in_frame = align(dec->base.height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
+   dec->macroblocks_in_frame *= dec->width_in_macroblocks;
 
    /* TODO: Implement 422, 444 */
    assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
index 5f048f0..6ebe1b3 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
@@ -50,6 +50,7 @@ struct vl_mpeg12_decoder
    unsigned blocks_per_line;
    unsigned num_blocks;
    unsigned width_in_macroblocks;
+   unsigned macroblocks_in_frame;
 
    enum pipe_format zscan_source_format;
 
-- 
1.7.4.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to