diff --git a/configure b/configure index a3fdbfff0d..fdc0fe3b81 100755 --- a/configure +++ b/configure @@ -1115,6 +1115,7 @@ HAVE_LIST=" alsa_asoundlib_h altivec_h arpa_inet_h + asm_mod_y attribute_may_alias attribute_packed bswap @@ -2778,6 +2779,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) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 9d7ceef5a4..48124cee84 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -81,23 +81,20 @@ static void free_geobtag(void *obj) /** * 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; @@ -112,7 +109,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--; @@ -122,7 +119,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; } @@ -133,7 +130,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; @@ -141,7 +138,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);) } @@ -150,7 +147,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--; @@ -163,10 +160,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, dst); *maxread = left; return 0; @@ -178,38 +172,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); } /** @@ -242,17 +238,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; @@ -410,7 +406,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t tag[3] = 0; tlen = avio_rb24(s->pb); } - if (tlen > (1<<28) || !tlen) + if (tlen > (1<<28)) break; len -= taghdrlen + tlen; @@ -419,6 +415,12 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t 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) { if (tlen < 4) break;