mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
avformat/brstm: fix decoding brstm with custom coeff offsets
This commit is contained in:
parent
61d767f3a3
commit
3382b0290a
@ -24,6 +24,11 @@
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef struct BRSTMCoeffOffset {
|
||||
uint8_t channel;
|
||||
uint32_t offset;
|
||||
} BRSTMCoeffOffset;
|
||||
|
||||
typedef struct BRSTMDemuxContext {
|
||||
uint32_t block_size;
|
||||
uint32_t block_count;
|
||||
@ -35,6 +40,7 @@ typedef struct BRSTMDemuxContext {
|
||||
uint32_t data_start;
|
||||
uint8_t *table;
|
||||
uint8_t *adpc;
|
||||
BRSTMCoeffOffset offsets[256];
|
||||
int little_endian;
|
||||
} BRSTMDemuxContext;
|
||||
|
||||
@ -67,6 +73,13 @@ static int read_close(AVFormatContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sort_offsets(const void *a, const void *b)
|
||||
{
|
||||
const BRSTMCoeffOffset *s1 = a;
|
||||
const BRSTMCoeffOffset *s2 = b;
|
||||
return FFDIFFSIGN(s1->offset, s2->offset);
|
||||
}
|
||||
|
||||
static av_always_inline unsigned int read16(AVFormatContext *s)
|
||||
{
|
||||
BRSTMDemuxContext *b = s->priv_data;
|
||||
@ -259,17 +272,33 @@ static int read_header(AVFormatContext *s)
|
||||
if (toffset > size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (!bfstm) {
|
||||
avio_skip(s->pb, pos + toffset - avio_tell(s->pb) - 8LL * (st->codecpar->channels + 1));
|
||||
for (ch = 0; ch < st->codecpar->channels; ch++) {
|
||||
avio_skip(s->pb, 4);
|
||||
b->offsets[ch].channel = ch;
|
||||
b->offsets[ch].offset = read32(s);
|
||||
}
|
||||
|
||||
qsort(b->offsets, st->codecpar->channels, sizeof(*b->offsets), sort_offsets);
|
||||
}
|
||||
|
||||
avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
|
||||
b->table = av_mallocz(32 * st->codecpar->channels);
|
||||
if (!b->table)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (ch = 0; ch < st->codecpar->channels; ch++) {
|
||||
if (!bfstm)
|
||||
avio_skip(s->pb, pos + 16LL + b->offsets[ch].offset - avio_tell(s->pb));
|
||||
|
||||
if (avio_read(s->pb, b->table + ch * 32, 32) != 32) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
avio_skip(s->pb, bfstm ? 14 : 24);
|
||||
|
||||
if (bfstm)
|
||||
avio_skip(s->pb, 14);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user