summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-02-25 04:00:43 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-02-25 04:00:43 +0100
commitb008ac18bb6072acb355445436a999c940538d84 (patch)
tree29d0042d7a4d0bc64f452440c2060a13a1e00e51 /libavcodec
parent7b9d8703f35585b065c32194b52131b7dd90c710 (diff)
parentd6a77e2b97f3968b99798faeb70e873eb5910849 (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: docs: use -bsf:[vas] instead of -[vas]bsf. mpegaudiodec: Prevent premature clipping of mp3 input buffer. lavf: move the packet keyframe setting code. oggenc: free comment header for all codecs lcl: error out if uncompressed input buffer is smaller than framesize. mjpeg: abort decoding if packet is too large. golomb: use HAVE_BITS_REMAINING() macro to prevent infloop on EOF. get_bits: add HAVE_BITS_REMAINING macro. lavf/output-example: use new audio encoding API correctly. lavf/output-example: more proper usage of the new API. tiff: Prevent overreads in the type_sizes array. tiff: Make the TIFF_LONG and TIFF_SHORT types unsigned. apetag: do not leak memory if avio_read() fails apetag: propagate errors. SBR DSP x86: implement SSE sbr_hf_g_filt SBR DSP x86: implement SSE sbr_sum_square_sse SBR DSP: use intptr_t for the ixh parameter. Conflicts: doc/bitstream_filters.texi doc/examples/muxing.c doc/ffmpeg.texi libavcodec/golomb.h libavcodec/x86/Makefile libavformat/oggenc.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/arm/sbrdsp_init_arm.c2
-rw-r--r--libavcodec/get_bits.h15
-rw-r--r--libavcodec/golomb.h2
-rw-r--r--libavcodec/lcldec.c23
-rw-r--r--libavcodec/mjpegdec.c4
-rw-r--r--libavcodec/mpegaudiodec.c6
-rw-r--r--libavcodec/sbrdsp.c4
-rw-r--r--libavcodec/sbrdsp.h5
-rw-r--r--libavcodec/tiff.c33
-rw-r--r--libavcodec/x86/Makefile2
-rw-r--r--libavcodec/x86/sbrdsp.asm114
-rw-r--r--libavcodec/x86/sbrdsp_init.c40
12 files changed, 229 insertions, 21 deletions
diff --git a/libavcodec/arm/sbrdsp_init_arm.c b/libavcodec/arm/sbrdsp_init_arm.c
index 2ab0df829d..04294cc401 100644
--- a/libavcodec/arm/sbrdsp_init_arm.c
+++ b/libavcodec/arm/sbrdsp_init_arm.c
@@ -30,7 +30,7 @@ void ff_sbr_qmf_post_shuffle_neon(float W[32][2], const float *z);
void ff_sbr_qmf_deint_neg_neon(float *v, const float *src);
void ff_sbr_qmf_deint_bfly_neon(float *v, const float *src0, const float *src1);
void ff_sbr_hf_g_filt_neon(float (*Y)[2], const float (*X_high)[40][2],
- const float *g_filt, int m_max, int ixh);
+ const float *g_filt, int m_max, intptr_t ixh);
void ff_sbr_hf_gen_neon(float (*X_high)[2], const float (*X_low)[2],
const float alpha0[2], const float alpha1[2],
float bw, int start, int end);
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index d310fe0976..09b846eb42 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -118,10 +118,23 @@ for examples see get_bits, show_bits, skip_bits, get_vlc
# define MIN_CACHE_BITS 25
#endif
+#if UNCHECKED_BITSTREAM_READER
#define OPEN_READER(name, gb) \
unsigned int name##_index = (gb)->index; \
av_unused unsigned int name##_cache
+#define HAVE_BITS_REMAINING(name, gb) 1
+#else
+#define OPEN_READER(name, gb) \
+ unsigned int name##_index = (gb)->index; \
+ unsigned int av_unused name##_cache = 0; \
+ unsigned int av_unused name##_size_plus8 = \
+ (gb)->size_in_bits_plus8
+
+#define HAVE_BITS_REMAINING(name, gb) \
+ name##_index < name##_size_plus8
+#endif
+
#define CLOSE_READER(name, gb) (gb)->index = name##_index
#ifdef BITSTREAM_READER_LE
@@ -154,7 +167,7 @@ for examples see get_bits, show_bits, skip_bits, get_vlc
# define SKIP_COUNTER(name, gb, num) name##_index += (num)
#else
# define SKIP_COUNTER(name, gb, num) \
- name##_index = FFMIN((gb)->size_in_bits_plus8, name##_index + (num))
+ name##_index = FFMIN(name##_size_plus8, name##_index + (num))
#endif
#define SKIP_BITS(name, gb, num) do { \
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 2f474be22e..32e53a456f 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -135,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
- } while(ret<0x8000000U);
+ } while (ret<0x8000000U && HAVE_BITS_REMAINING(re, gb));
CLOSE_READER(re, gb);
return ret - 1;
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 901d9421f4..88567f6a98 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -229,8 +229,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
len = mszh_dlen;
}
break;
- case COMP_MSZH_NOCOMP:
+ case COMP_MSZH_NOCOMP: {
+ int bppx2;
+ switch (c->imgtype) {
+ case IMGTYPE_YUV111:
+ case IMGTYPE_RGB24:
+ bppx2 = 6;
+ break;
+ case IMGTYPE_YUV422:
+ case IMGTYPE_YUV211:
+ bppx2 = 4;
+ break;
+ case IMGTYPE_YUV411:
+ case IMGTYPE_YUV420:
+ bppx2 = 3;
+ break;
+ default:
+ bppx2 = 0; // will error out below
+ break;
+ }
+ if (len < ((width * height * bppx2) >> 1))
+ return AVERROR_INVALIDDATA;
break;
+ }
default:
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
return -1;
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 954fce1e40..dac0d6711d 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1570,6 +1570,10 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
/* EOF */
if (start_code < 0) {
goto the_end;
+ } else if (unescaped_buf_size > (1U<<29)) {
+ av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n",
+ start_code, unescaped_buf_ptr, buf_size);
+ return AVERROR_INVALIDDATA;
} else {
av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
start_code, buf_end - buf_ptr);
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index f47416133f..fd8052ef82 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -42,6 +42,7 @@
#define BACKSTEP_SIZE 512
#define EXTRABYTES 24
+#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
/* layer 3 "granule" */
typedef struct GranuleDef {
@@ -65,7 +66,7 @@ typedef struct GranuleDef {
typedef struct MPADecodeContext {
MPA_DECODE_HEADER
- uint8_t last_buf[2 * BACKSTEP_SIZE + EXTRABYTES];
+ uint8_t last_buf[LAST_BUF_SIZE];
int last_buf_size;
/* next header (used in free format parsing) */
uint32_t free_format_next_header;
@@ -1379,7 +1380,8 @@ static int mp_decode_layer3(MPADecodeContext *s)
if (!s->adu_mode) {
const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
- int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);
+ int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0,
+ FFMAX(0, LAST_BUF_SIZE - s->last_buf_size));
assert((get_bits_count(&s->gb) & 7) == 0);
/* now we get bits from the main_data_begin offset */
av_dlog(s->avctx, "seekback: %d\n", main_data_begin);
diff --git a/libavcodec/sbrdsp.c b/libavcodec/sbrdsp.c
index 2711e71338..f942759aa7 100644
--- a/libavcodec/sbrdsp.c
+++ b/libavcodec/sbrdsp.c
@@ -151,7 +151,7 @@ static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
}
static void sbr_hf_g_filt_c(float (*Y)[2], const float (*X_high)[40][2],
- const float *g_filt, int m_max, int ixh)
+ const float *g_filt, int m_max, intptr_t ixh)
{
int m;
@@ -238,4 +238,6 @@ av_cold void ff_sbrdsp_init(SBRDSPContext *s)
if (ARCH_ARM)
ff_sbrdsp_init_arm(s);
+ if (HAVE_MMX)
+ ff_sbrdsp_init_x86(s);
}
diff --git a/libavcodec/sbrdsp.h b/libavcodec/sbrdsp.h
index 88285b07ec..fe91957ce4 100644
--- a/libavcodec/sbrdsp.h
+++ b/libavcodec/sbrdsp.h
@@ -21,6 +21,8 @@
#ifndef LIBAVCODEC_SBRDSP_H
#define LIBAVCODEC_SBRDSP_H
+#include <stdint.h>
+
typedef struct SBRDSPContext {
void (*sum64x5)(float *z);
float (*sum_square)(float (*x)[2], int n);
@@ -34,7 +36,7 @@ typedef struct SBRDSPContext {
const float alpha0[2], const float alpha1[2],
float bw, int start, int end);
void (*hf_g_filt)(float (*Y)[2], const float (*X_high)[40][2],
- const float *g_filt, int m_max, int ixh);
+ const float *g_filt, int m_max, intptr_t ixh);
void (*hf_apply_noise[4])(float (*Y)[2], const float *s_m,
const float *q_filt, int noise,
int kx, int m_max);
@@ -44,5 +46,6 @@ extern const float ff_sbr_noise_table[][2];
void ff_sbrdsp_init(SBRDSPContext *s);
void ff_sbrdsp_init_arm(SBRDSPContext *s);
+void ff_sbrdsp_init_x86(SBRDSPContext *s);
#endif
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a0424b984a..5d01e44ad8 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -58,24 +58,24 @@ typedef struct TiffContext {
LZWState *lzw;
} TiffContext;
-static int tget_short(const uint8_t **p, int le){
- int v = le ? AV_RL16(*p) : AV_RB16(*p);
+static unsigned tget_short(const uint8_t **p, int le) {
+ unsigned v = le ? AV_RL16(*p) : AV_RB16(*p);
*p += 2;
return v;
}
-static int tget_long(const uint8_t **p, int le){
- int v = le ? AV_RL32(*p) : AV_RB32(*p);
+static unsigned tget_long(const uint8_t **p, int le) {
+ unsigned v = le ? AV_RL32(*p) : AV_RB32(*p);
*p += 4;
return v;
}
-static int tget(const uint8_t **p, int type, int le){
+static unsigned tget(const uint8_t **p, int type, int le) {
switch(type){
case TIFF_BYTE : return *(*p)++;
case TIFF_SHORT: return tget_short(p, le);
case TIFF_LONG : return tget_long (p, le);
- default : return -1;
+ default : return UINT_MAX;
}
}
@@ -340,7 +340,7 @@ static int init_image(TiffContext *s)
static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf)
{
- int tag, type, count, off, value = 0;
+ unsigned tag, type, count, off, value = 0;
int i, j;
uint32_t *pal;
const uint8_t *rp, *gp, *bp;
@@ -352,6 +352,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
count = tget_long(&buf, s->le);
off = tget_long(&buf, s->le);
+ if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
+ av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type);
+ return 0;
+ }
+
if(count == 1){
switch(type){
case TIFF_BYTE:
@@ -370,13 +375,15 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
break;
}
default:
- value = -1;
+ value = UINT_MAX;
+ buf = start + off;
+ }
+ } else {
+ if (count <= 4 && type_sizes[type] * count <= 4) {
+ buf -= 4;
+ } else {
buf = start + off;
}
- }else if(type_sizes[type] * count <= 4){
- buf -= 4;
- }else{
- buf = start + off;
}
if(buf && (buf < start || buf > end_buf)){
@@ -454,7 +461,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
}
break;
case TIFF_ROWSPERSTRIP:
- if(type == TIFF_LONG && value == -1)
+ if (type == TIFF_LONG && value == UINT_MAX)
value = s->avctx->height;
if(value < 1){
av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index dc8c66afde..0f746e289e 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -53,6 +53,8 @@ YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o
MMX-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp-init.o
YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o
MMX-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp-init.o
+MMX-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp_init.o
+YASM-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp.o
MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o \
x86/dwt.o
YASM-OBJS-$(CONFIG_V210_DECODER) += x86/v210.o
diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm
new file mode 100644
index 0000000000..c165c52ca4
--- /dev/null
+++ b/libavcodec/x86/sbrdsp.asm
@@ -0,0 +1,114 @@
+;******************************************************************************
+;* AAC Spectral Band Replication decoding functions
+;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet@gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+%include "x86util.asm"
+
+;SECTION_RODATA
+SECTION .text
+
+INIT_XMM sse
+cglobal sbr_sum_square, 2, 3, 6
+ mov r2, r1
+ xorps m0, m0
+ xorps m1, m1
+ sar r2, 3
+ jz .prepare
+.loop:
+ movu m2, [r0 + 0]
+ movu m3, [r0 + 16]
+ movu m4, [r0 + 32]
+ movu m5, [r0 + 48]
+ mulps m2, m2
+ mulps m3, m3
+ mulps m4, m4
+ mulps m5, m5
+ addps m0, m2
+ addps m1, m3
+ addps m0, m4
+ addps m1, m5
+ add r0, 64
+ dec r2
+ jnz .loop
+.prepare:
+ and r1, 7
+ sar r1, 1
+ jz .end
+; len is a multiple of 2, thus there are at least 4 elements to process
+.endloop:
+ movu m2, [r0]
+ add r0, 16
+ mulps m2, m2
+ dec r1
+ addps m0, m2
+ jnz .endloop
+.end:
+ addps m0, m1
+ movhlps m2, m0
+ addps m0, m2
+ movss m1, m0
+ shufps m0, m0, 1
+ addss m0, m1
+%if ARCH_X86_64 == 0
+ movd r0m, m0
+ fld dword r0m
+%endif
+ RET
+
+%define STEP 40*4*2
+cglobal sbr_hf_g_filt, 5, 6, 5
+ lea r1, [r1 + 8*r4] ; offset by ixh elements into X_high
+ mov r5, r3
+ and r3, 0xFC
+ lea r2, [r2 + r3*4]
+ lea r0, [r0 + r3*8]
+ neg r3
+.loop4:
+ movq m0, [r2 + 4*r3 + 0]
+ movq m1, [r2 + 4*r3 + 8]
+ movq m2, [r1 + 0*STEP]
+ movq m3, [r1 + 2*STEP]
+ movhps m2, [r1 + 1*STEP]
+ movhps m3, [r1 + 3*STEP]
+ punpckldq m0, m0
+ punpckldq m1, m1
+ mulps m0, m2
+ mulps m1, m3
+ movu [r0 + 8*r3 + 0], m0
+ movu [r0 + 8*r3 + 16], m1
+ add r1, 4*STEP
+ add r3, 4
+ jnz .loop4
+ and r5, 3 ; number of single element loops
+ jz .end
+.loop1: ; element 0 and 1 can be computed at the same time
+ movss m0, [r2]
+ movq m2, [r1]
+ punpckldq m0, m0
+ mulps m2, m0
+ movq [r0], m2
+ add r0, 8
+ add r2, 4
+ add r1, STEP
+ dec r5
+ jnz .loop1
+.end:
+ RET
diff --git a/libavcodec/x86/sbrdsp_init.c b/libavcodec/x86/sbrdsp_init.c
new file mode 100644
index 0000000000..0ffe5b9e11
--- /dev/null
+++ b/libavcodec/x86/sbrdsp_init.c
@@ -0,0 +1,40 @@
+/*
+ * AAC Spectral Band Replication decoding functions
+ * Copyright (c) 2012 Christophe Gisquet <christophe.gisquet@gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/cpu.h"
+#include "libavcodec/sbrdsp.h"
+
+float ff_sbr_sum_square_sse(float (*x)[2], int n);
+void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2],
+ const float *g_filt, int m_max, intptr_t ixh);
+
+void ff_sbrdsp_init_x86(SBRDSPContext *s)
+{
+ if (HAVE_YASM) {
+ int mm_flags = av_get_cpu_flags();
+
+ if (mm_flags & AV_CPU_FLAG_SSE) {
+ s->sum_square = ff_sbr_sum_square_sse;
+ s->hf_g_filt = ff_sbr_hf_g_filt_sse;
+ }
+ }
+}