Dana 17. 6. 2015. 00:28 osoba "Rodger Combs" <rodger.co...@gmail.com> napisala je: > > --- > libavcodec/utils.c | 4 ++ > libavformat/Makefile | 1 + > libavformat/allformats.c | 1 + > libavformat/brstm.c | 129 +++++++++++++++++++++++++++++++++++++++-------- > 4 files changed, 115 insertions(+), 20 deletions(-) > > diff --git a/libavcodec/utils.c b/libavcodec/utils.c > index 558afeb..a444a5e 100644 > --- a/libavcodec/utils.c > +++ b/libavcodec/utils.c > @@ -3430,6 +3430,10 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) > return (frame_bytes - 4) * 2 / ch; > case AV_CODEC_ID_ADPCM_IMA_AMV: > return (frame_bytes - 8) * 2 / ch; > + case AV_CODEC_ID_ADPCM_THP: > + if (avctx->extradata) > + return frame_bytes * 14 / (8 * ch); > + break; > case AV_CODEC_ID_ADPCM_XA: > return (frame_bytes / 128) * 224 / ch; > case AV_CODEC_ID_INTERPLAY_DPCM: > diff --git a/libavformat/Makefile b/libavformat/Makefile > index b9169d9..3c2cf9f 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -106,6 +106,7 @@ OBJS-$(CONFIG_BIT_MUXER) += bit.o > OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o > OBJS-$(CONFIG_BOA_DEMUXER) += boadec.o > OBJS-$(CONFIG_BRSTM_DEMUXER) += brstm.o > +OBJS-$(CONFIG_BFSTM_DEMUXER) += brstm.o
Not in alphabetical order. > OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o > OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \ > isom.o replaygain.o > diff --git a/libavformat/allformats.c b/libavformat/allformats.c > index 3a49650..cc77d1c 100644 > --- a/libavformat/allformats.c > +++ b/libavformat/allformats.c > @@ -93,6 +93,7 @@ void av_register_all(void) > REGISTER_MUXDEMUX(BIT, bit); > REGISTER_DEMUXER (BMV, bmv); > REGISTER_DEMUXER (BRSTM, brstm); > + REGISTER_DEMUXER (BFSTM, bfstm); not in alphabetical order > REGISTER_DEMUXER (BOA, boa); > REGISTER_DEMUXER (C93, c93); > REGISTER_MUXDEMUX(CAF, caf); > diff --git a/libavformat/brstm.c b/libavformat/brstm.c > index 19a4a2a..1eba943 100644 > --- a/libavformat/brstm.c > +++ b/libavformat/brstm.c > @@ -32,6 +32,7 @@ typedef struct BRSTMDemuxContext { > uint32_t last_block_used_bytes; > uint8_t *table; > uint8_t *adpc; > + int bfstm; > } BRSTMDemuxContext; > > static int probe(AVProbeData *p) > @@ -43,6 +44,15 @@ static int probe(AVProbeData *p) > return 0; > } > > +static int probe_bfstm(AVProbeData *p) > +{ > + if (AV_RL32(p->buf) == MKTAG('F','S','T','M') && > + (AV_RL16(p->buf + 4) == 0xFFFE || > + AV_RL16(p->buf + 4) == 0xFEFF)) > + return AVPROBE_SCORE_MAX / 3 * 2; > + return 0; > +} > + > static int read_close(AVFormatContext *s) > { > BRSTMDemuxContext *b = s->priv_data; > @@ -57,11 +67,13 @@ static int read_header(AVFormatContext *s) > { > BRSTMDemuxContext *b = s->priv_data; > int bom, major, minor, codec, chunk; > - int64_t pos, h1offset, toffset; > + int64_t h1offset, pos, toffset, data_offset = 0; > uint32_t size, start, asize; > AVStream *st; > int ret = AVERROR_EOF; > > + b->bfstm = !strcmp("bfstm", s->iformat->name); > + > st = avformat_new_stream(s, NULL); > if (!st) > return AVERROR(ENOMEM); > @@ -79,19 +91,65 @@ static int read_header(AVFormatContext *s) > return AVERROR_PATCHWELCOME; > } > > - major = avio_r8(s->pb); > - minor = avio_r8(s->pb); > - avio_skip(s->pb, 4); // size of file > - size = avio_rb16(s->pb); > - if (size < 14) > - return AVERROR_INVALIDDATA; > + if (!b->bfstm) { > + major = avio_r8(s->pb); > + minor = avio_r8(s->pb); > + avio_skip(s->pb, 4); // size of file > + size = avio_rb16(s->pb); > + if (size < 14) > + return AVERROR_INVALIDDATA; > + > + avio_skip(s->pb, size - 14); > + pos = avio_tell(s->pb); > + if (avio_rl32(s->pb) != MKTAG('H','E','A','D')) > + return AVERROR_INVALIDDATA; > + } else { > + uint32_t info_offset = 0, info_size; > + uint16_t section_count, header_size, i; > + > + header_size = avio_rb16(s->pb); // 6 > + > + avio_skip(s->pb, 4); // Unknown constant 0x00030000 > + avio_skip(s->pb, 4); // size of file > + section_count = avio_rb16(s->pb); > + avio_skip(s->pb, 2); // padding > + for (i = 0; avio_tell(s->pb) < header_size > + && !(data_offset && info_offset) > + && i < section_count; i++) { > + uint32_t flag = avio_rb32(s->pb); > + switch (flag) { > + case 0x40000000: > + info_offset = avio_rb32(s->pb); > + info_size = avio_rb32(s->pb); > + break; > + case 0x40010000: > + avio_skip(s->pb, 4); // seek offset > + avio_skip(s->pb, 4); // seek size > + break; > + case 0x40020000: > + data_offset = avio_rb32(s->pb); > + avio_skip(s->pb, 4); //data_size = avio_rb32(s->pb); > + break; > + case 0x40030000: > + avio_skip(s->pb, 4); // REGN offset > + avio_skip(s->pb, 4); // REGN size > + break; > + } > + } > + > + if (!info_offset || !data_offset) > + return AVERROR_INVALIDDATA; > + > + start = data_offset + 8; > + > + avio_skip(s->pb, info_offset - avio_tell(s->pb)); > + pos = avio_tell(s->pb); > + if (avio_rl32(s->pb) != MKTAG('I','N','F','O')) > + return AVERROR_INVALIDDATA; > + } > > - avio_skip(s->pb, size - 14); > - pos = avio_tell(s->pb); > - if (avio_rl32(s->pb) != MKTAG('H','E','A','D')) > - return AVERROR_INVALIDDATA; > size = avio_rb32(s->pb); > - if (size < 256) > + if (size < 192) > return AVERROR_INVALIDDATA; > avio_skip(s->pb, 4); // unknown > h1offset = avio_rb32(s->pb); > @@ -121,17 +179,22 @@ static int read_header(AVFormatContext *s) > return AVERROR_INVALIDDATA; > > avio_skip(s->pb, 1); // padding > + if (b->bfstm) > + avio_skip(s->pb, 2); // padding > + > st->codec->sample_rate = avio_rb16(s->pb); > if (!st->codec->sample_rate) > return AVERROR_INVALIDDATA; > > - avio_skip(s->pb, 2); // padding > + if (!b->bfstm) > + avio_skip(s->pb, 2); // padding > avio_skip(s->pb, 4); // loop start sample > st->start_time = 0; > st->duration = avio_rb32(s->pb); > avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); > > - start = avio_rb32(s->pb); > + if (!b->bfstm) > + start = avio_rb32(s->pb); > b->current_block = 0; > b->block_count = avio_rb32(s->pb); > if (b->block_count > UINT16_MAX) { > @@ -157,7 +220,10 @@ static int read_header(AVFormatContext *s) > int ch; > > avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); > - toffset = avio_rb32(s->pb) + 16LL; > + if (!b->bfstm) > + toffset = avio_rb32(s->pb) + 16LL; > + else > + toffset = toffset + avio_rb32(s->pb) + st->codec->channels * 8 - 8; > if (toffset > size) > return AVERROR_INVALIDDATA; > > @@ -171,7 +237,15 @@ static int read_header(AVFormatContext *s) > ret = AVERROR_INVALIDDATA; > goto fail; > } > - avio_skip(s->pb, 24); > + avio_skip(s->pb, b->bfstm ? 14 : 24); > + } > + > + if (b->bfstm) { > + st->codec->extradata_size = 32 * st->codec->channels; > + st->codec->extradata = av_malloc(st->codec->extradata_size); > + if (!st->codec->extradata) > + return AVERROR(ENOMEM); > + memcpy(st->codec->extradata, b->table, st->codec->extradata_size); > } > } > > @@ -179,7 +253,11 @@ static int read_header(AVFormatContext *s) > ret = AVERROR_INVALIDDATA; > goto fail; > } > - avio_skip(s->pb, size - (avio_tell(s->pb) - pos)); > + > + if (!b->bfstm) > + avio_skip(s->pb, size - (avio_tell(s->pb) - pos)); > + else > + avio_skip(s->pb, data_offset - avio_tell(s->pb)); > > while (!avio_feof(s->pb)) { > chunk = avio_rl32(s->pb); > @@ -214,13 +292,13 @@ static int read_header(AVFormatContext *s) > break; > case MKTAG('D','A','T','A'): > if ((start < avio_tell(s->pb)) || > - (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) { > + (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP && !b->bfstm)) { > ret = AVERROR_INVALIDDATA; > goto fail; > } > avio_skip(s->pb, start - avio_tell(s->pb)); > > - if (major != 1 || minor) > + if ((major != 1 || minor) && !b->bfstm) > avpriv_request_sample(s, "Version %d.%d", major, minor); > > return 0; > @@ -257,7 +335,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) > return AVERROR_EOF; > } > > - if (codec->codec_id == AV_CODEC_ID_ADPCM_THP) { > + if (codec->codec_id == AV_CODEC_ID_ADPCM_THP && !codec->extradata) { > uint8_t *dst; > > if (av_new_packet(pkt, 8 + (32 + 4) * codec->channels + size) < 0) > @@ -295,3 +373,14 @@ AVInputFormat ff_brstm_demuxer = { > .read_close = read_close, > .extensions = "brstm", > }; > + > +AVInputFormat ff_bfstm_demuxer = { > + .name = "bfstm", > + .long_name = NULL_IF_CONFIG_SMALL("BFSTM (Binary Cafe Stream)"), > + .priv_data_size = sizeof(BRSTMDemuxContext), > + .read_probe = probe_bfstm, > + .read_header = read_header, > + .read_packet = read_packet, > + .read_close = read_close, > + .extensions = "bfstm", > +}; > -- > 2.4.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Missing minor bump and changelog entry, rest lgtm. What about fate test? _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel