Merge remote-tracking branch 'qatar/master'

* qatar/master:
  x86: dsputil: prettyprint gcc inline asm
  x86: K&R prettyprinting cosmetics for dsputil_mmx.c
  x86: conditionally compile H.264 QPEL optimizations
  dsputil_mmx: Surround QPEL macros by "do { } while (0);" blocks.
  Ignore generated files below doc/.
  dpcm: convert to bytestream2.
  interplayvideo: convert to bytestream2.
  movenc: Merge if statements
  h264: fix memleak in error path.
  pthread: Immediately release all frames in ff_thread_flush()
  h264: Add check for invalid chroma_format_idc
  utvideo: port header reading to bytestream2.

Conflicts:
	.gitignore
	configure
	libavcodec/h264_ps.c
	libavcodec/interplayvideo.c
	libavcodec/pthread.c
	libavcodec/x86/dsputil_mmx.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-03-25 23:10:30 +02:00
commit 9621646eb3
10 changed files with 2448 additions and 2211 deletions

3
.gitignore vendored
View File

@ -22,6 +22,9 @@ ffplay
ffprobe ffprobe
ffserver ffserver
avconv avconv
doc/avoptions_codec.texi
doc/avoptions_format.texi
doc/print_options
libavcodec/*_tablegen libavcodec/*_tablegen
libavcodec/*_tables.c libavcodec/*_tables.c
libavcodec/*_tables.h libavcodec/*_tables.h

15
configure vendored
View File

@ -1266,6 +1266,7 @@ CONFIG_EXTRA="
h264chroma h264chroma
h264dsp h264dsp
h264pred h264pred
h264qpel
huffman huffman
lgplv3 lgplv3
lpc lpc
@ -1424,7 +1425,7 @@ h263_vaapi_hwaccel_select="vaapi h263_decoder"
h263i_decoder_select="h263_decoder" h263i_decoder_select="h263_decoder"
h263p_encoder_select="h263_encoder" h263p_encoder_select="h263_encoder"
h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser" h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
h264_decoder_select="golomb h264chroma h264dsp h264pred" h264_decoder_select="golomb h264chroma h264dsp h264pred h264qpel"
h264_dxva2_hwaccel_deps="dxva2api_h" h264_dxva2_hwaccel_deps="dxva2api_h"
h264_dxva2_hwaccel_select="dxva2 h264_decoder" h264_dxva2_hwaccel_select="dxva2 h264_decoder"
h264_vaapi_hwaccel_select="vaapi h264_decoder" h264_vaapi_hwaccel_select="vaapi h264_decoder"
@ -1485,8 +1486,8 @@ rv10_decoder_select="h263_decoder"
rv10_encoder_select="h263_encoder" rv10_encoder_select="h263_encoder"
rv20_decoder_select="h263_decoder" rv20_decoder_select="h263_decoder"
rv20_encoder_select="h263_encoder" rv20_encoder_select="h263_encoder"
rv30_decoder_select="golomb h264chroma h264pred" rv30_decoder_select="golomb h264chroma h264pred h264qpel"
rv40_decoder_select="golomb h264chroma h264pred" rv40_decoder_select="golomb h264chroma h264pred h264qpel"
shorten_decoder_select="golomb" shorten_decoder_select="golomb"
sipr_decoder_select="lsp" sipr_decoder_select="lsp"
snow_decoder_select="dwt" snow_decoder_select="dwt"
@ -1495,7 +1496,7 @@ sonic_decoder_select="golomb"
sonic_encoder_select="golomb" sonic_encoder_select="golomb"
sonic_ls_encoder_select="golomb" sonic_ls_encoder_select="golomb"
svq1_encoder_select="aandct" svq1_encoder_select="aandct"
svq3_decoder_select="golomb h264chroma h264dsp h264pred" svq3_decoder_select="golomb h264chroma h264dsp h264pred h264qpel"
svq3_decoder_suggest="zlib" svq3_decoder_suggest="zlib"
theora_decoder_select="vp3_decoder" theora_decoder_select="vp3_decoder"
tiff_decoder_suggest="zlib" tiff_decoder_suggest="zlib"
@ -1504,7 +1505,7 @@ truehd_decoder_select="mlp_decoder"
tscc_decoder_select="zlib" tscc_decoder_select="zlib"
twinvq_decoder_select="mdct lsp sinewin" twinvq_decoder_select="mdct lsp sinewin"
vc1_crystalhd_decoder_select="crystalhd" vc1_crystalhd_decoder_select="crystalhd"
vc1_decoder_select="h263_decoder h264chroma" vc1_decoder_select="h263_decoder h264chroma h264qpel"
vc1_dxva2_hwaccel_deps="dxva2api_h" vc1_dxva2_hwaccel_deps="dxva2api_h"
vc1_dxva2_hwaccel_select="dxva2 vc1_decoder" vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
vc1_vaapi_hwaccel_select="vaapi vc1_decoder" vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
@ -1515,7 +1516,7 @@ vorbis_encoder_select="mdct"
vp6_decoder_select="huffman" vp6_decoder_select="huffman"
vp6a_decoder_select="vp6_decoder" vp6a_decoder_select="vp6_decoder"
vp6f_decoder_select="vp6_decoder" vp6f_decoder_select="vp6_decoder"
vp8_decoder_select="h264pred" vp8_decoder_select="h264pred h264qpel"
wmapro_decoder_select="mdct sinewin" wmapro_decoder_select="mdct sinewin"
wmav1_decoder_select="mdct sinewin" wmav1_decoder_select="mdct sinewin"
wmav1_encoder_select="mdct sinewin" wmav1_encoder_select="mdct sinewin"
@ -1544,7 +1545,7 @@ vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h" vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
# parsers # parsers
h264_parser_select="golomb h264chroma h264dsp h264pred" h264_parser_select="golomb h264chroma h264dsp h264pred h264qpel"
# external libraries # external libraries
libaacplus_encoder_deps="libaacplus" libaacplus_encoder_deps="libaacplus"

View File

@ -40,6 +40,7 @@
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
#include "mathops.h"
typedef struct DPCMContext { typedef struct DPCMContext {
AVFrame frame; AVFrame frame;
@ -173,20 +174,18 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt) int *got_frame_ptr, AVPacket *avpkt)
{ {
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size; int buf_size = avpkt->size;
const uint8_t *buf_end = buf + buf_size;
DPCMContext *s = avctx->priv_data; DPCMContext *s = avctx->priv_data;
int out = 0, ret; int out = 0, ret;
int predictor[2]; int predictor[2];
int ch = 0; int ch = 0;
int stereo = s->channels - 1; int stereo = s->channels - 1;
int16_t *output_samples; int16_t *output_samples, *samples_end;
GetByteContext gb;
if (stereo && (buf_size & 1)) { if (stereo && (buf_size & 1))
buf_size--; buf_size--;
buf_end--; bytestream2_init(&gb, avpkt->data, buf_size);
}
/* calculate output size */ /* calculate output size */
switch(avctx->codec->id) { switch(avctx->codec->id) {
@ -221,22 +220,23 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
return ret; return ret;
} }
output_samples = (int16_t *)s->frame.data[0]; output_samples = (int16_t *)s->frame.data[0];
samples_end = output_samples + out;
switch(avctx->codec->id) { switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM: case CODEC_ID_ROQ_DPCM:
buf += 6; bytestream2_skipu(&gb, 6);
if (stereo) { if (stereo) {
predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8); predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8); predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
} else { } else {
predictor[0] = (int16_t)bytestream_get_le16(&buf); predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16);
} }
/* decode the samples */ /* decode the samples */
while (buf < buf_end) { while (output_samples < samples_end) {
predictor[ch] += s->roq_square_array[*buf++]; predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)];
predictor[ch] = av_clip_int16(predictor[ch]); predictor[ch] = av_clip_int16(predictor[ch]);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
@ -246,16 +246,16 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
break; break;
case CODEC_ID_INTERPLAY_DPCM: case CODEC_ID_INTERPLAY_DPCM:
buf += 6; /* skip over the stream mask and stream length */ bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */
for (ch = 0; ch < s->channels; ch++) { for (ch = 0; ch < s->channels; ch++) {
predictor[ch] = (int16_t)bytestream_get_le16(&buf); predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
} }
ch = 0; ch = 0;
while (buf < buf_end) { while (output_samples < samples_end) {
predictor[ch] += interplay_delta_table[*buf++]; predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)];
predictor[ch] = av_clip_int16(predictor[ch]); predictor[ch] = av_clip_int16(predictor[ch]);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
@ -269,16 +269,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
int shift[2] = { 4, 4 }; int shift[2] = { 4, 4 };
for (ch = 0; ch < s->channels; ch++) for (ch = 0; ch < s->channels; ch++)
predictor[ch] = (int16_t)bytestream_get_le16(&buf); predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
ch = 0; ch = 0;
while (buf < buf_end) { while (output_samples < samples_end) {
uint8_t n = *buf++; int diff = bytestream2_get_byteu(&gb);
int16_t diff = (n & 0xFC) << 8; int n = diff & 3;
if ((n & 0x03) == 3)
if (n == 3)
shift[ch]++; shift[ch]++;
else else
shift[ch] -= (2 * (n & 3)); shift[ch] -= (2 * n);
diff = sign_extend((diff &~ 3) << 8, 16);
/* saturate the shifter to a lower limit of 0 */ /* saturate the shifter to a lower limit of 0 */
if (shift[ch] < 0) if (shift[ch] < 0)
shift[ch] = 0; shift[ch] = 0;
@ -296,9 +299,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
} }
case CODEC_ID_SOL_DPCM: case CODEC_ID_SOL_DPCM:
if (avctx->codec_tag != 3) { if (avctx->codec_tag != 3) {
uint8_t *output_samples_u8 = s->frame.data[0]; uint8_t *output_samples_u8 = s->frame.data[0],
while (buf < buf_end) { *samples_end_u8 = output_samples_u8 + out;
uint8_t n = *buf++; while (output_samples_u8 < samples_end_u8) {
int n = bytestream2_get_byteu(&gb);
s->sample[0] += s->sol_table[n >> 4]; s->sample[0] += s->sol_table[n >> 4];
s->sample[0] = av_clip_uint8(s->sample[0]); s->sample[0] = av_clip_uint8(s->sample[0]);
@ -309,8 +313,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
*output_samples_u8++ = s->sample[stereo]; *output_samples_u8++ = s->sample[stereo];
} }
} else { } else {
while (buf < buf_end) { while (output_samples < samples_end) {
uint8_t n = *buf++; int n = bytestream2_get_byteu(&gb);
if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F]; if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
else s->sample[ch] += sol_table_16[n & 0x7F]; else s->sample[ch] += sol_table_16[n & 0x7F];
s->sample[ch] = av_clip_int16(s->sample[ch]); s->sample[ch] = av_clip_int16(s->sample[ch]);

View File

@ -352,9 +352,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
if (sps->chroma_format_idc > 3U) { if (sps->chroma_format_idc > 3U) {
av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc);
goto fail; goto fail;
} } else if(sps->chroma_format_idc == 3) {
if(sps->chroma_format_idc == 3)
sps->residual_color_transform_flag = get_bits1(&s->gb); sps->residual_color_transform_flag = get_bits1(&s->gb);
}
sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8;
sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) {

View File

@ -56,14 +56,8 @@ typedef struct IpvideoContext {
const unsigned char *decoding_map; const unsigned char *decoding_map;
int decoding_map_size; int decoding_map_size;
const unsigned char *buf;
int size;
int is_16bpp; int is_16bpp;
const unsigned char *stream_ptr; GetByteContext stream_ptr, mv_ptr;
const unsigned char *stream_end;
const uint8_t *mv_ptr;
const uint8_t *mv_end;
unsigned char *pixel_ptr; unsigned char *pixel_ptr;
int line_inc; int line_inc;
int stride; int stride;
@ -72,13 +66,6 @@ typedef struct IpvideoContext {
uint32_t pal[256]; uint32_t pal[256];
} IpvideoContext; } IpvideoContext;
#define CHECK_STREAM_PTR(stream_ptr, stream_end, n) \
if (stream_end - stream_ptr < n) { \
av_log(s->avctx, AV_LOG_ERROR, "stream_ptr out of bounds (%p >= %p)\n", \
stream_ptr + n, stream_end); \
return -1; \
}
static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y) static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
{ {
int current_offset = s->pixel_ptr - s->current_frame.data[0]; int current_offset = s->pixel_ptr - s->current_frame.data[0];
@ -118,11 +105,9 @@ static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
/* copy block from 2 frames ago using a motion vector; need 1 more byte */ /* copy block from 2 frames ago using a motion vector; need 1 more byte */
if (!s->is_16bpp) { if (!s->is_16bpp) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); B = bytestream2_get_byte(&s->stream_ptr);
B = *s->stream_ptr++;
} else { } else {
CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); B = bytestream2_get_byte(&s->mv_ptr);
B = *s->mv_ptr++;
} }
if (B < 56) { if (B < 56) {
@ -146,11 +131,9 @@ static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
/* need 1 more byte for motion */ /* need 1 more byte for motion */
if (!s->is_16bpp) { if (!s->is_16bpp) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); B = bytestream2_get_byte(&s->stream_ptr);
B = *s->stream_ptr++;
} else { } else {
CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); B = bytestream2_get_byte(&s->mv_ptr);
B = *s->mv_ptr++;
} }
if (B < 56) { if (B < 56) {
@ -172,11 +155,9 @@ static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
/* copy a block from the previous frame; need 1 more byte */ /* copy a block from the previous frame; need 1 more byte */
if (!s->is_16bpp) { if (!s->is_16bpp) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); B = bytestream2_get_byte(&s->stream_ptr);
B = *s->stream_ptr++;
} else { } else {
CHECK_STREAM_PTR(s->mv_ptr, s->mv_end, 1); B = bytestream2_get_byte(&s->mv_ptr);
B = *s->mv_ptr++;
} }
BL = B & 0x0F; BL = B & 0x0F;
@ -194,10 +175,8 @@ static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
/* copy a block from the previous frame using an expanded range; /* copy a block from the previous frame using an expanded range;
* need 2 more bytes */ * need 2 more bytes */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); x = bytestream2_get_byte(&s->stream_ptr);
y = bytestream2_get_byte(&s->stream_ptr);
x = *s->stream_ptr++;
y = *s->stream_ptr++;
av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y); av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
return copy_from(s, &s->last_frame, x, y); return copy_from(s, &s->last_frame, x, y);
@ -219,18 +198,14 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
unsigned int flags; unsigned int flags;
/* 2-color encoding */ /* 2-color encoding */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); P[0] = bytestream2_get_byte(&s->stream_ptr);
P[1] = bytestream2_get_byte(&s->stream_ptr);
P[0] = *s->stream_ptr++;
P[1] = *s->stream_ptr++;
if (P[0] <= P[1]) { if (P[0] <= P[1]) {
/* need 8 more bytes from the stream */ /* need 8 more bytes from the stream */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
flags = *s->stream_ptr++ | 0x100; flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
for (; flags != 1; flags >>= 1) for (; flags != 1; flags >>= 1)
*s->pixel_ptr++ = P[flags & 1]; *s->pixel_ptr++ = P[flags & 1];
s->pixel_ptr += s->line_inc; s->pixel_ptr += s->line_inc;
@ -239,9 +214,7 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
} else { } else {
/* need 2 more bytes from the stream */ /* need 2 more bytes from the stream */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); flags = bytestream2_get_le16(&s->stream_ptr);
flags = bytestream_get_le16(&s->stream_ptr);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2, flags >>= 1) { for (x = 0; x < 8; x += 2, flags >>= 1) {
s->pixel_ptr[x ] = s->pixel_ptr[x ] =
@ -260,26 +233,23 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s) static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
{ {
int x, y; int x, y;
unsigned char P[2]; unsigned char P[4];
unsigned int flags = 0; unsigned int flags = 0;
/* 2-color encoding for each 4x4 quadrant, or 2-color encoding on /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
* either top and bottom or left and right halves */ * either top and bottom or left and right halves */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); P[0] = bytestream2_get_byte(&s->stream_ptr);
P[1] = bytestream2_get_byte(&s->stream_ptr);
P[0] = *s->stream_ptr++;
P[1] = *s->stream_ptr++;
if (P[0] <= P[1]) { if (P[0] <= P[1]) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 14);
s->stream_ptr -= 2;
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// new values for each 4x4 block // new values for each 4x4 block
if (!(y & 3)) { if (!(y & 3)) {
P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++; if (y) {
flags = bytestream_get_le16(&s->stream_ptr); P[0] = bytestream2_get_byte(&s->stream_ptr);
P[1] = bytestream2_get_byte(&s->stream_ptr);
}
flags = bytestream2_get_le16(&s->stream_ptr);
} }
for (x = 0; x < 4; x++, flags >>= 1) for (x = 0; x < 4; x++, flags >>= 1)
@ -290,13 +260,11 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
} }
} else { } else {
flags = bytestream2_get_le32(&s->stream_ptr);
P[2] = bytestream2_get_byte(&s->stream_ptr);
P[3] = bytestream2_get_byte(&s->stream_ptr);
/* need 10 more bytes */ if (P[2] <= P[3]) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 10);
if (s->stream_ptr[4] <= s->stream_ptr[5]) {
flags = bytestream_get_le32(&s->stream_ptr);
/* vertical split; left & right halves are 2-color encoded */ /* vertical split; left & right halves are 2-color encoded */
@ -307,8 +275,9 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
// switch to right half // switch to right half
if (y == 7) { if (y == 7) {
s->pixel_ptr -= 8 * s->stride - 4; s->pixel_ptr -= 8 * s->stride - 4;
P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++; P[0] = P[2];
flags = bytestream_get_le32(&s->stream_ptr); P[1] = P[3];
flags = bytestream2_get_le32(&s->stream_ptr);
} }
} }
@ -318,12 +287,12 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
if (y == 4) { if (y == 4) {
P[0] = *s->stream_ptr++; P[0] = P[2];
P[1] = *s->stream_ptr++; P[1] = P[3];
flags = bytestream2_get_le32(&s->stream_ptr);
} }
flags = *s->stream_ptr++ | 0x100;
for (; flags != 1; flags >>= 1) for (x = 0; x < 8; x++, flags >>= 1)
*s->pixel_ptr++ = P[flags & 1]; *s->pixel_ptr++ = P[flags & 1];
s->pixel_ptr += s->line_inc; s->pixel_ptr += s->line_inc;
} }
@ -340,20 +309,15 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
unsigned char P[4]; unsigned char P[4];
/* 4-color encoding */ /* 4-color encoding */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); bytestream2_get_buffer(&s->stream_ptr, P, 4);
memcpy(P, s->stream_ptr, 4);
s->stream_ptr += 4;
if (P[0] <= P[1]) { if (P[0] <= P[1]) {
if (P[2] <= P[3]) { if (P[2] <= P[3]) {
/* 1 of 4 colors for each pixel, need 16 more bytes */ /* 1 of 4 colors for each pixel, need 16 more bytes */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
/* get the next set of 8 2-bit flags */ /* get the next set of 8 2-bit flags */
int flags = bytestream_get_le16(&s->stream_ptr); int flags = bytestream2_get_le16(&s->stream_ptr);
for (x = 0; x < 8; x++, flags >>= 2) for (x = 0; x < 8; x++, flags >>= 2)
*s->pixel_ptr++ = P[flags & 0x03]; *s->pixel_ptr++ = P[flags & 0x03];
s->pixel_ptr += s->line_inc; s->pixel_ptr += s->line_inc;
@ -363,9 +327,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
uint32_t flags; uint32_t flags;
/* 1 of 4 colors for each 2x2 block, need 4 more bytes */ /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); flags = bytestream2_get_le32(&s->stream_ptr);
flags = bytestream_get_le32(&s->stream_ptr);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2, flags >>= 2) { for (x = 0; x < 8; x += 2, flags >>= 2) {
@ -382,9 +344,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
uint64_t flags; uint64_t flags;
/* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */ /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); flags = bytestream2_get_le64(&s->stream_ptr);
flags = bytestream_get_le64(&s->stream_ptr);
if (P[2] <= P[3]) { if (P[2] <= P[3]) {
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x += 2, flags >>= 2) { for (x = 0; x < 8; x += 2, flags >>= 2) {
@ -411,24 +371,21 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s) static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
{ {
int x, y; int x, y;
unsigned char P[4]; unsigned char P[8];
int flags = 0; int flags = 0;
bytestream2_get_buffer(&s->stream_ptr, P, 4);
/* 4-color encoding for each 4x4 quadrant, or 4-color encoding on /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
* either top and bottom or left and right halves */ * either top and bottom or left and right halves */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24); if (P[0] <= P[1]) {
if (s->stream_ptr[0] <= s->stream_ptr[1]) {
/* 4-color encoding for each quadrant; need 32 bytes */ /* 4-color encoding for each quadrant; need 32 bytes */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32);
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// new values for each 4x4 block // new values for each 4x4 block
if (!(y & 3)) { if (!(y & 3)) {
memcpy(P, s->stream_ptr, 4); if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
s->stream_ptr += 4; flags = bytestream2_get_le32(&s->stream_ptr);
flags = bytestream_get_le32(&s->stream_ptr);
} }
for (x = 0; x < 4; x++, flags >>= 2) for (x = 0; x < 4; x++, flags >>= 2)
@ -441,20 +398,16 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
} else { } else {
// vertical split? // vertical split?
int vert = s->stream_ptr[12] <= s->stream_ptr[13]; int vert;
uint64_t flags = 0; uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
vert = P[4] <= P[5];
/* 4-color encoding for either left and right or top and bottom /* 4-color encoding for either left and right or top and bottom
* halves */ * halves */
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// load values for each half
if (!(y & 7)) {
memcpy(P, s->stream_ptr, 4);
s->stream_ptr += 4;
flags = bytestream_get_le64(&s->stream_ptr);
}
for (x = 0; x < 4; x++, flags >>= 2) for (x = 0; x < 4; x++, flags >>= 2)
*s->pixel_ptr++ = P[flags & 0x03]; *s->pixel_ptr++ = P[flags & 0x03];
@ -463,6 +416,12 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
// switch to right half // switch to right half
if (y == 7) s->pixel_ptr -= 8 * s->stride - 4; if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
} else if (y & 1) s->pixel_ptr += s->line_inc; } else if (y & 1) s->pixel_ptr += s->line_inc;
// load values for second half
if (y == 7) {
memcpy(P, P + 4, 4);
flags = bytestream2_get_le64(&s->stream_ptr);
}
} }
} }
@ -475,11 +434,8 @@ static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
int y; int y;
/* 64-color encoding (each pixel in block is a different color) */ /* 64-color encoding (each pixel in block is a different color) */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 64);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
memcpy(s->pixel_ptr, s->stream_ptr, 8); bytestream2_get_buffer(&s->stream_ptr, s->pixel_ptr, 8);
s->stream_ptr += 8;
s->pixel_ptr += s->stride; s->pixel_ptr += s->stride;
} }
@ -492,14 +448,12 @@ static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
int x, y; int x, y;
/* 16-color block encoding: each 2x2 block is a different color */ /* 16-color block encoding: each 2x2 block is a different color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2) { for (x = 0; x < 8; x += 2) {
s->pixel_ptr[x ] = s->pixel_ptr[x ] =
s->pixel_ptr[x + 1 ] = s->pixel_ptr[x + 1 ] =
s->pixel_ptr[x + s->stride] = s->pixel_ptr[x + s->stride] =
s->pixel_ptr[x + 1 + s->stride] = *s->stream_ptr++; s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
} }
s->pixel_ptr += s->stride * 2; s->pixel_ptr += s->stride * 2;
} }
@ -514,12 +468,10 @@ static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
unsigned char P[2]; unsigned char P[2];
/* 4-color block encoding: each 4x4 block is a different color */ /* 4-color block encoding: each 4x4 block is a different color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
if (!(y & 3)) { if (!(y & 3)) {
P[0] = *s->stream_ptr++; P[0] = bytestream2_get_byte(&s->stream_ptr);
P[1] = *s->stream_ptr++; P[1] = bytestream2_get_byte(&s->stream_ptr);
} }
memset(s->pixel_ptr, P[0], 4); memset(s->pixel_ptr, P[0], 4);
memset(s->pixel_ptr + 4, P[1], 4); memset(s->pixel_ptr + 4, P[1], 4);
@ -536,8 +488,7 @@ static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
unsigned char pix; unsigned char pix;
/* 1-color encoding: the whole block is 1 solid color */ /* 1-color encoding: the whole block is 1 solid color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 1); pix = bytestream2_get_byte(&s->stream_ptr);
pix = *s->stream_ptr++;
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
memset(s->pixel_ptr, pix, 8); memset(s->pixel_ptr, pix, 8);
@ -554,9 +505,8 @@ static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
unsigned char sample[2]; unsigned char sample[2];
/* dithered encoding */ /* dithered encoding */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); sample[0] = bytestream2_get_byte(&s->stream_ptr);
sample[0] = *s->stream_ptr++; sample[1] = bytestream2_get_byte(&s->stream_ptr);
sample[1] = *s->stream_ptr++;
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x += 2) { for (x = 0; x < 8; x += 2) {
@ -575,10 +525,8 @@ static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
signed char x, y; signed char x, y;
/* copy a block from the second last frame using an expanded range */ /* copy a block from the second last frame using an expanded range */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); x = bytestream2_get_byte(&s->stream_ptr);
y = bytestream2_get_byte(&s->stream_ptr);
x = *s->stream_ptr++;
y = *s->stream_ptr++;
av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y); av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
return copy_from(s, &s->second_last_frame, x, y); return copy_from(s, &s->second_last_frame, x, y);
@ -592,17 +540,13 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 2-color encoding */ /* 2-color encoding */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); P[0] = bytestream2_get_le16(&s->stream_ptr);
P[1] = bytestream2_get_le16(&s->stream_ptr);
P[0] = bytestream_get_le16(&s->stream_ptr);
P[1] = bytestream_get_le16(&s->stream_ptr);
if (!(P[0] & 0x8000)) { if (!(P[0] & 0x8000)) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
flags = *s->stream_ptr++ | 0x100; flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
for (; flags != 1; flags >>= 1) for (; flags != 1; flags >>= 1)
*pixel_ptr++ = P[flags & 1]; *pixel_ptr++ = P[flags & 1];
pixel_ptr += s->line_inc; pixel_ptr += s->line_inc;
@ -610,9 +554,7 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
} else { } else {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); flags = bytestream2_get_le16(&s->stream_ptr);
flags = bytestream_get_le16(&s->stream_ptr);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2, flags >>= 1) { for (x = 0; x < 8; x += 2, flags >>= 1) {
pixel_ptr[x ] = pixel_ptr[x ] =
@ -630,28 +572,25 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s) static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
{ {
int x, y; int x, y;
uint16_t P[2]; uint16_t P[4];
unsigned int flags = 0; unsigned int flags = 0;
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 2-color encoding for each 4x4 quadrant, or 2-color encoding on /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
* either top and bottom or left and right halves */ * either top and bottom or left and right halves */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); P[0] = bytestream2_get_le16(&s->stream_ptr);
P[1] = bytestream2_get_le16(&s->stream_ptr);
P[0] = bytestream_get_le16(&s->stream_ptr);
P[1] = bytestream_get_le16(&s->stream_ptr);
if (!(P[0] & 0x8000)) { if (!(P[0] & 0x8000)) {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24);
s->stream_ptr -= 4;
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// new values for each 4x4 block // new values for each 4x4 block
if (!(y & 3)) { if (!(y & 3)) {
P[0] = bytestream_get_le16(&s->stream_ptr); if (y) {
P[1] = bytestream_get_le16(&s->stream_ptr); P[0] = bytestream2_get_le16(&s->stream_ptr);
flags = bytestream_get_le16(&s->stream_ptr); P[1] = bytestream2_get_le16(&s->stream_ptr);
}
flags = bytestream2_get_le16(&s->stream_ptr);
} }
for (x = 0; x < 4; x++, flags >>= 1) for (x = 0; x < 4; x++, flags >>= 1)
@ -663,11 +602,11 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
} else { } else {
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 12); flags = bytestream2_get_le32(&s->stream_ptr);
P[2] = bytestream2_get_le16(&s->stream_ptr);
P[3] = bytestream2_get_le16(&s->stream_ptr);
if (!(AV_RL16(s->stream_ptr + 4) & 0x8000)) { if (!(P[2] & 0x8000)) {
flags = bytestream_get_le32(&s->stream_ptr);
/* vertical split; left & right halves are 2-color encoded */ /* vertical split; left & right halves are 2-color encoded */
@ -678,9 +617,9 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
// switch to right half // switch to right half
if (y == 7) { if (y == 7) {
pixel_ptr -= 8 * s->stride - 4; pixel_ptr -= 8 * s->stride - 4;
P[0] = bytestream_get_le16(&s->stream_ptr); P[0] = P[2];
P[1] = bytestream_get_le16(&s->stream_ptr); P[1] = P[3];
flags = bytestream_get_le32(&s->stream_ptr); flags = bytestream2_get_le32(&s->stream_ptr);
} }
} }
@ -690,12 +629,12 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
if (y == 4) { if (y == 4) {
P[0] = bytestream_get_le16(&s->stream_ptr); P[0] = P[2];
P[1] = bytestream_get_le16(&s->stream_ptr); P[1] = P[3];
flags = bytestream2_get_le32(&s->stream_ptr);
} }
flags = *s->stream_ptr++ | 0x100;
for (; flags != 1; flags >>= 1) for (x = 0; x < 8; x++, flags >>= 1)
*pixel_ptr++ = P[flags & 1]; *pixel_ptr++ = P[flags & 1];
pixel_ptr += s->line_inc; pixel_ptr += s->line_inc;
} }
@ -713,20 +652,16 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 4-color encoding */ /* 4-color encoding */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++)
P[x] = bytestream_get_le16(&s->stream_ptr); P[x] = bytestream2_get_le16(&s->stream_ptr);
if (!(P[0] & 0x8000)) { if (!(P[0] & 0x8000)) {
if (!(P[2] & 0x8000)) { if (!(P[2] & 0x8000)) {
/* 1 of 4 colors for each pixel */ /* 1 of 4 colors for each pixel */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 16);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
/* get the next set of 8 2-bit flags */ /* get the next set of 8 2-bit flags */
int flags = bytestream_get_le16(&s->stream_ptr); int flags = bytestream2_get_le16(&s->stream_ptr);
for (x = 0; x < 8; x++, flags >>= 2) for (x = 0; x < 8; x++, flags >>= 2)
*pixel_ptr++ = P[flags & 0x03]; *pixel_ptr++ = P[flags & 0x03];
pixel_ptr += s->line_inc; pixel_ptr += s->line_inc;
@ -736,9 +671,7 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
uint32_t flags; uint32_t flags;
/* 1 of 4 colors for each 2x2 block */ /* 1 of 4 colors for each 2x2 block */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 4); flags = bytestream2_get_le32(&s->stream_ptr);
flags = bytestream_get_le32(&s->stream_ptr);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2, flags >>= 2) { for (x = 0; x < 8; x += 2, flags >>= 2) {
@ -755,9 +688,7 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
uint64_t flags; uint64_t flags;
/* 1 of 4 colors for each 2x1 or 1x2 block */ /* 1 of 4 colors for each 2x1 or 1x2 block */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8); flags = bytestream2_get_le64(&s->stream_ptr);
flags = bytestream_get_le64(&s->stream_ptr);
if (!(P[2] & 0x8000)) { if (!(P[2] & 0x8000)) {
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x += 2, flags >>= 2) { for (x = 0; x < 8; x += 2, flags >>= 2) {
@ -784,25 +715,25 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s) static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
{ {
int x, y; int x, y;
uint16_t P[4]; uint16_t P[8];
int flags = 0; int flags = 0;
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
for (x = 0; x < 4; x++)
P[x] = bytestream2_get_le16(&s->stream_ptr);
/* 4-color encoding for each 4x4 quadrant, or 4-color encoding on /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
* either top and bottom or left and right halves */ * either top and bottom or left and right halves */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 24); if (!(P[0] & 0x8000)) {
if (!(AV_RL16(s->stream_ptr) & 0x8000)) {
/* 4-color encoding for each quadrant */ /* 4-color encoding for each quadrant */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 48);
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// new values for each 4x4 block // new values for each 4x4 block
if (!(y & 3)) { if (!(y & 3)) {
if (y)
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++)
P[x] = bytestream_get_le16(&s->stream_ptr); P[x] = bytestream2_get_le16(&s->stream_ptr);
flags = bytestream_get_le32(&s->stream_ptr); flags = bytestream2_get_le32(&s->stream_ptr);
} }
for (x = 0; x < 4; x++, flags >>= 2) for (x = 0; x < 4; x++, flags >>= 2)
@ -815,20 +746,17 @@ static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
} else { } else {
// vertical split? // vertical split?
int vert = !(AV_RL16(s->stream_ptr + 16) & 0x8000); int vert;
uint64_t flags = 0; uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
for (x = 4; x < 8; x++)
P[x] = bytestream2_get_le16(&s->stream_ptr);
vert = !(P[4] & 0x8000);
/* 4-color encoding for either left and right or top and bottom /* 4-color encoding for either left and right or top and bottom
* halves */ * halves */
for (y = 0; y < 16; y++) { for (y = 0; y < 16; y++) {
// load values for each half
if (!(y & 7)) {
for (x = 0; x < 4; x++)
P[x] = bytestream_get_le16(&s->stream_ptr);
flags = bytestream_get_le64(&s->stream_ptr);
}
for (x = 0; x < 4; x++, flags >>= 2) for (x = 0; x < 4; x++, flags >>= 2)
*pixel_ptr++ = P[flags & 0x03]; *pixel_ptr++ = P[flags & 0x03];
@ -837,6 +765,12 @@ static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
// switch to right half // switch to right half
if (y == 7) pixel_ptr -= 8 * s->stride - 4; if (y == 7) pixel_ptr -= 8 * s->stride - 4;
} else if (y & 1) pixel_ptr += s->line_inc; } else if (y & 1) pixel_ptr += s->line_inc;
// load values for second half
if (y == 7) {
memcpy(P, P + 4, 8);
flags = bytestream2_get_le64(&s->stream_ptr);
}
} }
} }
@ -850,11 +784,9 @@ static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 64-color encoding (each pixel in block is a different color) */ /* 64-color encoding (each pixel in block is a different color) */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 128);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) for (x = 0; x < 8; x++)
pixel_ptr[x] = bytestream_get_le16(&s->stream_ptr); pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
pixel_ptr += s->stride; pixel_ptr += s->stride;
} }
@ -868,14 +800,12 @@ static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 16-color block encoding: each 2x2 block is a different color */ /* 16-color block encoding: each 2x2 block is a different color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 32);
for (y = 0; y < 8; y += 2) { for (y = 0; y < 8; y += 2) {
for (x = 0; x < 8; x += 2) { for (x = 0; x < 8; x += 2) {
pixel_ptr[x ] = pixel_ptr[x ] =
pixel_ptr[x + 1 ] = pixel_ptr[x + 1 ] =
pixel_ptr[x + s->stride] = pixel_ptr[x + s->stride] =
pixel_ptr[x + 1 + s->stride] = bytestream_get_le16(&s->stream_ptr); pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
} }
pixel_ptr += s->stride * 2; pixel_ptr += s->stride * 2;
} }
@ -891,12 +821,10 @@ static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 4-color block encoding: each 4x4 block is a different color */ /* 4-color block encoding: each 4x4 block is a different color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 8);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
if (!(y & 3)) { if (!(y & 3)) {
P[0] = bytestream_get_le16(&s->stream_ptr); P[0] = bytestream2_get_le16(&s->stream_ptr);
P[1] = bytestream_get_le16(&s->stream_ptr); P[1] = bytestream2_get_le16(&s->stream_ptr);
} }
for (x = 0; x < 8; x++) for (x = 0; x < 8; x++)
pixel_ptr[x] = P[x >> 2]; pixel_ptr[x] = P[x >> 2];
@ -914,8 +842,7 @@ static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr; uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
/* 1-color encoding: the whole block is 1 solid color */ /* 1-color encoding: the whole block is 1 solid color */
CHECK_STREAM_PTR(s->stream_ptr, s->stream_end, 2); pix = bytestream2_get_le16(&s->stream_ptr);
pix = bytestream_get_le16(&s->stream_ptr);
for (y = 0; y < 8; y++) { for (y = 0; y < 8; y++) {
for (x = 0; x < 8; x++) for (x = 0; x < 8; x++)
@ -960,19 +887,16 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
av_dlog(s->avctx, "frame %d\n", frame); av_dlog(s->avctx, "frame %d\n", frame);
frame++; frame++;
bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
if (!s->is_16bpp) { if (!s->is_16bpp) {
/* this is PAL8, so make the palette available */ /* this is PAL8, so make the palette available */
memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE); memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE);
s->stride = s->current_frame.linesize[0]; s->stride = s->current_frame.linesize[0];
s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */
s->stream_end = s->buf + s->size;
} else { } else {
s->stride = s->current_frame.linesize[0] >> 1; s->stride = s->current_frame.linesize[0] >> 1;
s->stream_ptr = s->buf + 16; s->mv_ptr = s->stream_ptr;
s->stream_end = bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
s->mv_ptr = s->buf + 14 + AV_RL16(s->buf+14);
s->mv_end = s->buf + s->size;
} }
s->line_inc = s->stride - 8; s->line_inc = s->stride - 8;
s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0] s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0]
@ -1002,9 +926,10 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
} }
} }
} }
if (s->stream_end - s->stream_ptr > 1) { if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
av_log(s->avctx, AV_LOG_ERROR, "decode finished with %td bytes left over\n", av_log(s->avctx, AV_LOG_ERROR,
s->stream_end - s->stream_ptr); "decode finished with %d bytes left over\n",
bytestream2_get_bytes_left(&s->stream_ptr));
} }
} }
@ -1046,8 +971,8 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
return buf_size; return buf_size;
s->decoding_map = buf; s->decoding_map = buf;
s->buf = buf + s->decoding_map_size; bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size,
s->size = buf_size - s->decoding_map_size; buf_size - s->decoding_map_size);
s->current_frame.reference = 3; s->current_frame.reference = 3;
if (avctx->get_buffer(avctx, &s->current_frame)) { if (avctx->get_buffer(avctx, &s->current_frame)) {

View File

@ -907,9 +907,13 @@ void ff_thread_flush(AVCodecContext *avctx)
fctx->next_decoding = fctx->next_finished = 0; fctx->next_decoding = fctx->next_finished = 0;
fctx->delaying = 1; fctx->delaying = 1;
fctx->prev_thread = NULL; fctx->prev_thread = NULL;
for (i = 0; i < avctx->thread_count; i++) {
PerThreadContext *p = &fctx->threads[i];
// Make sure decode flush calls with size=0 won't return old frames // Make sure decode flush calls with size=0 won't return old frames
for (i = 0; i < avctx->thread_count; i++) p->got_frame = 0;
fctx->threads[i].got_frame = 0;
release_delayed_buffers(p);
}
} }
static int *allocate_progress(PerThreadContext *p) static int *allocate_progress(PerThreadContext *p)

