summaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-02-19 01:36:23 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-02-19 01:47:10 +0100
commit4a519b6e036bb593d868c2a424da43512215c571 (patch)
treebbbd734383e7b2bfd005a1c19fe64d36d493b576 /libavcodec
parent57182b9f0fa15ebedbf5229e17bc77a70cc68d9d (diff)
parent5be805d38cb43e6f0b85941f75946d09bc8cc13f (diff)
downloadffmpeg-streaming-4a519b6e036bb593d868c2a424da43512215c571.zip
ffmpeg-streaming-4a519b6e036bb593d868c2a424da43512215c571.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: mov: Use defines for sample flags in fragments mov: Use defines for trun flags mov: Use defines for tfhd flags proresenc: force bitrate not to exceed given limit vc1parse: call vc1_init_common(). wma: don't return 0 on invalid packets. asf: prevent packet_size_left from going negative if hdrlen > pktlen. mjpegb: don't return 0 at the end of frame decoding. rtpdec: Identify incorrectly signalled H263 vp8dsp: split long line. aiff: don't skip block_align==0 check on COMM-after-SSND files. dpcm: ignore extra unpaired bytes in stereo streams. mp3on4: require a minimum framesize. mpc7: assign an error level + context to av_log() msg. huffyuv: error out on bit overrun. dct-test: Add the missing ff_ prefix to the altivec functions dct-test: Remove a stray declaration of a nonexistent function movenc: Write the unknown duration as 64 bit fields in ismv movenc: Write track durations with all bits set if duration is unknown Conflicts: libavcodec/dct-test.c libavcodec/wmadec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/dct-test.c2
-rw-r--r--libavcodec/dpcm.c7
-rw-r--r--libavcodec/huffyuv.c2
-rw-r--r--libavcodec/mjpegbdec.c4
-rw-r--r--libavcodec/mpc7.c2
-rw-r--r--libavcodec/mpegaudiodec.c4
-rw-r--r--libavcodec/proresenc_kostya.c72
-rw-r--r--libavcodec/vc1.h1
-rw-r--r--libavcodec/vc1_parser.c2
-rw-r--r--libavcodec/vc1dec.c4
-rw-r--r--libavcodec/vp8dsp.h4
-rw-r--r--libavcodec/wmadec.c8
12 files changed, 90 insertions, 22 deletions
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index 5a27b75..3a6ab96 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -54,7 +54,7 @@ void ff_bfin_fdct(DCTELEM *block);
// ALTIVEC
void ff_fdct_altivec(DCTELEM *block);
-//void idct_altivec(DCTELEM *block);?? no routine
+//void ff_idct_altivec(DCTELEM *block);?? no routine
// ARM
void ff_j_rev_dct_arm(DCTELEM *data);
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index 8240221..4915223 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -183,6 +183,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
int stereo = s->channels - 1;
int16_t *output_samples;
+ if (stereo && (buf_size & 1)) {
+ buf_size--;
+ buf_end--;
+ }
+
/* calculate output size */
switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM:
@@ -320,7 +325,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
*got_frame_ptr = 1;
*(AVFrame *)data = s->frame;
- return buf_size;
+ return avpkt->size;
}
#define DPCM_DECODER(id_, name_, long_name_) \
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index c46e93f..625d8fb 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -212,7 +212,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){
if(repeat==0)
repeat= get_bits(gb, 8);
//printf("%d %d\n", val, repeat);
- if(i+repeat > 256) {
+ if(i+repeat > 256 || get_bits_left(gb) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
return -1;
}
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index fc77b14..b70311b 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -69,7 +69,7 @@ read_header:
if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))
{
av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
- return 0;
+ return AVERROR_INVALIDDATA;
}
field_size = get_bits_long(&hgb, 32); /* field size */
@@ -149,7 +149,7 @@ read_header:
picture->quality*= FF_QP2LAMBDA;
}
- return buf_ptr - buf;
+ return buf_size;
}
AVCodec ff_mjpegb_decoder = {
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index e90c934..6e4b850 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -298,7 +298,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
bits_used = get_bits_count(&gb);
bits_avail = buf_size * 8;
if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) {
- av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
+ av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
return -1;
}
if(c->frames_to_skip){
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index 2ca30f2..f474161 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -1914,6 +1914,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
m = s->mp3decctx[fr];
assert(m != NULL);
+ if (fsize < HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
+ return AVERROR_INVALIDDATA;
+ }
header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
if (ff_mpa_check_header(header) < 0) // Bad header, discard block
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index 242537b..8259b2a 100644
--- a/libavcodec/proresenc_kostya.c
+++ b/libavcodec/proresenc_kostya.c
@@ -139,11 +139,14 @@ struct TrellisNode {
int score;
};
+#define MAX_STORED_Q 16
+
typedef struct ProresContext {
AVClass *class;
DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
- int16_t quants[16][64];
+ int16_t quants[MAX_STORED_Q][64];
+ int16_t custom_q[64];
ProresDSPContext dsp;
ScanTable scantable;
@@ -156,6 +159,8 @@ typedef struct ProresContext {
int num_planes;
int bits_per_mb;
+ int frame_size;
+
int profile;
const struct prores_profile *profile_info;
@@ -348,6 +353,15 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
int slice_width_factor = av_log2(mbs_per_slice);
int num_cblocks, pwidth;
int plane_factor, is_chroma;
+ uint16_t *qmat;
+
+ if (quant < MAX_STORED_Q) {
+ qmat = ctx->quants[quant];
+ } else {
+ qmat = ctx->custom_q;
+ for (i = 0; i < 64; i++)
+ qmat[i] = ctx->profile_info->quant[i] * quant;
+ }
for (i = 0; i < ctx->num_planes; i++) {
is_chroma = (i == 1 || i == 2);
@@ -373,7 +387,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
mbs_per_slice, ctx->blocks[0],
num_cblocks, plane_factor,
- ctx->quants[quant]);
+ qmat);
total_size += sizes[i];
}
return total_size;
@@ -500,6 +514,8 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
int error, bits, bits_limit;
int mbs, prev, cur, new_score;
int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
+ int overquant;
+ uint16_t *qmat;
mbs = x + mbs_per_slice;
@@ -526,7 +542,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
mbs_per_slice, num_cblocks[i]);
}
- for (q = min_quant; q <= max_quant; q++) {
+ for (q = min_quant; q < max_quant + 2; q++) {
ctx->nodes[trellis_node + q].prev_node = -1;
ctx->nodes[trellis_node + q].quant = q;
}
@@ -549,12 +565,43 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
slice_bits[q] = bits;
slice_score[q] = error;
}
+ if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
+ slice_bits[max_quant + 1] = slice_bits[max_quant];
+ slice_score[max_quant + 1] = slice_score[max_quant] + 1;
+ overquant = max_quant;
+ } else {
+ for (q = max_quant + 1; q < 128; q++) {
+ bits = 0;
+ error = 0;
+ if (q < MAX_STORED_Q) {
+ qmat = ctx->quants[q];
+ } else {
+ qmat = ctx->custom_q;
+ for (i = 0; i < 64; i++)
+ qmat[i] = ctx->profile_info->quant[i] * q;
+ }
+ for (i = 0; i < ctx->num_planes; i++) {
+ bits += estimate_slice_plane(ctx, &error, i,
+ src, pic->linesize[i],
+ mbs_per_slice,
+ num_cblocks[i], plane_factor[i],
+ qmat);
+ }
+ if (bits <= ctx->bits_per_mb * mbs_per_slice)
+ break;
+ }
+
+ slice_bits[max_quant + 1] = bits;
+ slice_score[max_quant + 1] = error;
+ overquant = q;
+ }
+ ctx->nodes[trellis_node + max_quant + 1].quant = overquant;
bits_limit = mbs * ctx->bits_per_mb;
- for (pq = min_quant; pq <= max_quant; pq++) {
+ for (pq = min_quant; pq < max_quant + 2; pq++) {
prev = trellis_node - TRELLIS_WIDTH + pq;
- for (q = min_quant; q <= max_quant; q++) {
+ for (q = min_quant; q < max_quant + 2; q++) {
cur = trellis_node + q;
bits = ctx->nodes[prev].bits + slice_bits[q];
@@ -578,7 +625,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
error = ctx->nodes[trellis_node + min_quant].score;
pq = trellis_node + min_quant;
- for (q = min_quant + 1; q <= max_quant; q++) {
+ for (q = min_quant + 1; q < max_quant + 2; q++) {
if (ctx->nodes[trellis_node + q].score <= error) {
error = ctx->nodes[trellis_node + q].score;
pq = trellis_node + q;
@@ -606,8 +653,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
avctx->coded_frame->key_frame = 1;
- pkt_size = ctx->mb_width * ctx->mb_height * 64 * 3 * 12
- + ctx->num_slices * 2 + 200 + FF_MIN_BUFFER_SIZE;
+ pkt_size = ctx->frame_size + FF_MIN_BUFFER_SIZE;
if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
@@ -762,9 +808,13 @@ static av_cold int encode_init(AVCodecContext *avctx)
break;
ctx->bits_per_mb = ctx->profile_info->br_tab[i];
+ ctx->frame_size = ctx->num_slices * (2 + 2 * ctx->num_planes
+ + (2 * mps * ctx->bits_per_mb) / 8)
+ + 200;
+
min_quant = ctx->profile_info->min_quant;
max_quant = ctx->profile_info->max_quant;
- for (i = min_quant; i <= max_quant; i++) {
+ for (i = min_quant; i < MAX_STORED_Q; i++) {
for (j = 0; j < 64; j++)
ctx->quants[i][j] = ctx->profile_info->quant[j] * i;
}
@@ -773,6 +823,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices, %d bits per MB\n",
ctx->profile, ctx->num_slices, ctx->bits_per_mb);
+ av_log(avctx, AV_LOG_DEBUG, "estimated frame size %d\n",
+ ctx->frame_size);
ctx->nodes = av_malloc((ctx->slices_width + 1) * TRELLIS_WIDTH
* sizeof(*ctx->nodes));
@@ -780,7 +832,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
encode_close(avctx);
return AVERROR(ENOMEM);
}
- for (i = min_quant; i <= max_quant; i++) {
+ for (i = min_quant; i < max_quant + 2; i++) {
ctx->nodes[i].prev_node = -1;
ctx->nodes[i].bits = 0;
ctx->nodes[i].score = 0;
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 61b3427..0f18530 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -447,5 +447,6 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex
int ff_vc1_parse_frame_header (VC1Context *v, GetBitContext *gb);
int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
+int ff_vc1_init_common(VC1Context *v);
#endif /* AVCODEC_VC1_H */
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index f133e3a..a2a0d4a 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -188,7 +188,7 @@ static int vc1_parse_init(AVCodecParserContext *s)
{
VC1ParseContext *vpc = s->priv_data;
vpc->v.s.slice_context_count = 1;
- return 0;
+ return ff_vc1_init_common(&vpc->v);
}
AVCodecParser ff_vc1_parser = {
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index a10ec85..bffd7b8 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -67,7 +67,7 @@ static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
* @param v The VC1Context to initialize
* @return Status
*/
-static int vc1_init_common(VC1Context *v)
+int ff_vc1_init_common(VC1Context *v)
{
static int done = 0;
int i = 0;
@@ -5274,7 +5274,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
avctx->idct_algo = FF_IDCT_WMV2;
}
- if (vc1_init_common(v) < 0)
+ if (ff_vc1_init_common(v) < 0)
return -1;
ff_vc1dsp_init(&v->vc1dsp);
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index 987fa59..951a556 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -29,7 +29,9 @@
#include "dsputil.h"
-typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
+typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride,
+ uint8_t *src/*align 1*/, int srcStride,
+ int h, int x, int y);
typedef struct VP8DSPContext {
void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]);
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 7d7cc7f..c90e22c 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -834,8 +834,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
s->last_superframe_len = 0;
return 0;
}
- if (buf_size < s->block_align)
- return AVERROR(EINVAL);
+ if (buf_size < s->block_align) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Input packet size too small (%d < %d)\n",
+ buf_size, s->block_align);
+ return AVERROR_INVALIDDATA;
+ }
if(s->block_align)
buf_size = s->block_align;
OpenPOWER on IntegriCloud