Originally committed as revision 19884 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -51,37 +51,56 @@ typedef struct {
|
| 51 | 51 |
int64_t samples; |
| 52 | 52 |
} MPCContext; |
| 53 | 53 |
|
| 54 |
+static inline int64_t bs_get_v(uint8_t **bs) |
|
| 55 |
+{
|
|
| 56 |
+ int64_t v = 0; |
|
| 57 |
+ int br = 0; |
|
| 58 |
+ int c; |
|
| 59 |
+ |
|
| 60 |
+ do {
|
|
| 61 |
+ c = **bs; (*bs)++; |
|
| 62 |
+ v <<= 7; |
|
| 63 |
+ v |= c & 0x7F; |
|
| 64 |
+ br++; |
|
| 65 |
+ if (br > 10) |
|
| 66 |
+ return -1; |
|
| 67 |
+ } while (c & 0x80); |
|
| 68 |
+ |
|
| 69 |
+ return v - br; |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 54 | 72 |
static int mpc8_probe(AVProbeData *p) |
| 55 | 73 |
{
|
| 74 |
+ uint8_t *bs = p->buf + 4; |
|
| 75 |
+ uint8_t *bs_end = bs + p->buf_size; |
|
| 76 |
+ int64_t size; |
|
| 77 |
+ |
|
| 56 | 78 |
if (p->buf_size < 16) |
| 57 | 79 |
return 0; |
| 58 | 80 |
if (AV_RL32(p->buf) != TAG_MPCK) |
| 59 | 81 |
return 0; |
| 60 |
- if (p->buf[4] == 'S' && p->buf[5] == 'H') {
|
|
| 61 |
- int size = p->buf[6]; |
|
| 62 |
- |
|
| 63 |
- if (size < 12 || size > 30) |
|
| 64 |
- return 0; |
|
| 65 |
- if (!AV_RL32(&p->buf[7])) //zero CRC is invalid |
|
| 82 |
+ while (bs < bs_end + 3) {
|
|
| 83 |
+ int header_found = (bs[0] == 'S' && bs[1] == 'H'); |
|
| 84 |
+ if (bs[0] < 'A' || bs[0] > 'Z' || bs[1] < 'A' || bs[1] > 'Z') |
|
| 66 | 85 |
return 0; |
| 67 |
- //check whether some tag follows stream header or not |
|
| 68 |
- if (p->buf[4 + size] < 'A' || p->buf[4 + size] > 'Z') |
|
| 86 |
+ bs += 2; |
|
| 87 |
+ size = bs_get_v(&bs); |
|
| 88 |
+ if (size < 2) |
|
| 69 | 89 |
return 0; |
| 70 |
- if (p->buf[5 + size] < 'A' || p->buf[5 + size] > 'Z') |
|
| 90 |
+ if (bs + size - 2 >= bs_end) |
|
| 91 |
+ return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet |
|
| 92 |
+ if (header_found) {
|
|
| 93 |
+ |
|
| 94 |
+ if (size < 11 || size > 28) |
|
| 71 | 95 |
return 0; |
| 72 |
- if (p->buf[6 + size] < 3) |
|
| 96 |
+ if (!AV_RL32(bs)) //zero CRC is invalid |
|
| 73 | 97 |
return 0; |
| 74 | 98 |
return AVPROBE_SCORE_MAX; |
| 99 |
+ } else {
|
|
| 100 |
+ bs += size - 2; |
|
| 101 |
+ } |
|
| 75 | 102 |
} |
| 76 |
- /* file magic number should be followed by tag name which consists of |
|
| 77 |
- two uppercase letters */ |
|
| 78 |
- if (p->buf[4] < 'A' || p->buf[4] > 'Z' || p->buf[5] < 'A' || p->buf[5] > 'Z') |
|
| 79 |
- return 0; |
|
| 80 |
- // tag size should be >= 3 |
|
| 81 |
- if (p->buf[6] < 3) |
|
| 82 |
- return 0; |
|
| 83 |
- // if first tag is not stream header, that's suspicious |
|
| 84 |
- return AVPROBE_SCORE_MAX / 4; |
|
| 103 |
+ return 0; |
|
| 85 | 104 |
} |
| 86 | 105 |
|
| 87 | 106 |
static inline int64_t gb_get_v(GetBitContext *gb) |