View File

@ -358,13 +358,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
{ {
const uint8_t *buf = avpkt->data; const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size; int buf_size = avpkt->size;
const uint8_t *buf_end = buf + buf_size;
UtvideoContext *c = avctx->priv_data; UtvideoContext *c = avctx->priv_data;
const uint8_t *ptr;
int i, j; int i, j;
const uint8_t *plane_start[5]; const uint8_t *plane_start[5];
int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size; int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
int ret; int ret;
GetByteContext gb;
if (c->pic.data[0]) if (c->pic.data[0])
ff_thread_release_buffer(avctx, &c->pic); ff_thread_release_buffer(avctx, &c->pic);
@ -377,20 +376,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
} }
/* parse plane structure to retrieve frame flags and validate slice offsets */ /* parse plane structure to retrieve frame flags and validate slice offsets */
ptr = buf; bytestream2_init(&gb, buf, buf_size);
for (i = 0; i < c->planes; i++) { for (i = 0; i < c->planes; i++) {
plane_start[i] = ptr; plane_start[i] = gb.buffer;
if (buf_end - ptr < 256 + 4 * c->slices) { if (bytestream2_get_bytes_left(&gb) < 256 + 4 * c->slices) {
av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n"); av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
ptr += 256; bytestream2_skipu(&gb, 256);
slice_start = 0; slice_start = 0;
slice_end = 0; slice_end = 0;
for (j = 0; j < c->slices; j++) { for (j = 0; j < c->slices; j++) {
slice_end = bytestream_get_le32(&ptr); slice_end = bytestream2_get_le32u(&gb);
slice_size = slice_end - slice_start; slice_size = slice_end - slice_start;
if (slice_size < 0) { if (slice_end <= 0 || slice_size <= 0 ||
bytestream2_get_bytes_left(&gb) < slice_end) {
av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n"); av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -398,18 +398,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
max_slice_size = FFMAX(max_slice_size, slice_size); max_slice_size = FFMAX(max_slice_size, slice_size);
} }
plane_size = slice_end; plane_size = slice_end;
if (buf_end - ptr < plane_size) { bytestream2_skipu(&gb, plane_size);
av_log(avctx, AV_LOG_ERROR, "Plane size is bigger than available data\n");
return AVERROR_INVALIDDATA;
} }
ptr += plane_size; plane_start[c->planes] = gb.buffer;
} if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) {
plane_start[c->planes] = ptr;
if (buf_end - ptr < c->frame_info_size) {
av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n"); av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
c->frame_info = AV_RL32(ptr); c->frame_info = bytestream2_get_le32u(&gb);
av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info); av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info);
c->frame_pred = (c->frame_info >> 8) & 3; c->frame_pred = (c->frame_info >> 8) & 3;

View File

@ -25,6 +25,7 @@ YASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \
YASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \ YASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \
x86/h264_intrapred_10bit.o x86/h264_intrapred_10bit.o
MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o
YASM-OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel_10bit.o
MMX-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp_init.o MMX-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp_init.o
YASM-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp.o YASM-OBJS-$(CONFIG_RV30_DECODER) += x86/rv34dsp.o
@ -71,7 +72,6 @@ MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o
MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \ MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \
x86/deinterlace.o \ x86/deinterlace.o \
x86/fmtconvert.o \ x86/fmtconvert.o \
x86/h264_qpel_10bit.o \
$(YASM-OBJS-yes) $(YASM-OBJS-yes)
MMX-OBJS-$(CONFIG_FFT) += x86/fft.o MMX-OBJS-$(CONFIG_FFT) += x86/fft.o

File diff suppressed because it is too large Load Diff

View File

@ -2209,14 +2209,11 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
size); size);
av_free(ptr); av_free(ptr);
} }
} else {
param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
track->enc->extradata_size);
}
if (track->enc->codec_id == CODEC_ID_H264) {
param_write_string(pb, "FourCC", "H264"); param_write_string(pb, "FourCC", "H264");
} else if (track->enc->codec_id == CODEC_ID_VC1) { } else if (track->enc->codec_id == CODEC_ID_VC1) {
param_write_string(pb, "FourCC", "WVC1"); param_write_string(pb, "FourCC", "WVC1");
param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
track->enc->extradata_size);
} }
param_write_int(pb, "MaxWidth", track->enc->width); param_write_int(pb, "MaxWidth", track->enc->width);
param_write_int(pb, "MaxHeight", track->enc->height); param_write_int(pb, "MaxHeight", track->enc->height);