From 6308729e6885947e04291d5eca7e740fff50fff1 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 2 Oct 2011 23:38:32 +0100 Subject: [PATCH 1/5] ARM: check for inline asm 'y' operand modifier support The inline asm added in bf5d46d uses the 'y' modifier which is only supported from gcc 4.5. This check allows building with older compilers. Signed-off-by: Mans Rullgard --- configure | 3 +++ libavcodec/arm/dca.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 32f1a26298..22735e788e 100755 --- a/configure +++ b/configure @@ -1042,6 +1042,7 @@ HAVE_LIST=" alsa_asoundlib_h altivec_h arpa_inet_h + asm_mod_y attribute_may_alias attribute_packed bswap @@ -2644,6 +2645,8 @@ EOF enabled neon && check_asm neon '"vadd.i16 q0, q0, q0"' enabled vfpv3 && check_asm vfpv3 '"vmov.f32 s0, #1.0"' + check_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' + enabled_all armv6t2 shared !pic && enable_pic elif enabled mips; then diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h index c4c024a36a..38c8d1f9cc 100644 --- a/libavcodec/arm/dca.h +++ b/libavcodec/arm/dca.h @@ -24,7 +24,7 @@ #include #include "config.h" -#if HAVE_NEON && HAVE_INLINE_ASM +#if HAVE_NEON && HAVE_INLINE_ASM && HAVE_ASM_MOD_Y #define int8x8_fmul_int32 int8x8_fmul_int32 static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale) From 24ec9ac4755525e9875fb121aba4d360df916447 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2011 16:10:53 +0200 Subject: [PATCH 2/5] libvpx: fix build with older libvpx versions. VPX_ERROR_RESILIENT_DEFAULT and VPX_ERROR_RESILIENT_PARTITIONS weren't defined before 4cb0ebe5b27d35ccc2a78c1d16f2622ddef21f74 (CommitDate: Tue Jun 28 11:10:17 2011) --- libavcodec/libvpxenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 524c53d533..673834f5a9 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -539,11 +539,13 @@ static const AVOption options[] = { { "good", NULL, 0, FF_OPT_TYPE_CONST, {VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"}, { "realtime", NULL, 0, FF_OPT_TYPE_CONST, {VPX_DL_REALTIME}, 0, 0, VE, "quality"}, { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), FF_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, VE, "er"}, +#ifdef VPX_ERROR_RESILIENT_DEFAULT { "default", "Improve resiliency against losses of whole frames", 0, FF_OPT_TYPE_CONST, {VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"}, { "partitions", "The frame partitions are independently decodable " "by the bool decoder, meaning that partitions can be decoded even " "though earlier partitions have been lost. Note that intra predicition" " is still done over the partition boundary.", 0, FF_OPT_TYPE_CONST, {VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, +#endif { NULL } }; From 1e18d32d01fc0ac784a0d592b46215bfbdcc579d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2011 07:16:09 +0200 Subject: [PATCH 3/5] id3v2: don't discard the whole tag when encountering empty frames. While they're technically invalid, it's better to skip them and try to read the rest of the tag. --- libavformat/id3v2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 68c1709b93..a3d7ae6c5f 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -401,13 +401,19 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t tag[3] = 0; tlen = avio_rb24(s->pb); } - if (tlen <= 0 || tlen > len - taghdrlen) { + if (tlen < 0 || tlen > len - taghdrlen) { av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag); break; } len -= taghdrlen + tlen; next = avio_tell(s->pb) + tlen; + if (!tlen) { + if (tag[0]) + av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag); + continue; + } + if (tflags & ID3v2_FLAG_DATALEN) { avio_rb32(s->pb); tlen -= 4; From d2961e4ebfbb78af0f066760eb0ffb8a8567e529 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2011 09:06:34 +0200 Subject: [PATCH 4/5] id3v2: read TXXX frames with two calls to decode_str() instead of one. Read the key in the first, value in the second. This allows to avoid pointless strdups and simplify decode_str() by dropping two of its parameters. --- libavformat/id3v2.c | 60 +++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index a3d7ae6c5f..48443e1865 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -73,23 +73,20 @@ static void free_geobtag(ID3v2ExtraMetaGEOB *geob) /** * Decode characters to UTF-8 according to encoding type. The decoded buffer is - * always null terminated. + * always null terminated. Stop reading when either *maxread bytes are read from + * pb or U+0000 character is found. * * @param dst Pointer where the address of the buffer with the decoded bytes is * stored. Buffer must be freed by caller. - * @param dstlen Pointer to an int where the length of the decoded string - * is stored (in bytes, incl. null termination) * @param maxread Pointer to maximum number of characters to read from the * AVIOContext. After execution the value is decremented by the number of bytes * actually read. - * @seeknull If true, decoding stops after the first U+0000 character found, if - * there is any before maxread is reached * @returns 0 if no error occured, dst is uninitialized on error */ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, - uint8_t **dst, int *dstlen, int *maxread, const int seeknull) + uint8_t **dst, int *maxread) { - int len, ret; + int ret; uint8_t tmp; uint32_t ch = 1; int left = *maxread; @@ -104,7 +101,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, switch (encoding) { case ID3v2_ENCODING_ISO8859: - while (left && (!seeknull || ch)) { + while (left && ch) { ch = avio_r8(pb); PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) left--; @@ -133,7 +130,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, // fall-through case ID3v2_ENCODING_UTF16BE: - while ((left > 1) && (!seeknull || ch)) { + while ((left > 1) && ch) { GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;) PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) } @@ -142,7 +139,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, break; case ID3v2_ENCODING_UTF8: - while (left && (!seeknull || ch)) { + while (left && ch) { ch = avio_r8(pb); avio_w8(dynbuf, ch); left--; @@ -155,10 +152,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, if (ch) avio_w8(dynbuf, 0); - len = avio_close_dyn_buf(dynbuf, (uint8_t **)dst); - if (dstlen) - *dstlen = len; - + avio_close_dyn_buf(dynbuf, (uint8_t **)dst); *maxread = left; return 0; @@ -170,38 +164,40 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key) { uint8_t *dst; - const char *val = NULL; - int len, dstlen; + int encoding, dict_flags = AV_DICT_DONT_OVERWRITE; unsigned genre; if (taglen < 1) return; + encoding = avio_r8(pb); taglen--; /* account for encoding type byte */ - if (decode_str(s, pb, avio_r8(pb), &dst, &dstlen, &taglen, 0) < 0) { + if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); return; } if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) - && genre <= ID3v1_GENRE_MAX) - val = ff_id3v1_genre_str[genre]; - else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { - /* dst now contains two 0-terminated strings */ - dst[dstlen] = 0; - len = strlen(dst); + && genre <= ID3v1_GENRE_MAX) { + av_freep(&dst); + dst = ff_id3v1_genre_str[genre]; + } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { + /* dst now contains the key, need to get value */ key = dst; - val = dst + FFMIN(len + 1, dstlen); + if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { + av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); + av_freep(&key); + return; + } + dict_flags |= AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_STRDUP_KEY; } else if (*dst) - val = dst; + dict_flags |= AV_DICT_DONT_STRDUP_VAL; - if (val) - av_dict_set(&s->metadata, key, val, AV_DICT_DONT_OVERWRITE); - - av_free(dst); + if (dst) + av_dict_set(&s->metadata, key, dst, dict_flags); } /** @@ -234,17 +230,17 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char * taglen--; /* read MIME type (always ISO-8859) */ - if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, NULL, &taglen, 1) < 0 + if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0 || taglen <= 0) goto fail; /* read file name */ - if (decode_str(s, pb, encoding, &geob_data->file_name, NULL, &taglen, 1) < 0 + if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 || taglen <= 0) goto fail; /* read content description */ - if (decode_str(s, pb, encoding, &geob_data->description, NULL, &taglen, 1) < 0 + if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 || taglen < 0) goto fail; From 60df6b004858dcab96fc96c6dd32484780a8d7c3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 2 Oct 2011 09:14:30 +0200 Subject: [PATCH 5/5] id3v2: remove pointless casts --- libavformat/id3v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 48443e1865..c30ab4ceb3 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -111,7 +111,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, case ID3v2_ENCODING_UTF16BOM: if ((left -= 2) < 0) { av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n"); - avio_close_dyn_buf(dynbuf, (uint8_t **)dst); + avio_close_dyn_buf(dynbuf, dst); av_freep(dst); return AVERROR_INVALIDDATA; } @@ -122,7 +122,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, break; default: av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n"); - avio_close_dyn_buf(dynbuf, (uint8_t **)dst); + avio_close_dyn_buf(dynbuf, dst); av_freep(dst); *maxread = left; return AVERROR_INVALIDDATA; @@ -152,7 +152,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, if (ch) avio_w8(dynbuf, 0); - avio_close_dyn_buf(dynbuf, (uint8_t **)dst); + avio_close_dyn_buf(dynbuf, dst); *maxread = left; return 0;