[FFmpeg-cvslog] vmd: refactor the inner decode loop
Luca Barbato
git at videolan.org
Mon Jun 3 02:31:51 CEST 2013
ffmpeg | branch: release/1.1 | Luca Barbato <lu_zero at gentoo.org> | Tue May 28 22:09:59 2013 +0200| [5fed47b94f889b724b3214a0898aa6eac00ac575] | committer: Luca Barbato
vmd: refactor the inner decode loop
Simplify a little, assume empty frames are acceptable and
do not pointlessly reinit the bytestream2 contexts using
possibly wrong size values.
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable at libav.org
(cherry picked from commit 676da248cad49debc40720baa13214f0b94dcc71)
Signed-off-by: Luca Barbato <lu_zero at gentoo.org>
Conflicts:
libavcodec/vmdav.c
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5fed47b94f889b724b3214a0898aa6eac00ac575
---
libavcodec/vmdav.c | 160 +++++++++++++++++++++++++++-------------------------
1 file changed, 82 insertions(+), 78 deletions(-)
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index 49ad20c..d4ac6f7 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -269,91 +269,95 @@ static int vmd_decode(VmdVideoContext *s)
}
s->size -= PALETTE_COUNT * 3 + 2;
}
- if (s->size > 0) {
- /* originally UnpackFrame in VAG's code */
- bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer);
- if (bytestream2_get_bytes_left(&gb) < 1)
- return AVERROR_INVALIDDATA;
- meth = bytestream2_get_byteu(&gb);
- if (meth & 0x80) {
- lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
- s->unpack_buffer, s->unpack_buffer_size);
- meth &= 0x7F;
- bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
- }
- dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
- pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
- switch (meth) {
- case 1:
- for (i = 0; i < frame_height; i++) {
- ofs = 0;
- do {
- len = bytestream2_get_byte(&gb);
- if (len & 0x80) {
- len = (len & 0x7F) + 1;
- if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len)
- return AVERROR_INVALIDDATA;
- bytestream2_get_buffer(&gb, &dp[ofs], len);
- ofs += len;
- } else {
- /* interframe pixel copy */
- if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
- return AVERROR_INVALIDDATA;
- memcpy(&dp[ofs], &pp[ofs], len + 1);
- ofs += len + 1;
- }
- } while (ofs < frame_width);
- if (ofs > frame_width) {
- av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
- ofs, frame_width);
- return AVERROR_INVALIDDATA;
- }
- dp += s->frame.linesize[0];
- pp += s->prev_frame.linesize[0];
- }
- break;
+ if (!s->size)
+ return 0;
+
+ /* originally UnpackFrame in VAG's code */
+ if (bytestream2_get_bytes_left(&gb) < 1)
+ return AVERROR_INVALIDDATA;
+ meth = bytestream2_get_byteu(&gb);
+ if (meth & 0x80) {
+ lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
+ s->unpack_buffer, s->unpack_buffer_size);
+ meth &= 0x7F;
+ bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
+ }
- case 2:
- for (i = 0; i < frame_height; i++) {
- bytestream2_get_buffer(&gb, dp, frame_width);
- dp += s->frame.linesize[0];
- pp += s->prev_frame.linesize[0];
+ dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
+ pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
+ switch (meth) {
+ case 1:
+ for (i = 0; i < frame_height; i++) {
+ ofs = 0;
+ do {
+ len = bytestream2_get_byte(&gb);
+ if (len & 0x80) {
+ len = (len & 0x7F) + 1;
+ if (ofs + len > frame_width ||
+ bytestream2_get_bytes_left(&gb) < len)
+ return AVERROR_INVALIDDATA;
+ bytestream2_get_buffer(&gb, &dp[ofs], len);
+ ofs += len;
+ } else {
+ /* interframe pixel copy */
+ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+ return AVERROR_INVALIDDATA;
+ memcpy(&dp[ofs], &pp[ofs], len + 1);
+ ofs += len + 1;
+ }
+ } while (ofs < frame_width);
+ if (ofs > frame_width) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "VMD video: offset > width (%d > %d)\n",
+ ofs, frame_width);
+ return AVERROR_INVALIDDATA;
}
- break;
+ dp += s->frame.linesize[0];
+ pp += s->prev_frame.linesize[0];
+ }
+ break;
- case 3:
- for (i = 0; i < frame_height; i++) {
- ofs = 0;
- do {
- len = bytestream2_get_byte(&gb);
- if (len & 0x80) {
- len = (len & 0x7F) + 1;
- if (bytestream2_get_byte(&gb) == 0xFF)
- len = rle_unpack(gb.buffer, &dp[ofs],
- len, bytestream2_get_bytes_left(&gb),
- frame_width - ofs);
- else
- bytestream2_get_buffer(&gb, &dp[ofs], len);
- bytestream2_skip(&gb, len);
- } else {
- /* interframe pixel copy */
- if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
- return AVERROR_INVALIDDATA;
- memcpy(&dp[ofs], &pp[ofs], len + 1);
- ofs += len + 1;
- }
- } while (ofs < frame_width);
- if (ofs > frame_width) {
- av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
- ofs, frame_width);
- return AVERROR_INVALIDDATA;
+ case 2:
+ for (i = 0; i < frame_height; i++) {
+ bytestream2_get_buffer(&gb, dp, frame_width);
+ dp += s->frame.linesize[0];
+ pp += s->prev_frame.linesize[0];
+ }
+ break;
+
+ case 3:
+ for (i = 0; i < frame_height; i++) {
+ ofs = 0;
+ do {
+ len = bytestream2_get_byte(&gb);
+ if (len & 0x80) {
+ len = (len & 0x7F) + 1;
+ if (bytestream2_get_byte(&gb) == 0xFF)
+ len = rle_unpack(gb.buffer, &dp[ofs],
+ len, bytestream2_get_bytes_left(&gb),
+ frame_width - ofs);
+ else
+ bytestream2_get_buffer(&gb, &dp[ofs], len);
+ bytestream2_skip(&gb, len);
+ } else {
+ /* interframe pixel copy */
+ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+ return AVERROR_INVALIDDATA;
+ memcpy(&dp[ofs], &pp[ofs], len + 1);
+ ofs += len + 1;
}
- dp += s->frame.linesize[0];
- pp += s->prev_frame.linesize[0];
+ } while (ofs < frame_width);
+ if (ofs > frame_width) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "VMD video: offset > width (%d > %d)\n",
+ ofs, frame_width);
+ return AVERROR_INVALIDDATA;
}
- break;
+ dp += s->frame.linesize[0];
+ pp += s->prev_frame.linesize[0];
}
+ break;
}
return 0;
}
More information about the ffmpeg-cvslog
mailing list