summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-06-26 11:40:47 +0200
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-06-26 11:40:47 +0200
commit9aebad618c0aab527a0b838ce0a79ffa6dd426bb (patch)
treea27412af905ef21e2234ff58c1746608dfdb25b2 /src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
parent95c21f12f321bb33ae8e1f1b255680ac8eeffade (diff)
vl/mpeg12: handle mpeg-1 bitstreams more correctly
Add support for D-frames. Add support for slices ending on a different horizontal row of macroblocks.
Diffstat (limited to 'src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c')
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
index b0fb1bb04ec..81199e433b5 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
@@ -729,6 +729,7 @@ decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)
vl_vlc_eatbits(&bs->vlc, entry->length);
if (entry->run == dct_End_of_Block) {
+next_d:
dst += 64;
cbp <<= 1;
cbp &= 0x3F;
@@ -760,6 +761,8 @@ entry:
dst[0] = bs->pred_dc[cc];
i = 0;
+ if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)
+ goto next_d;
} else {
entry = tbl_B14_DC + vl_vlc_peekbits(&bs->vlc, 17);
i = -1;
@@ -797,6 +800,9 @@ entry:
vl_vlc_fillbits(&bs->vlc);
entry = table + vl_vlc_peekbits(&bs->vlc, 17);
}
+
+ if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)
+ vl_vlc_eatbits(&bs->vlc, 1);
}
static INLINE void
@@ -821,7 +827,7 @@ decode_slice(struct vl_mpg12_bs *bs, struct pipe_video_buffer *target)
vl_vlc_fillbits(&bs->vlc);
vl_vlc_fillbits(&bs->vlc);
- assert(vl_vlc_bits_left(&bs->vlc) > 23 && vl_vlc_peekbits(&bs->vlc, 23));
+ assert(vl_vlc_peekbits(&bs->vlc, 23));
do {
int inc = 0;
@@ -849,6 +855,11 @@ decode_slice(struct vl_mpg12_bs *bs, struct pipe_video_buffer *target)
bs->decoder->decode_macroblock(bs->decoder, target, &bs->desc->base, &mb.base, 1);
}
mb.x = x += inc;
+ if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1) {
+ int width = align(bs->decoder->width, 16) / 16;
+ mb.y += mb.x / width;
+ mb.x = x %= width;
+ }
switch (bs->desc->picture_coding_type) {
case PIPE_MPEG12_PICTURE_CODING_TYPE_I:
@@ -863,10 +874,10 @@ decode_slice(struct vl_mpg12_bs *bs, struct pipe_video_buffer *target)
mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B4, 6);
break;
- default:
- mb.macroblock_type = 0;
- /* dumb gcc */
- assert(0);
+ case PIPE_MPEG12_PICTURE_CODING_TYPE_D:
+ vl_vlc_eatbits(&bs->vlc, 1);
+ mb.macroblock_type = PIPE_MPEG12_MB_TYPE_INTRA;
+ break;
}
mb.macroblock_modes.value = 0;