示例#1
0
static int nsv_parse_NSVf_header(AVFormatContext *s)
{
    NSVContext *nsv = s->priv_data;
    AVIOContext *pb = s->pb;
    unsigned int file_size;
    unsigned int size;
    int64_t duration;
    int strings_size;
    int table_entries;
    int table_entries_used;

    av_dlog(s, "%s()\n", __FUNCTION__);

    nsv->state = NSV_UNSYNC; /* in case we fail */

    size = avio_rl32(pb);
    if (size < 28)
        return -1;
    nsv->NSVf_end = size;

    //s->file_size = (uint32_t)avio_rl32(pb);
    file_size = (uint32_t)avio_rl32(pb);
    av_dlog(s, "NSV NSVf chunk_size %u\n", size);
    av_dlog(s, "NSV NSVf file_size %u\n", file_size);

    nsv->duration = duration = avio_rl32(pb); /* in ms */
    av_dlog(s, "NSV NSVf duration %"PRId64" ms\n", duration);
    // XXX: store it in AVStreams

    strings_size = avio_rl32(pb);
    table_entries = avio_rl32(pb);
    table_entries_used = avio_rl32(pb);
    av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
            strings_size, table_entries, table_entries_used);
    if (pb->eof_reached)
        return -1;

    av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));

    if (strings_size > 0) {
        char *strings; /* last byte will be '\0' to play safe with str*() */
        char *p, *endp;
        char *token, *value;
        char quote;

        p = strings = av_mallocz((size_t)strings_size + 1);
        if (!p)
            return AVERROR(ENOMEM);
        endp = strings + strings_size;
        avio_read(pb, strings, strings_size);
        while (p < endp) {
            while (*p == ' ')
                p++; /* strip out spaces */
            if (p >= endp-2)
                break;
            token = p;
            p = strchr(p, '=');
            if (!p || p >= endp-2)
                break;
            *p++ = '\0';
            quote = *p++;
            value = p;
            p = strchr(p, quote);
            if (!p || p >= endp)
                break;
            *p++ = '\0';
            av_dlog(s, "NSV NSVf INFO: %s='%s'\n", token, value);
            av_dict_set(&s->metadata, token, value, 0);
        }
        av_free(strings);
    }
    if (pb->eof_reached)
        return -1;

    av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));

    if (table_entries_used > 0) {
        int i;
        nsv->index_entries = table_entries_used;
        if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t))
            return -1;
        nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t));
        if (!nsv->nsvs_file_offset)
            return AVERROR(ENOMEM);

        for(i=0;i<table_entries_used;i++)
            nsv->nsvs_file_offset[i] = avio_rl32(pb) + size;

        if(table_entries > table_entries_used &&
           avio_rl32(pb) == MKTAG('T','O','C','2')) {
            nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t));
            if (!nsv->nsvs_timestamps)
                return AVERROR(ENOMEM);
            for(i=0;i<table_entries_used;i++) {
                nsv->nsvs_timestamps[i] = avio_rl32(pb);
            }
        }
    }

    av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));

#ifdef DEBUG_DUMP_INDEX
#define V(v) ((v<0x20 || v > 127)?'.':v)
    /* dump index */
    av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries);
    av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries);
    for (i = 0; i < table_entries; i++) {
        unsigned char b[8];
        avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET);
        avio_read(pb, b, 8);
        av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x"
           "%c%c%c%c%c%c%c%c\n",
           nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i],
           b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
           V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) );
    }
    //avio_seek(pb, size, SEEK_SET); /* go back to end of header */
#undef V
#endif

    avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */

    if (pb->eof_reached)
        return -1;
    nsv->state = NSV_HAS_READ_NSVF;
    return 0;
}
示例#2
0
/**
 * read rl2 header data and setup the avstreams
 * @param s demuxer context
 * @return 0 on success, AVERROR otherwise
 */
static av_cold int rl2_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    AVStream *st;
    unsigned int frame_count;
    unsigned int audio_frame_counter = 0;
    unsigned int video_frame_counter = 0;
    unsigned int back_size;
    unsigned short sound_rate;
    unsigned short rate;
    unsigned short channels;
    unsigned short def_sound_size;
    unsigned int signature;
    unsigned int pts_den = 11025; /* video only case */
    unsigned int pts_num = 1103;
    unsigned int* chunk_offset = NULL;
    int* chunk_size = NULL;
    int* audio_size = NULL;
    int i;
    int ret = 0;

    avio_skip(pb,4);          /* skip FORM tag */
    back_size = avio_rl32(pb); /**< get size of the background frame */
    signature = avio_rb32(pb);
    avio_skip(pb, 4);         /* data size */
    frame_count = avio_rl32(pb);

    /* disallow back_sizes and frame_counts that may lead to overflows later */
    if(back_size > INT_MAX/2  || frame_count > INT_MAX / sizeof(uint32_t))
        return AVERROR_INVALIDDATA;

    avio_skip(pb, 2);         /* encoding mentod */
    sound_rate = avio_rl16(pb);
    rate = avio_rl16(pb);
    channels = avio_rl16(pb);
    def_sound_size = avio_rl16(pb);

    /** setup video stream */
    st = avformat_new_stream(s, NULL);
    if(!st)
         return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = AV_CODEC_ID_RL2;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = 320;
    st->codec->height = 200;

    /** allocate and fill extradata */
    st->codec->extradata_size = EXTRADATA1_SIZE;

    if(signature == RLV3_TAG && back_size > 0)
        st->codec->extradata_size += back_size;

    if(ff_get_extradata(st->codec, pb, st->codec->extradata_size) < 0)
        return AVERROR(ENOMEM);

    /** setup audio stream if present */
    if(sound_rate){
        if (!channels || channels > 42) {
            av_log(s, AV_LOG_ERROR, "Invalid number of channels: %d\n", channels);
            return AVERROR_INVALIDDATA;
        }

        pts_num = def_sound_size;
        pts_den = rate;

        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = AV_CODEC_ID_PCM_U8;
        st->codec->codec_tag = 1;
        st->codec->channels = channels;
        st->codec->bits_per_coded_sample = 8;
        st->codec->sample_rate = rate;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
            st->codec->bits_per_coded_sample;
        st->codec->block_align = st->codec->channels *
            st->codec->bits_per_coded_sample / 8;
        avpriv_set_pts_info(st,32,1,rate);
    }

    avpriv_set_pts_info(s->streams[0], 32, pts_num, pts_den);

    chunk_size =   av_malloc(frame_count * sizeof(uint32_t));
    audio_size =   av_malloc(frame_count * sizeof(uint32_t));
    chunk_offset = av_malloc(frame_count * sizeof(uint32_t));

    if(!chunk_size || !audio_size || !chunk_offset){
        av_free(chunk_size);
        av_free(audio_size);
        av_free(chunk_offset);
        return AVERROR(ENOMEM);
    }

    /** read offset and size tables */
    for(i=0; i < frame_count;i++) {
        if (avio_feof(pb))
            return AVERROR_INVALIDDATA;
        chunk_size[i] = avio_rl32(pb);
    }
    for(i=0; i < frame_count;i++) {
        if (avio_feof(pb))
            return AVERROR_INVALIDDATA;
        chunk_offset[i] = avio_rl32(pb);
    }
    for(i=0; i < frame_count;i++) {
        if (avio_feof(pb))
            return AVERROR_INVALIDDATA;
        audio_size[i] = avio_rl32(pb) & 0xFFFF;
    }

    /** build the sample index */
    for(i=0;i<frame_count;i++){
        if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){
            ret = AVERROR_INVALIDDATA;
            break;
        }

        if(sound_rate && audio_size[i]){
            av_add_index_entry(s->streams[1], chunk_offset[i],
                audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME);
            audio_frame_counter += audio_size[i] / channels;
        }
        av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i],
            video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME);
        ++video_frame_counter;
    }


    av_free(chunk_size);
    av_free(audio_size);
    av_free(chunk_offset);

    return ret;
}
示例#3
0
文件: wv.c 项目: mfpgt/FFmpeg
static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int append)
{
    WVContext *wc = ctx->priv_data;
    uint32_t tag, ver;
    int size;
    int rate, bpp, chan;
    uint32_t chmask;

    wc->pos = avio_tell(pb);
    if(!append){
        tag = avio_rl32(pb);
        if (tag != MKTAG('w', 'v', 'p', 'k'))
            return -1;
        size = avio_rl32(pb);
        if(size < 24 || size > WV_BLOCK_LIMIT){
            av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
            return -1;
        }
        wc->blksize = size;
        ver = avio_rl16(pb);
        if(ver < 0x402 || ver > 0x410){
            av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
            return -1;
        }
        avio_r8(pb); // track no
        avio_r8(pb); // track sub index
        wc->samples = avio_rl32(pb); // total samples in file
        wc->soff = avio_rl32(pb); // offset in samples of current block
        avio_read(pb, wc->extra, WV_EXTRA_SIZE);
    }else{
        size = wc->blksize;
    }
    wc->flags = AV_RL32(wc->extra + 4);
    // blocks with zero samples don't contain actual audio information and should be ignored
    if (!AV_RN32(wc->extra))
        return 0;
    //parse flags
    bpp = ((wc->flags & 3) + 1) << 3;
    chan = 1 + !(wc->flags & WV_MONO);
    chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
    rate = wv_rates[(wc->flags >> 23) & 0xF];
    wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK);
    if(wc->multichannel){
        chan = wc->chan;
        chmask = wc->chmask;
    }
    if((rate == -1 || !chan) && !wc->block_parsed){
        int64_t block_end = avio_tell(pb) + wc->blksize - 24;
        if(!pb->seekable){
            av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n");
            return -1;
        }
        while(avio_tell(pb) < block_end){
            int id, size;
            id = avio_r8(pb);
            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
            size <<= 1;
            if(id&0x40)
                size--;
            switch(id&0x3F){
            case 0xD:
                if(size <= 1){
                    av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n");
                    return -1;
                }
                chan = avio_r8(pb);
                switch(size - 2){
                case 0:
                    chmask = avio_r8(pb);
                    break;
                case 1:
                    chmask = avio_rl16(pb);
                    break;
                case 2:
                    chmask = avio_rl24(pb);
                    break;
                case 3:
                    chmask = avio_rl32(pb);
                    break;
                case 5:
                    avio_skip(pb, 1);
                    chan |= (avio_r8(pb) & 0xF) << 8;
                    chmask = avio_rl24(pb);
                    break;
                default:
                    av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size);
                    return -1;
                }
                break;
            case 0x27:
                rate = avio_rl24(pb);
                break;
            default:
                avio_skip(pb, size);
            }
            if(id&0x40)
                avio_skip(pb, 1);
        }
        if(rate == -1){
            av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
            return -1;
        }
        avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET);
    }
    if(!wc->bpp) wc->bpp = bpp;
    if(!wc->chan) wc->chan = chan;
    if(!wc->chmask) wc->chmask = chmask;
    if(!wc->rate) wc->rate = rate;

    if(wc->flags && bpp != wc->bpp){
        av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp);
        return -1;
    }
    if(wc->flags && !wc->multichannel && chan != wc->chan){
        av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
        return -1;
    }
    if(wc->flags && rate != -1 && rate != wc->rate){
        av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
        return -1;
    }
    wc->blksize = size - 24;
    return 0;
}
示例#4
0
文件: tta.c 项目: NeeMeese/mplayer-ce
static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    TTAContext *c = s->priv_data;
    AVStream *st;
    int i, channels, bps, samplerate, datalen, framelen;
    uint64_t framepos, start_offset;

    if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
        ff_id3v1_read(s);

    start_offset = url_ftell(s->pb);
    if (avio_rl32(s->pb) != AV_RL32("TTA1"))
        return -1; // not tta file

    avio_seek(s->pb, 2, SEEK_CUR); // FIXME: flags
    channels = avio_rl16(s->pb);
    bps = avio_rl16(s->pb);
    samplerate = avio_rl32(s->pb);
    if(samplerate <= 0 || samplerate > 1000000){
        av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
        return -1;
    }

    datalen = avio_rl32(s->pb);
    if(datalen < 0){
        av_log(s, AV_LOG_ERROR, "nonsense datalen\n");
        return -1;
    }

    avio_seek(s->pb, 4, SEEK_CUR); // header crc

    framelen = samplerate*256/245;
    c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0);
    c->currentframe = 0;

    if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){
        av_log(s, AV_LOG_ERROR, "totalframes too large\n");
        return -1;
    }

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);

    av_set_pts_info(st, 64, 1, samplerate);
    st->start_time = 0;
    st->duration = datalen;

    framepos = url_ftell(s->pb) + 4*c->totalframes + 4;

    for (i = 0; i < c->totalframes; i++) {
        uint32_t size = avio_rl32(s->pb);
        av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME);
        framepos += size;
    }
    avio_seek(s->pb, 4, SEEK_CUR); // seektable crc

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_TTA;
    st->codec->channels = channels;
    st->codec->sample_rate = samplerate;
    st->codec->bits_per_coded_sample = bps;

    st->codec->extradata_size = url_ftell(s->pb) - start_offset;
    if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
        //this check is redundant as avio_read should fail
        av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
        return -1;
    }
    st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
    avio_seek(s->pb, start_offset, SEEK_SET);
    avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);

    return 0;
}
示例#5
0
static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    APNGDemuxContext *ctx = s->priv_data;
    int64_t ret;
    int64_t size;
    AVIOContext *pb = s->pb;
    uint32_t len, tag;

    /*
     * fcTL chunk length, in bytes:
     *  4 (length)
     *  4 (tag)
     * 26 (actual chunk)
     *  4 (crc) bytes
     * and needed next:
     *  4 (length)
     *  4 (tag (must be fdAT or IDAT))
     */
    /* if num_play is not 1, then the seekback is already guaranteed */
    if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 46)) < 0)
        return ret;

    len = avio_rb32(pb);
    tag = avio_rl32(pb);

    if (avio_feof(pb))
        return AVERROR_EOF;

    switch (tag) {
    case MKTAG('f', 'c', 'T', 'L'):
        if (len != 26)
            return AVERROR_INVALIDDATA;

        if ((ret = decode_fctl_chunk(s, ctx, pkt)) < 0)
            return ret;

        /* fcTL must precede fdAT or IDAT */
        len = avio_rb32(pb);
        tag = avio_rl32(pb);
        if (len > 0x7fffffff ||
            tag != MKTAG('f', 'd', 'A', 'T') &&
            tag != MKTAG('I', 'D', 'A', 'T'))
            return AVERROR_INVALIDDATA;

        size = 38 /* fcTL */ + 8 /* len, tag */ + len + 4 /* crc */;
        if (size > INT_MAX)
            return AVERROR(EINVAL);

        if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0 ||
            (ret = av_append_packet(pb, pkt, size)) < 0)
            return ret;

        if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
            return ret;

        len = avio_rb32(pb);
        tag = avio_rl32(pb);
        while (tag &&
               tag != MKTAG('f', 'c', 'T', 'L') &&
               tag != MKTAG('I', 'E', 'N', 'D')) {
            if (len > 0x7fffffff)
                return AVERROR_INVALIDDATA;
            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
                (ret = av_append_packet(pb, pkt, len + 12)) < 0)
                return ret;
            if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
                return ret;
            len = avio_rb32(pb);
            tag = avio_rl32(pb);
        }
        if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
            return ret;

        if (ctx->is_key_frame)
            pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->pts = pkt->dts = AV_NOPTS_VALUE;
        pkt->duration = ctx->pkt_duration;
        return ret;
    case MKTAG('I', 'E', 'N', 'D'):
        ctx->cur_loop++;
        if (ctx->ignore_loop || ctx->num_play >= 1 && ctx->cur_loop == ctx->num_play) {
            avio_seek(pb, -8, SEEK_CUR);
            return AVERROR_EOF;
        }
        if ((ret = avio_seek(pb, s->streams[0]->codecpar->extradata_size + 8, SEEK_SET)) < 0)
            return ret;
        return 0;
    default:
        avpriv_request_sample(s, "In-stream tag=%s (0x%08"PRIX32") len=%"PRIu32,
                              av_fourcc2str(tag), tag, len);
        avio_skip(pb, len + 4);
    }

    /* Handle the unsupported yet cases */
    return AVERROR_PATCHWELCOME;
}
示例#6
0
文件: xwma.c 项目: lkiesow/FFmpeg
static int xwma_read_header(AVFormatContext *s)
{
    int64_t size;
    int ret = 0;
    uint32_t dpds_table_size = 0;
    uint32_t *dpds_table = NULL;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    AVStream *st;
    XWMAContext *xwma = s->priv_data;
    int i;

    /* The following code is mostly copied from wav.c, with some
     * minor alterations.
     */

    /* check RIFF header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('R', 'I', 'F', 'F'))
        return -1;
    avio_rl32(pb); /* file size */
    tag = avio_rl32(pb);
    if (tag != MKTAG('X', 'W', 'M', 'A'))
        return -1;

    /* parse fmt header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('f', 'm', 't', ' '))
        return -1;
    size = avio_rl32(pb);
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    ret = ff_get_wav_header(pb, st->codec, size, 0);
    if (ret < 0)
        return ret;
    st->need_parsing = AVSTREAM_PARSE_NONE;

    /* All xWMA files I have seen contained WMAv2 data. If there are files
     * using WMA Pro or some other codec, then we need to figure out the right
     * extradata for that. Thus, ask the user for feedback, but try to go on
     * anyway.
     */
    if (st->codec->codec_id != AV_CODEC_ID_WMAV2) {
        avpriv_request_sample(s, "Unexpected codec (tag 0x04%x; id %d)",
                              st->codec->codec_tag, st->codec->codec_id);
    } else {
        /* In all xWMA files I have seen, there is no extradata. But the WMA
         * codecs require extradata, so we provide our own fake extradata.
         *
         * First, check that there really was no extradata in the header. If
         * there was, then try to use it, after asking the user to provide a
         * sample of this unusual file.
         */
        if (st->codec->extradata_size != 0) {
            /* Surprise, surprise: We *did* get some extradata. No idea
             * if it will work, but just go on and try it, after asking
             * the user for a sample.
             */
            avpriv_request_sample(s, "Unexpected extradata (%d bytes)",
                                  st->codec->extradata_size);
        } else {
            st->codec->extradata_size = 6;
            st->codec->extradata      = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);

            /* setup extradata with our experimentally obtained value */
            st->codec->extradata[4] = 31;
        }
    }

    if (!st->codec->channels) {
        av_log(s, AV_LOG_WARNING, "Invalid channel count: %d\n",
               st->codec->channels);
        return AVERROR_INVALIDDATA;
    }
    if (!st->codec->bits_per_coded_sample) {
        av_log(s, AV_LOG_WARNING, "Invalid bits_per_coded_sample: %d\n",
               st->codec->bits_per_coded_sample);
        return AVERROR_INVALIDDATA;
    }

    /* set the sample rate */
    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    /* parse the remaining RIFF chunks */
    for (;;) {
        if (pb->eof_reached) {
            ret = AVERROR_EOF;
            goto fail;
        }
        /* read next chunk tag */
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
        if (tag == MKTAG('d', 'a', 't', 'a')) {
            /* We assume that the data chunk comes last. */
            break;
        } else if (tag == MKTAG('d','p','d','s')) {
            /* Quoting the MSDN xWMA docs on the dpds chunk: "Contains the
             * decoded packet cumulative data size array, each element is the
             * number of bytes accumulated after the corresponding xWMA packet
             * is decoded in order."
             *
             * Each packet has size equal to st->codec->block_align, which in
             * all cases I saw so far was always 2230. Thus, we can use the
             * dpds data to compute a seeking index.
             */

            /* Error out if there is more than one dpds chunk. */
            if (dpds_table) {
                av_log(s, AV_LOG_ERROR, "two dpds chunks present\n");
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }

            /* Compute the number of entries in the dpds chunk. */
            if (size & 3) {  /* Size should be divisible by four */
                av_log(s, AV_LOG_WARNING,
                       "dpds chunk size %"PRId64" not divisible by 4\n", size);
            }
            dpds_table_size = size / 4;
            if (dpds_table_size == 0 || dpds_table_size >= INT_MAX / 4) {
                av_log(s, AV_LOG_ERROR,
                       "dpds chunk size %"PRId64" invalid\n", size);
                return AVERROR_INVALIDDATA;
            }

            /* Allocate some temporary storage to keep the dpds data around.
             * for processing later on.
             */
            dpds_table = av_malloc(dpds_table_size * sizeof(uint32_t));
            if (!dpds_table) {
                return AVERROR(ENOMEM);
            }

            for (i = 0; i < dpds_table_size; ++i) {
                dpds_table[i] = avio_rl32(pb);
                size -= 4;
            }
        }
        avio_skip(pb, size);
    }

    /* Determine overall data length */
    if (size < 0) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }
    if (!size) {
        xwma->data_end = INT64_MAX;
    } else
        xwma->data_end = avio_tell(pb) + size;


    if (dpds_table && dpds_table_size) {
        int64_t cur_pos;
        const uint32_t bytes_per_sample
                = (st->codec->channels * st->codec->bits_per_coded_sample) >> 3;

        /* Estimate the duration from the total number of output bytes. */
        const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1];

        if (!bytes_per_sample) {
            av_log(s, AV_LOG_ERROR,
                   "Invalid bits_per_coded_sample %d for %d channels\n",
                   st->codec->bits_per_coded_sample, st->codec->channels);
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }

        st->duration = total_decoded_bytes / bytes_per_sample;

        /* Use the dpds data to build a seek table.  We can only do this after
         * we know the offset to the data chunk, as we need that to determine
         * the actual offset to each input block.
         * Note: If we allowed ourselves to assume that the data chunk always
         * follows immediately after the dpds block, we could of course guess
         * the data block's start offset already while reading the dpds chunk.
         * I decided against that, just in case other chunks ever are
         * discovered.
         */
        cur_pos = avio_tell(pb);
        for (i = 0; i < dpds_table_size; ++i) {
            /* From the number of output bytes that would accumulate in the
             * output buffer after decoding the first (i+1) packets, we compute
             * an offset / timestamp pair.
             */
            av_add_index_entry(st,
                               cur_pos + (i+1) * st->codec->block_align, /* pos */
                               dpds_table[i] / bytes_per_sample,         /* timestamp */
                               st->codec->block_align,                   /* size */
                               0,                                        /* duration */
                               AVINDEX_KEYFRAME);
        }
    } else if (st->codec->bit_rate) {
示例#7
0
/* Returns the number of sound data frames or negative on error */
static unsigned int get_aiff_header(AVIOContext *pb, AVCodecContext *codec,
                             int size, unsigned version)
{
    int exp;
    uint64_t val;
    double sample_rate;
    unsigned int num_frames;

    if (size & 1)
        size++;
    codec->codec_type = AVMEDIA_TYPE_AUDIO;
    codec->channels = avio_rb16(pb);
    num_frames = avio_rb32(pb);
    codec->bits_per_coded_sample = avio_rb16(pb);

    exp = avio_rb16(pb);
    val = avio_rb64(pb);
    sample_rate = ldexp((double)val, exp - 16383 - 63);
    codec->sample_rate = sample_rate;
    size -= 18;

    /* Got an AIFF-C? */
    if (version == AIFF_C_VERSION1) {
        codec->codec_tag = avio_rl32(pb);
        codec->codec_id  = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag);

        switch (codec->codec_id) {
        case CODEC_ID_PCM_S16BE:
            codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
            codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
            break;
        case CODEC_ID_ADPCM_IMA_QT:
            codec->block_align = 34*codec->channels;
            codec->frame_size = 64;
            break;
        case CODEC_ID_MACE3:
            codec->block_align = 2*codec->channels;
            codec->frame_size = 6;
            break;
        case CODEC_ID_MACE6:
            codec->block_align = 1*codec->channels;
            codec->frame_size = 6;
            break;
        case CODEC_ID_GSM:
            codec->block_align = 33;
            codec->frame_size = 160;
            break;
        case CODEC_ID_QCELP:
            codec->block_align = 35;
            codec->frame_size= 160;
            break;
        default:
            break;
        }
        size -= 4;
    } else {
        /* Need the codec type */
        codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
        codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
    }

    /* Block align needs to be computed in all cases, as the definition
     * is specific to applications -> here we use the WAVE format definition */
    if (!codec->block_align)
        codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3;

    codec->bit_rate = (codec->frame_size ? codec->sample_rate/codec->frame_size :
                       codec->sample_rate) * (codec->block_align << 3);

    /* Chunk is over */
    if (size)
        avio_skip(pb, size);

    return num_frames;
}
示例#8
0
static int idcin_read_packet(AVFormatContext *s,
                             AVPacket *pkt)
{
    int ret;
    unsigned int command;
    unsigned int chunk_size;
    IdcinDemuxContext *idcin = s->priv_data;
    AVIOContext *pb = s->pb;
    int i;
    int palette_scale;
    unsigned char r, g, b;
    unsigned char palette_buffer[768];
    uint32_t palette[256];

    if (s->pb->eof_reached)
        return AVERROR(EIO);

    if (idcin->next_chunk_is_video) {
        command = avio_rl32(pb);
        if (command == 2) {
            return AVERROR(EIO);
        } else if (command == 1) {
            /* trigger a palette change */
            if (avio_read(pb, palette_buffer, 768) != 768)
                return AVERROR(EIO);
            /* scale the palette as necessary */
            palette_scale = 2;
            for (i = 0; i < 768; i++)
                if (palette_buffer[i] > 63) {
                    palette_scale = 0;
                    break;
                }

            for (i = 0; i < 256; i++) {
                r = palette_buffer[i * 3    ] << palette_scale;
                g = palette_buffer[i * 3 + 1] << palette_scale;
                b = palette_buffer[i * 3 + 2] << palette_scale;
                palette[i] = (r << 16) | (g << 8) | (b);
            }
        }

        chunk_size = avio_rl32(pb);
        /* skip the number of decoded bytes (always equal to width * height) */
        avio_skip(pb, 4);
        chunk_size -= 4;
        ret= av_get_packet(pb, pkt, chunk_size);
        if (ret < 0)
            return ret;
        if (command == 1) {
            uint8_t *pal;

            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                          AVPALETTE_SIZE);
            if (ret < 0)
                return ret;
            memcpy(pal, palette, AVPALETTE_SIZE);
        }
        pkt->stream_index = idcin->video_stream_index;
        pkt->pts = idcin->pts;
    } else {
        /* send out the audio chunk */
        if (idcin->current_audio_chunk)
            chunk_size = idcin->audio_chunk_size2;
        else
            chunk_size = idcin->audio_chunk_size1;
        ret= av_get_packet(pb, pkt, chunk_size);
        if (ret < 0)
            return ret;
        pkt->stream_index = idcin->audio_stream_index;
        pkt->pts = idcin->pts;

        idcin->current_audio_chunk ^= 1;
        idcin->pts++;
    }

    if (idcin->audio_present)
        idcin->next_chunk_is_video ^= 1;

    return ret;
}
示例#9
0
static int smjpeg_read_header(AVFormatContext *s)
{
    SMJPEGContext *sc = s->priv_data;
    AVStream *ast = NULL, *vst = NULL;
    AVIOContext *pb = s->pb;
    uint32_t version, htype, hlength, duration;
    char *comment;

    avio_skip(pb, 8); // magic
    version = avio_rb32(pb);
    if (version)
        avpriv_request_sample(s, "Unknown version %"PRIu32, version);

    duration = avio_rb32(pb); // in msec

    while (!pb->eof_reached) {
        htype = avio_rl32(pb);
        switch (htype) {
        case SMJPEG_TXT:
            hlength = avio_rb32(pb);
            if (!hlength || hlength > 512)
                return AVERROR_INVALIDDATA;
            comment = av_malloc(hlength + 1);
            if (!comment)
                return AVERROR(ENOMEM);
            if (avio_read(pb, comment, hlength) != hlength) {
                av_freep(&comment);
                av_log(s, AV_LOG_ERROR, "error when reading comment\n");
                return AVERROR_INVALIDDATA;
            }
            comment[hlength] = 0;
            av_dict_set(&s->metadata, "comment", comment,
                        AV_DICT_DONT_STRDUP_VAL);
            break;
        case SMJPEG_SND:
            if (ast) {
                avpriv_request_sample(s, "Multiple audio streams");
                return AVERROR_PATCHWELCOME;
            }
            hlength = avio_rb32(pb);
            if (hlength < 8)
                return AVERROR_INVALIDDATA;
            ast = avformat_new_stream(s, 0);
            if (!ast)
                return AVERROR(ENOMEM);
            ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
            ast->codec->sample_rate = avio_rb16(pb);
            ast->codec->bits_per_coded_sample = avio_r8(pb);
            ast->codec->channels    = avio_r8(pb);
            ast->codec->codec_tag   = avio_rl32(pb);
            ast->codec->codec_id    = ff_codec_get_id(ff_codec_smjpeg_audio_tags,
                                                      ast->codec->codec_tag);
            ast->duration           = duration;
            sc->audio_stream_index  = ast->index;
            avpriv_set_pts_info(ast, 32, 1, 1000);
            avio_skip(pb, hlength - 8);
            break;
        case SMJPEG_VID:
            if (vst) {
                avpriv_request_sample(s, "Multiple video streams");
                return AVERROR_INVALIDDATA;
            }
            hlength = avio_rb32(pb);
            if (hlength < 12)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 4); // number of frames
            vst = avformat_new_stream(s, 0);
            if (!vst)
                return AVERROR(ENOMEM);
            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            vst->codec->width      = avio_rb16(pb);
            vst->codec->height     = avio_rb16(pb);
            vst->codec->codec_tag  = avio_rl32(pb);
            vst->codec->codec_id   = ff_codec_get_id(ff_codec_smjpeg_video_tags,
                                                     vst->codec->codec_tag);
            vst->duration          = duration;
            sc->video_stream_index = vst->index;
            avpriv_set_pts_info(vst, 32, 1, 1000);
            avio_skip(pb, hlength - 12);
            break;
        case SMJPEG_HEND:
            return 0;
        default:
            av_log(s, AV_LOG_ERROR, "unknown header %"PRIx32"\n", htype);
            return AVERROR_INVALIDDATA;
        }
    }

    return AVERROR_EOF;
}
static int ea_read_packet(AVFormatContext *s,
                          AVPacket *pkt)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb = s->pb;
    int ret = 0;
    int packet_read = 0;
    unsigned int chunk_type, chunk_size;
    int key = 0;
    int av_uninit(num_samples);

    while (!packet_read) {
        chunk_type = avio_rl32(pb);
        chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
        if (chunk_size <= 8)
            return AVERROR_INVALIDDATA;
        chunk_size -= 8;

        switch (chunk_type) {
        /* audio data */
        case ISNh_TAG:
            /* header chunk also contains data; skip over the header portion*/
            if (chunk_size < 32)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 32);
            chunk_size -= 32;
        case ISNd_TAG:
        case SCDl_TAG:
        case SNDC_TAG:
        case SDEN_TAG:
            if (!ea->audio_codec) {
                avio_skip(pb, chunk_size);
                break;
            } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR ||
                       ea->audio_codec == CODEC_ID_MP3) {
                num_samples = avio_rl32(pb);
                avio_skip(pb, 8);
                chunk_size -= 12;
            }
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->audio_stream_index;
            pkt->pts = 90000;
            pkt->pts *= ea->audio_frame_counter;
            pkt->pts /= ea->sample_rate;

            switch (ea->audio_codec) {
            case CODEC_ID_ADPCM_EA:
                /* 2 samples/byte, 1 or 2 samples per frame depending
                 * on stereo; chunk also has 12-byte header */
                ea->audio_frame_counter += ((chunk_size - 12) * 2) /
                    ea->num_channels;
                break;
            case CODEC_ID_PCM_S16LE_PLANAR:
            case CODEC_ID_MP3:
                ea->audio_frame_counter += num_samples;
                break;
            default:
                ea->audio_frame_counter += chunk_size /
                    (ea->bytes * ea->num_channels);
            }

            packet_read = 1;
            break;

        /* ending tag */
        case 0:
        case ISNe_TAG:
        case SCEl_TAG:
        case SEND_TAG:
        case SEEN_TAG:
            ret = AVERROR(EIO);
            packet_read = 1;
            break;

        case MVIh_TAG:
        case kVGT_TAG:
        case pQGT_TAG:
        case TGQs_TAG:
        case MADk_TAG:
            key = AV_PKT_FLAG_KEY;
        case MVIf_TAG:
        case fVGT_TAG:
        case MADm_TAG:
        case MADe_TAG:
            avio_seek(pb, -8, SEEK_CUR);     // include chunk preamble
            chunk_size += 8;
            goto get_video_packet;

        case mTCD_TAG:
            avio_skip(pb, 8);  // skip ea dct header
            chunk_size -= 8;
            goto get_video_packet;

        case MV0K_TAG:
        case MPCh_TAG:
        case pIQT_TAG:
            key = AV_PKT_FLAG_KEY;
        case MV0F_TAG:
get_video_packet:
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->video_stream_index;
            pkt->flags |= key;
            packet_read = 1;
            break;

        default:
            avio_skip(pb, chunk_size);
            break;
        }
    }

    return ret;
}
示例#11
0
static int idcin_read_header(AVFormatContext *s,
                             AVFormatParameters *ap)
{
    AVIOContext *pb = s->pb;
    IdcinDemuxContext *idcin = s->priv_data;
    AVStream *st;
    unsigned int width, height;
    unsigned int sample_rate, bytes_per_sample, channels;

    /* get the 5 header parameters */
    width = avio_rl32(pb);
    height = avio_rl32(pb);
    sample_rate = avio_rl32(pb);
    bytes_per_sample = avio_rl32(pb);
    channels = avio_rl32(pb);

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    av_set_pts_info(st, 33, 1, IDCIN_FPS);
    idcin->video_stream_index = st->index;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_IDCIN;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = width;
    st->codec->height = height;

    /* load up the Huffman tables into extradata */
    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
    st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
    if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) !=
        HUFFMAN_TABLE_SIZE)
        return AVERROR(EIO);

    /* if sample rate is 0, assume no audio */
    if (sample_rate) {
        idcin->audio_present = 1;
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        av_set_pts_info(st, 33, 1, IDCIN_FPS);
        idcin->audio_stream_index = st->index;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_tag = 1;
        st->codec->channels = channels;
        st->codec->sample_rate = sample_rate;
        st->codec->bits_per_coded_sample = bytes_per_sample * 8;
        st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;
        st->codec->block_align = bytes_per_sample * channels;
        if (bytes_per_sample == 1)
            st->codec->codec_id = CODEC_ID_PCM_U8;
        else
            st->codec->codec_id = CODEC_ID_PCM_S16LE;

        if (sample_rate % 14 != 0) {
            idcin->audio_chunk_size1 = (sample_rate / 14) *
            bytes_per_sample * channels;
            idcin->audio_chunk_size2 = (sample_rate / 14 + 1) *
                bytes_per_sample * channels;
        } else {
            idcin->audio_chunk_size1 = idcin->audio_chunk_size2 =
                (sample_rate / 14) * bytes_per_sample * channels;
        }
        idcin->current_audio_chunk = 0;
    } else
        idcin->audio_present = 1;

    idcin->next_chunk_is_video = 1;
    idcin->pts = 0;

    return 0;
}
/*
 * Process EA file header
 * Returns 1 if the EA file is valid and successfully opened, 0 otherwise
 */
static int process_ea_header(AVFormatContext *s) {
    uint32_t blockid, size = 0;
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb = s->pb;
    int i;

    for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
        unsigned int startpos = avio_tell(pb);
        int err = 0;

        blockid = avio_rl32(pb);
        size = avio_rl32(pb);
        if (i == 0)
            ea->big_endian = size > 0x000FFFFF;
        if (ea->big_endian)
            size = av_bswap32(size);

        switch (blockid) {
            case ISNh_TAG:
                if (avio_rl32(pb) != EACS_TAG) {
                    av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
                    return 0;
                }
                err = process_audio_header_eacs(s);
                break;

            case SCHl_TAG :
            case SHEN_TAG :
                blockid = avio_rl32(pb);
                if (blockid == GSTR_TAG) {
                    avio_skip(pb, 4);
                } else if ((blockid & 0xFFFF)!=PT00_TAG) {
                    av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n");
                    return 0;
                }
                err = process_audio_header_elements(s);
                break;

            case SEAD_TAG:
                err = process_audio_header_sead(s);
                break;

            case MVIh_TAG :
                ea->video_codec = CODEC_ID_CMV;
                break;

            case kVGT_TAG:
                ea->video_codec = CODEC_ID_TGV;
                break;

            case mTCD_TAG :
                err = process_video_header_mdec(s);
                break;

            case MPCh_TAG:
                ea->video_codec = CODEC_ID_MPEG2VIDEO;
                break;

            case pQGT_TAG:
            case TGQs_TAG:
                ea->video_codec = CODEC_ID_TGQ;
                break;

            case pIQT_TAG:
                ea->video_codec = CODEC_ID_TQI;
                break;

            case MADk_TAG :
                ea->video_codec = CODEC_ID_MAD;
                break;

            case MVhd_TAG :
                err = process_video_header_vp6(s);
                break;
        }

        if (err < 0) {
            av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
            return err;
        }

        avio_seek(pb, startpos + size, SEEK_SET);
    }

    avio_seek(pb, 0, SEEK_SET);

    return 1;
}
示例#13
0
static int flac_read_header(AVFormatContext *s)
{
    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
    uint8_t header[4];
    uint8_t *buffer=NULL;
    AVStream *st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = AV_CODEC_ID_FLAC;
    st->need_parsing = AVSTREAM_PARSE_FULL;
    /* the parameters will be extracted from the compressed bitstream */

    /* if fLaC marker is not found, assume there is no header */
    if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) {
        avio_seek(s->pb, -4, SEEK_CUR);
        return 0;
    }

    /* process metadata blocks */
    while (!s->pb->eof_reached && !metadata_last) {
        avio_read(s->pb, header, 4);
        flac_parse_block_header(header, &metadata_last, &metadata_type,
                                   &metadata_size);
        switch (metadata_type) {
        /* allocate and read metadata block for supported types */
        case FLAC_METADATA_TYPE_STREAMINFO:
        case FLAC_METADATA_TYPE_CUESHEET:
        case FLAC_METADATA_TYPE_PICTURE:
        case FLAC_METADATA_TYPE_VORBIS_COMMENT:
            buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!buffer) {
                return AVERROR(ENOMEM);
            }
            if (avio_read(s->pb, buffer, metadata_size) != metadata_size) {
                av_freep(&buffer);
                return AVERROR(EIO);
            }
            break;
        /* skip metadata block for unsupported types */
        default:
            ret = avio_skip(s->pb, metadata_size);
            if (ret < 0)
                return ret;
        }

        if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
            FLACStreaminfo si;
            /* STREAMINFO can only occur once */
            if (found_streaminfo) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            if (metadata_size != FLAC_STREAMINFO_SIZE) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            found_streaminfo = 1;
            st->codec->extradata      = buffer;
            st->codec->extradata_size = metadata_size;
            buffer = NULL;

            /* get codec params from STREAMINFO header */
            avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);

            /* set time base and duration */
            if (si.samplerate > 0) {
                avpriv_set_pts_info(st, 64, 1, si.samplerate);
                if (si.samples > 0)
                    st->duration = si.samples;
            }
        } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) {
            uint8_t isrc[13];
            uint64_t start;
            const uint8_t *offset;
            int i, chapters, track, ti;
            if (metadata_size < 431)
                return AVERROR_INVALIDDATA;
            offset = buffer + 395;
            chapters = bytestream_get_byte(&offset) - 1;
            if (chapters <= 0)
                return AVERROR_INVALIDDATA;
            for (i = 0; i < chapters; i++) {
                if (offset + 36 - buffer > metadata_size)
                    return AVERROR_INVALIDDATA;
                start = bytestream_get_be64(&offset);
                track = bytestream_get_byte(&offset);
                bytestream_get_buffer(&offset, isrc, 12);
                isrc[12] = 0;
                offset += 14;
                ti = bytestream_get_byte(&offset);
                if (ti <= 0) return AVERROR_INVALIDDATA;
                offset += ti * 12;
                avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
            }
        } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
            ret = ff_flac_parse_picture(s, buffer, metadata_size);
            av_freep(&buffer);
            if (ret < 0) {
                av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
                return ret;
            }
        } else {
            /* STREAMINFO must be the first block */
            if (!found_streaminfo) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            /* process supported blocks other than STREAMINFO */
            if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
                AVDictionaryEntry *chmask;

                ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1);
                if (ret < 0) {
                    av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
                } else if (ret > 0) {
                    s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
                }

                /* parse the channels mask if present */
                chmask = av_dict_get(s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
                if (chmask) {
                    uint64_t mask = strtol(chmask->value, NULL, 0);
                    if (!mask || mask & ~0x3ffffULL) {
                        av_log(s, AV_LOG_WARNING,
                               "Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
                    } else {
                        st->codec->channel_layout = mask;
                        av_dict_set(&s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
                    }
                }
            }
            av_freep(&buffer);
        }
    }

    ret = ff_replaygain_export(st, s->metadata);
    if (ret < 0)
        return ret;

    return 0;
}
示例#14
0
文件: genh.c 项目: AleXoundOS/FFmpeg
static int genh_read_header(AVFormatContext *s)
{
    unsigned start_offset, header_size, codec, coef_type, coef[2];
    GENHDemuxContext *c = s->priv_data;
    av_unused unsigned coef_splitted[2];
    int align, ch, ret;
    AVStream *st;

    avio_skip(s->pb, 4);

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->channels    = avio_rl32(s->pb);
    if (st->codec->channels <= 0)
        return AVERROR_INVALIDDATA;
    if (st->codec->channels == 1)
        st->codec->channel_layout = AV_CH_LAYOUT_MONO;
    else if (st->codec->channels == 2)
        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
    align                  =
    c->interleave_size     = avio_rl32(s->pb);
    if (align < 0 || align > INT_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    st->codec->block_align = align * st->codec->channels;
    st->codec->sample_rate = avio_rl32(s->pb);
    avio_skip(s->pb, 4);
    st->duration = avio_rl32(s->pb);

    codec = avio_rl32(s->pb);
    switch (codec) {
    case  0: st->codec->codec_id = AV_CODEC_ID_ADPCM_PSX;        break;
    case  1:
    case 11: st->codec->bits_per_coded_sample = 4;
             st->codec->block_align = 36 * st->codec->channels;
             st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_WAV;    break;
    case  2: st->codec->codec_id = AV_CODEC_ID_ADPCM_DTK;        break;
    case  3: st->codec->codec_id = st->codec->block_align > 0 ?
                                   AV_CODEC_ID_PCM_S16BE_PLANAR :
                                   AV_CODEC_ID_PCM_S16BE;        break;
    case  4: st->codec->codec_id = st->codec->block_align > 0 ?
                                   AV_CODEC_ID_PCM_S16LE_PLANAR :
                                   AV_CODEC_ID_PCM_S16LE;        break;
    case  5: st->codec->codec_id = st->codec->block_align > 0 ?
                                   AV_CODEC_ID_PCM_S8_PLANAR :
                                   AV_CODEC_ID_PCM_S8;           break;
    case  6: st->codec->codec_id = AV_CODEC_ID_SDX2_DPCM;        break;
    case  7: ret = ff_alloc_extradata(st->codec, 2);
             if (ret < 0)
                 return ret;
             AV_WL16(st->codec->extradata, 3);
             st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_WS;     break;
    case 10: st->codec->codec_id = AV_CODEC_ID_ADPCM_AICA;       break;
    case 12: st->codec->codec_id = AV_CODEC_ID_ADPCM_THP;        break;
    case 13: st->codec->codec_id = AV_CODEC_ID_PCM_U8;           break;
    case 17: st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_QT;     break;
    default:
             avpriv_request_sample(s, "codec %d", codec);
             return AVERROR_PATCHWELCOME;
    }

    start_offset = avio_rl32(s->pb);
    header_size  = avio_rl32(s->pb);

    if (header_size > start_offset)
        return AVERROR_INVALIDDATA;

    if (header_size == 0)
        start_offset = 0x800;

    coef[0]          = avio_rl32(s->pb);
    coef[1]          = avio_rl32(s->pb);
    c->dsp_int_type  = avio_rl32(s->pb);
    coef_type        = avio_rl32(s->pb);
    coef_splitted[0] = avio_rl32(s->pb);
    coef_splitted[1] = avio_rl32(s->pb);

    if (st->codec->codec_id == AV_CODEC_ID_ADPCM_THP) {
        if (st->codec->channels > 2) {
            avpriv_request_sample(s, "channels %d>2", st->codec->channels);
            return AVERROR_PATCHWELCOME;
        }

        ff_alloc_extradata(st->codec, 32 * st->codec->channels);
        for (ch = 0; ch < st->codec->channels; ch++) {
            if (coef_type & 1) {
                avpriv_request_sample(s, "coef_type & 1");
                return AVERROR_PATCHWELCOME;
            } else {
                avio_seek(s->pb, coef[ch], SEEK_SET);
                avio_read(s->pb, st->codec->extradata + 32 * ch, 32);
            }
        }

        if (c->dsp_int_type == 1) {
            st->codec->block_align = 8 * st->codec->channels;
            if (c->interleave_size != 1 &&
                c->interleave_size != 2 &&
                c->interleave_size != 4)
                return AVERROR_INVALIDDATA;
        }
    }

    avio_skip(s->pb, start_offset - avio_tell(s->pb));

    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    return 0;
}
示例#15
0
文件: iff.c 项目: SmartJog/ffmpeg
static int iff_read_header(AVFormatContext *s)
{
    IffDemuxContext *iff = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    uint8_t *buf;
    uint32_t chunk_id, data_size;
    uint32_t screenmode = 0;
    unsigned transparency = 0;
    unsigned masking = 0; // no mask
    uint8_t fmt[16];
    int fmt_size;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->channels = 1;
    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
    avio_skip(pb, 8);
    // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
    st->codec->codec_tag = avio_rl32(pb);

    while(!url_feof(pb)) {
        uint64_t orig_pos;
        int res;
        const char *metadata_tag = NULL;
        chunk_id = avio_rl32(pb);
        data_size = avio_rb32(pb);
        orig_pos = avio_tell(pb);

        switch(chunk_id) {
        case ID_VHDR:
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            if (data_size < 14)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 12);
            st->codec->sample_rate = avio_rb16(pb);
            if (data_size >= 16) {
                avio_skip(pb, 1);
                iff->svx8_compression = avio_r8(pb);
            }
            break;

        case ID_ABIT:
        case ID_BODY:
        case ID_DBOD:
            iff->body_pos = avio_tell(pb);
            iff->body_size = data_size;
            break;

        case ID_CHAN:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            if (avio_rb32(pb) < 6) {
                st->codec->channels       = 1;
                st->codec->channel_layout = AV_CH_LAYOUT_MONO;
            } else {
                st->codec->channels       = 2;
                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
            }
            break;

        case ID_CAMG:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            screenmode                = avio_rb32(pb);
            break;

        case ID_CMAP:
            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;
            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
                return AVERROR(EIO);
            break;

        case ID_BMHD:
            iff->bitmap_compression = -1;
            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
            if (data_size <= 8)
                return AVERROR_INVALIDDATA;
            st->codec->width                 = avio_rb16(pb);
            st->codec->height                = avio_rb16(pb);
            avio_skip(pb, 4); // x, y offset
            st->codec->bits_per_coded_sample = avio_r8(pb);
            if (data_size >= 10)
                masking                      = avio_r8(pb);
            if (data_size >= 11)
                iff->bitmap_compression      = avio_r8(pb);
            if (data_size >= 14) {
                avio_skip(pb, 1); // padding
                transparency                 = avio_rb16(pb);
            }
            if (data_size >= 16) {
                st->sample_aspect_ratio.num  = avio_r8(pb);
                st->sample_aspect_ratio.den  = avio_r8(pb);
            }
            break;

        case ID_DPEL:
            if (data_size < 4 || (data_size & 3))
                return AVERROR_INVALIDDATA;
            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)
                return fmt_size;
            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))
                st->codec->pix_fmt = AV_PIX_FMT_RGB24;
            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))
                st->codec->pix_fmt = AV_PIX_FMT_RGBA;
            else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))
                st->codec->pix_fmt = AV_PIX_FMT_BGRA;
            else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))
                st->codec->pix_fmt = AV_PIX_FMT_ARGB;
            else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))
                st->codec->pix_fmt = AV_PIX_FMT_ABGR;
            else {
                av_log_ask_for_sample(s, "unsupported color format\n");
                return AVERROR_PATCHWELCOME;
            }
            break;

        case ID_DGBL:
            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
            if (data_size < 8)
                return AVERROR_INVALIDDATA;
            st->codec->width                 = avio_rb16(pb);
            st->codec->height                = avio_rb16(pb);
            iff->bitmap_compression          = avio_rb16(pb);
            if (iff->bitmap_compression > 1) {
                av_log(s, AV_LOG_ERROR,
                       "compression %i not supported\n", iff->bitmap_compression);
                return AVERROR_PATCHWELCOME;
            }
            st->sample_aspect_ratio.num      = avio_r8(pb);
            st->sample_aspect_ratio.den      = avio_r8(pb);
            st->codec->bits_per_coded_sample = 24;
            break;

        case ID_DLOC:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            st->codec->width  = avio_rb16(pb);
            st->codec->height = avio_rb16(pb);
            break;

        case ID_ANNO:
        case ID_TEXT:      metadata_tag = "comment";   break;
        case ID_AUTH:      metadata_tag = "artist";    break;
        case ID_COPYRIGHT: metadata_tag = "copyright"; break;
        case ID_NAME:      metadata_tag = "title";     break;
        }

        if (metadata_tag) {
            if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {
                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);
                return res;
            }
        }
        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));
    }

    avio_seek(pb, iff->body_pos, SEEK_SET);

    switch(st->codec->codec_type) {
    case AVMEDIA_TYPE_AUDIO:
        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);

        switch (iff->svx8_compression) {
        case COMP_NONE:
            st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;
            break;
        case COMP_FIB:
            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;
            break;
        case COMP_EXP:
            st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;
            break;
        default:
            av_log(s, AV_LOG_ERROR,
                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);
            return -1;
        }

        st->codec->bits_per_coded_sample = iff->svx8_compression == COMP_NONE ? 8 : 4;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample;
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
        break;

    case AVMEDIA_TYPE_VIDEO:
        iff->bpp          = st->codec->bits_per_coded_sample;
        if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {
            iff->ham      = iff->bpp > 6 ? 6 : 4;
            st->codec->bits_per_coded_sample = 24;
        }
        iff->flags        = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;
        iff->masking      = masking;
        iff->transparency = transparency;

        if (!st->codec->extradata) {
            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;
            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
        }
        buf = st->codec->extradata;
        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);
        bytestream_put_byte(&buf, iff->bitmap_compression);
        bytestream_put_byte(&buf, iff->bpp);
        bytestream_put_byte(&buf, iff->ham);
        bytestream_put_byte(&buf, iff->flags);
        bytestream_put_be16(&buf, iff->transparency);
        bytestream_put_byte(&buf, iff->masking);

        switch (iff->bitmap_compression) {
        case BITMAP_RAW:
            st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;
            break;
        case BITMAP_BYTERUN1:
            st->codec->codec_id = AV_CODEC_ID_IFF_BYTERUN1;
            break;
        default:
            av_log(s, AV_LOG_ERROR,
                   "Unknown bitmap compression method '%d'\n", iff->bitmap_compression);
            return AVERROR_INVALIDDATA;
        }
        break;
    default:
        return -1;
    }

    return 0;
}
示例#16
0
static int tmv_read_header(AVFormatContext *s)
{
    TMVContext *tmv   = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *vst, *ast;
    AVRational fps;
    unsigned comp_method, char_cols, char_rows, features;

    if (avio_rl32(pb) != TMV_TAG)
        return -1;

    if (!(vst = avformat_new_stream(s, NULL)))
        return AVERROR(ENOMEM);

    if (!(ast = avformat_new_stream(s, NULL)))
        return AVERROR(ENOMEM);

    ast->codec->sample_rate = avio_rl16(pb);
    if (!ast->codec->sample_rate) {
        av_log(s, AV_LOG_ERROR, "invalid sample rate\n");
        return -1;
    }

    tmv->audio_chunk_size   = avio_rl16(pb);
    if (!tmv->audio_chunk_size) {
        av_log(s, AV_LOG_ERROR, "invalid audio chunk size\n");
        return -1;
    }

    comp_method             = avio_r8(pb);
    if (comp_method) {
        av_log(s, AV_LOG_ERROR, "unsupported compression method %d\n",
               comp_method);
        return -1;
    }

    char_cols = avio_r8(pb);
    char_rows = avio_r8(pb);
    tmv->video_chunk_size = char_cols * char_rows * 2;

    features  = avio_r8(pb);
    if (features & ~(TMV_PADDING | TMV_STEREO)) {
        av_log(s, AV_LOG_ERROR, "unsupported features 0x%02x\n",
               features & ~(TMV_PADDING | TMV_STEREO));
        return -1;
    }

    ast->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
    ast->codec->codec_id              = AV_CODEC_ID_PCM_U8;
    if (features & TMV_STEREO) {
        ast->codec->channels       = 2;
        ast->codec->channel_layout = AV_CH_LAYOUT_STEREO;
    } else {
        ast->codec->channels       = 1;
        ast->codec->channel_layout = AV_CH_LAYOUT_MONO;
    }
    ast->codec->bits_per_coded_sample = 8;
    ast->codec->bit_rate              = ast->codec->sample_rate *
                                        ast->codec->bits_per_coded_sample;
    avpriv_set_pts_info(ast, 32, 1, ast->codec->sample_rate);

    fps.num = ast->codec->sample_rate * ast->codec->channels;
    fps.den = tmv->audio_chunk_size;
    av_reduce(&fps.num, &fps.den, fps.num, fps.den, 0xFFFFFFFFLL);

    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id   = AV_CODEC_ID_TMV;
    vst->codec->pix_fmt    = AV_PIX_FMT_PAL8;
    vst->codec->width      = char_cols * 8;
    vst->codec->height     = char_rows * 8;
    avpriv_set_pts_info(vst, 32, fps.den, fps.num);

    if (features & TMV_PADDING)
        tmv->padding =
            ((tmv->video_chunk_size + tmv->audio_chunk_size + 511) & ~511) -
             (tmv->video_chunk_size + tmv->audio_chunk_size);

    vst->codec->bit_rate = ((tmv->video_chunk_size + tmv->padding) *
                            fps.num * 8) / fps.den;

    return 0;
}
示例#17
0
文件: ape.c 项目: bluecherrydvr/libav
static int ape_read_header(AVFormatContext * s)
{
    AVIOContext *pb = s->pb;
    APEContext *ape = s->priv_data;
    AVStream *st;
    uint32_t tag;
    int i;
    int total_blocks, final_size = 0;
    int64_t pts, file_size;

    /* Skip any leading junk such as id3v2 tags */
    ape->junklength = avio_tell(pb);

    tag = avio_rl32(pb);
    if (tag != MKTAG('M', 'A', 'C', ' '))
        return -1;

    ape->fileversion = avio_rl16(pb);

    if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
        av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n",
               ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
        return -1;
    }

    if (ape->fileversion >= 3980) {
        ape->padding1             = avio_rl16(pb);
        ape->descriptorlength     = avio_rl32(pb);
        ape->headerlength         = avio_rl32(pb);
        ape->seektablelength      = avio_rl32(pb);
        ape->wavheaderlength      = avio_rl32(pb);
        ape->audiodatalength      = avio_rl32(pb);
        ape->audiodatalength_high = avio_rl32(pb);
        ape->wavtaillength        = avio_rl32(pb);
        avio_read(pb, ape->md5, 16);

        /* Skip any unknown bytes at the end of the descriptor.
           This is for future compatibility */
        if (ape->descriptorlength > 52)
            avio_skip(pb, ape->descriptorlength - 52);

        /* Read header data */
        ape->compressiontype      = avio_rl16(pb);
        ape->formatflags          = avio_rl16(pb);
        ape->blocksperframe       = avio_rl32(pb);
        ape->finalframeblocks     = avio_rl32(pb);
        ape->totalframes          = avio_rl32(pb);
        ape->bps                  = avio_rl16(pb);
        ape->channels             = avio_rl16(pb);
        ape->samplerate           = avio_rl32(pb);
    } else {
        ape->descriptorlength = 0;
        ape->headerlength = 32;

        ape->compressiontype      = avio_rl16(pb);
        ape->formatflags          = avio_rl16(pb);
        ape->channels             = avio_rl16(pb);
        ape->samplerate           = avio_rl32(pb);
        ape->wavheaderlength      = avio_rl32(pb);
        ape->wavtaillength        = avio_rl32(pb);
        ape->totalframes          = avio_rl32(pb);
        ape->finalframeblocks     = avio_rl32(pb);

        if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) {
            avio_skip(pb, 4); /* Skip the peak level */
            ape->headerlength += 4;
        }

        if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) {
            ape->seektablelength = avio_rl32(pb);
            ape->headerlength += 4;
            ape->seektablelength *= sizeof(int32_t);
        } else
            ape->seektablelength = ape->totalframes * sizeof(int32_t);

        if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT)
            ape->bps = 8;
        else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT)
            ape->bps = 24;
        else
            ape->bps = 16;

        if (ape->fileversion >= 3950)
            ape->blocksperframe = 73728 * 4;
        else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800  && ape->compressiontype >= 4000))
            ape->blocksperframe = 73728;
        else
            ape->blocksperframe = 9216;

        /* Skip any stored wav header */
        if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
            avio_skip(pb, ape->wavheaderlength);
    }

    if(!ape->totalframes) {
        av_log(s, AV_LOG_ERROR, "No frames in the file!\n");
        return AVERROR(EINVAL);
    }
    if(ape->totalframes > UINT_MAX / sizeof(APEFrame)) {
        av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n",
               ape->totalframes);
        return -1;
    }
    if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) {
        av_log(s, AV_LOG_ERROR,
               "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n",
               ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
        return AVERROR_INVALIDDATA;
    }
    ape->frames       = av_malloc(ape->totalframes * sizeof(APEFrame));
    if(!ape->frames)
        return AVERROR(ENOMEM);
    ape->firstframe   = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength;
    ape->currentframe = 0;


    ape->totalsamples = ape->finalframeblocks;
    if (ape->totalframes > 1)
        ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1);

    if (ape->seektablelength > 0) {
        ape->seektable = av_malloc(ape->seektablelength);
        if (!ape->seektable)
            return AVERROR(ENOMEM);
        for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++)
            ape->seektable[i] = avio_rl32(pb);
    }

    ape->frames[0].pos     = ape->firstframe;
    ape->frames[0].nblocks = ape->blocksperframe;
    ape->frames[0].skip    = 0;
    for (i = 1; i < ape->totalframes; i++) {
        ape->frames[i].pos      = ape->seektable[i] + ape->junklength;
        ape->frames[i].nblocks  = ape->blocksperframe;
        ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos;
        ape->frames[i].skip     = (ape->frames[i].pos - ape->frames[0].pos) & 3;
    }
    ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks;
    /* calculate final packet size from total file size, if available */
    file_size = avio_size(pb);
    if (file_size > 0) {
        final_size = file_size - ape->frames[ape->totalframes - 1].pos -
                     ape->wavtaillength;
        final_size -= final_size & 3;
    }
    if (file_size <= 0 || final_size <= 0)
        final_size = ape->finalframeblocks * 8;
    ape->frames[ape->totalframes - 1].size = final_size;

    for (i = 0; i < ape->totalframes; i++) {
        if(ape->frames[i].skip) {
            ape->frames[i].pos  -= ape->frames[i].skip;
            ape->frames[i].size += ape->frames[i].skip;
        }
        ape->frames[i].size = (ape->frames[i].size + 3) & ~3;
    }


    ape_dumpinfo(s, ape);

    /* try to read APE tags */
    if (pb->seekable) {
        ff_ape_parse_tag(s);
        avio_seek(pb, 0, SEEK_SET);
    }

    av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n",
           ape->fileversion / 1000, (ape->fileversion % 1000) / 10,
           ape->compressiontype);

    /* now we are ready: build format streams */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return -1;

    total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks;

    st->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id        = CODEC_ID_APE;
    st->codec->codec_tag       = MKTAG('A', 'P', 'E', ' ');
    st->codec->channels        = ape->channels;
    st->codec->sample_rate     = ape->samplerate;
    st->codec->bits_per_coded_sample = ape->bps;

    st->nb_frames = ape->totalframes;
    st->start_time = 0;
    st->duration  = total_blocks / MAC_SUBFRAME_SIZE;
    avpriv_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);

    st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE);
    st->codec->extradata_size = APE_EXTRADATA_SIZE;
    AV_WL16(st->codec->extradata + 0, ape->fileversion);
    AV_WL16(st->codec->extradata + 2, ape->compressiontype);
    AV_WL16(st->codec->extradata + 4, ape->formatflags);

    pts = 0;
    for (i = 0; i < ape->totalframes; i++) {
        ape->frames[i].pts = pts;
        av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME);
        pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
    }

    return 0;
}
示例#18
0
static int lvf_read_header(AVFormatContext *s)
{
    AVStream *st;
    int64_t next_offset;
    unsigned size, nb_streams, id;

    avio_skip(s->pb, 16);
    nb_streams = avio_rl32(s->pb);
    if (!nb_streams)
        return AVERROR_INVALIDDATA;
    if (nb_streams > 2) {
        avpriv_request_sample(s, "%d streams", nb_streams);
        return AVERROR_PATCHWELCOME;
    }

    avio_skip(s->pb, 1012);

    while (!url_feof(s->pb)) {
        id          = avio_rl32(s->pb);
        size        = avio_rl32(s->pb);
        next_offset = avio_tell(s->pb) + size;

        switch (id) {
        case MKTAG('0', '0', 'f', 'm'):
            st = avformat_new_stream(s, 0);
            if (!st)
                return AVERROR(ENOMEM);

            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            avio_skip(s->pb, 4);
            st->codec->width      = avio_rl32(s->pb);
            st->codec->height     = avio_rl32(s->pb);
            avio_skip(s->pb, 4);
            st->codec->codec_tag  = avio_rl32(s->pb);
            st->codec->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
                                                    st->codec->codec_tag);
            avpriv_set_pts_info(st, 32, 1, 1000);
            break;
        case MKTAG('0', '1', 'f', 'm'):
            st = avformat_new_stream(s, 0);
            if (!st)
                return AVERROR(ENOMEM);

            st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
            st->codec->codec_tag   = avio_rl16(s->pb);
            st->codec->channels    = avio_rl16(s->pb);
            st->codec->sample_rate = avio_rl16(s->pb);
            avio_skip(s->pb, 8);
            st->codec->bits_per_coded_sample = avio_r8(s->pb);
            st->codec->codec_id    = ff_codec_get_id(ff_codec_wav_tags,
                                                     st->codec->codec_tag);
            avpriv_set_pts_info(st, 32, 1, 1000);
            break;
        case 0:
            avio_seek(s->pb, 2048 + 8, SEEK_SET);
            return 0;
        default:
            avpriv_request_sample(s, "id %d", id);
            return AVERROR_PATCHWELCOME;
        }

        avio_seek(s->pb, next_offset, SEEK_SET);
    }

    return AVERROR_EOF;
}
示例#19
0
/* aiff input */
static int aiff_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
{
    int size, filesize;
    int64_t offset = 0;
    uint32_t tag;
    unsigned version = AIFF_C_VERSION1;
    AVIOContext *pb = s->pb;
    AVStream * st;
    AIFFInputContext *aiff = (AIFFInputContext *)s->priv_data;

    /* check FORM header */
    filesize = get_tag(pb, &tag);
    if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))
        return AVERROR_INVALIDDATA;

    /* AIFF data type */
    tag = avio_rl32(pb);
    if (tag == MKTAG('A', 'I', 'F', 'F'))       /* Got an AIFF file */
        version = AIFF;
    else if (tag != MKTAG('A', 'I', 'F', 'C'))  /* An AIFF-C file then */
        return AVERROR_INVALIDDATA;

    filesize -= 4;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    while (filesize > 0) {
        /* parse different chunks */
        size = get_tag(pb, &tag);
        if (size < 0)
            return size;

        filesize -= size + 8;

        switch (tag) {
        case MKTAG('C', 'O', 'M', 'M'):     /* Common chunk */
            /* Then for the complete header info */
            st->nb_frames = get_aiff_header(pb, st->codec, size, version);
            if (st->nb_frames < 0)
                return st->nb_frames;
            if (offset > 0) // COMM is after SSND
                goto got_sound;
            break;
        case MKTAG('F', 'V', 'E', 'R'):     /* Version chunk */
            version = avio_rb32(pb);
            break;
        case MKTAG('N', 'A', 'M', 'E'):     /* Sample name chunk */
            get_meta(s, "title"    , size);
            break;
        case MKTAG('A', 'U', 'T', 'H'):     /* Author chunk */
            get_meta(s, "author"   , size);
            break;
        case MKTAG('(', 'c', ')', ' '):     /* Copyright chunk */
            get_meta(s, "copyright", size);
            break;
        case MKTAG('A', 'N', 'N', 'O'):     /* Annotation chunk */
            get_meta(s, "comment"  , size);
            break;
        case MKTAG('S', 'S', 'N', 'D'):     /* Sampled sound chunk */
            aiff->data_end = avio_tell(pb) + size;
            offset = avio_rb32(pb);      /* Offset of sound data */
            avio_rb32(pb);               /* BlockSize... don't care */
            offset += avio_tell(pb);    /* Compute absolute data offset */
            if (st->codec->block_align)    /* Assume COMM already parsed */
                goto got_sound;
            if (!pb->seekable) {
                av_log(s, AV_LOG_ERROR, "file is not seekable\n");
                return -1;
            }
            avio_skip(pb, size - 8);
            break;
        case MKTAG('w', 'a', 'v', 'e'):
            if ((uint64_t)size > (1<<30))
                return -1;
            st->codec->extradata = (uint8_t *)av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
            st->codec->extradata_size = size;
            avio_read(pb, st->codec->extradata, size);
            break;
        case MKTAG('C','H','A','N'):
            if (size < 12)
                return AVERROR_INVALIDDATA;
            ff_mov_read_chan(s, size, st->codec);
            break;
        default: /* Jump */
            if (size & 1)   /* Always even aligned */
                size++;
            avio_skip(pb, size);
        }
    }

got_sound:
    if (!st->codec->block_align) {
        av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");
        return -1;
    }

    /* Now positioned, get the sound data start and end */
    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
    st->start_time = 0;
    st->duration = st->codec->frame_size ?
        st->nb_frames * st->codec->frame_size : st->nb_frames;

    /* Position the stream at the first block */
    avio_seek(pb, offset, SEEK_SET);

    return 0;
}
示例#20
0
文件: bink.c 项目: simock85/libav
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    BinkDemuxContext *bink = s->priv_data;
    AVIOContext *pb = s->pb;
    int ret;

    if (bink->current_track < 0) {
        int index_entry;
        AVStream *st = s->streams[0]; // stream 0 is video stream with index

        if (bink->video_pts >= st->duration)
            return AVERROR(EIO);

        index_entry = av_index_search_timestamp(st, bink->video_pts,
                                                AVSEEK_FLAG_ANY);
        if (index_entry < 0) {
            av_log(s, AV_LOG_ERROR,
                   "could not find index entry for frame %"PRId64"\n",
                   bink->video_pts);
            return AVERROR(EIO);
        }

        bink->remain_packet_size = st->index_entries[index_entry].size;
        bink->current_track = 0;
    }

    while (bink->current_track < bink->num_audio_tracks) {
        uint32_t audio_size = avio_rl32(pb);
        if (audio_size > bink->remain_packet_size - 4) {
            av_log(s, AV_LOG_ERROR,
                   "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n",
                   bink->video_pts, audio_size, bink->remain_packet_size);
            return AVERROR(EIO);
        }
        bink->remain_packet_size -= 4 + audio_size;
        bink->current_track++;
        if (audio_size >= 4) {
            /* get one audio packet per track */
            if ((ret = av_get_packet(pb, pkt, audio_size)) < 0)
                return ret;
            pkt->stream_index = bink->current_track;
            pkt->pts = bink->audio_pts[bink->current_track - 1];

            /* Each audio packet reports the number of decompressed samples
               (in bytes). We use this value to calcuate the audio PTS */
            if (pkt->size >= 4)
                bink->audio_pts[bink->current_track -1] +=
                    AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec->channels);
            return 0;
        } else {
            avio_skip(pb, audio_size);
        }
    }

    /* get video packet */
    if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) < 0)
        return ret;
    pkt->stream_index = 0;
    pkt->pts = bink->video_pts++;
    pkt->flags |= AV_PKT_FLAG_KEY;

    /* -1 instructs the next call to read_packet() to read the next frame */
    bink->current_track = -1;

    return 0;
}
示例#21
0
文件: apetag.c 项目: Ancaro/stepmania
static int ape_tag_read_field(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    uint8_t key[1024], *value;
    uint32_t size, flags;
    int i, c;

    size = avio_rl32(pb);  /* field size */
    flags = avio_rl32(pb); /* field flags */
    for (i = 0; i < sizeof(key) - 1; i++) {
        c = avio_r8(pb);
        if (c < 0x20 || c > 0x7E)
            break;
        else
            key[i] = c;
    }
    key[i] = 0;
    if (c != 0) {
        av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key);
        return -1;
    }
    if (size >= UINT_MAX)
        return -1;
    if (flags & APE_TAG_FLAG_IS_BINARY) {
        uint8_t filename[1024];
        enum AVCodecID id;
        AVStream *st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);

        size -= avio_get_str(pb, size, filename, sizeof(filename));
        if (size <= 0) {
            av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key);
            return 0;
        }

        av_dict_set(&st->metadata, key, filename, 0);

        if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) {
            AVPacket pkt;
            int ret;

            ret = av_get_packet(s->pb, &pkt, size);
            if (ret < 0) {
                av_log(s, AV_LOG_ERROR, "Error reading cover art.\n");
                return ret;
            }

            st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            st->codec->codec_id   = id;

            st->attached_pic              = pkt;
            st->attached_pic.stream_index = st->index;
            st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
        } else {
            if (ff_alloc_extradata(st->codec, size))
                return AVERROR(ENOMEM);
            if (avio_read(pb, st->codec->extradata, size) != size) {
                av_freep(&st->codec->extradata);
                st->codec->extradata_size = 0;
                return AVERROR(EIO);
            }
            st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
        }
    } else {
        value = av_malloc(size+1);
        if (!value)
            return AVERROR(ENOMEM);
        c = avio_read(pb, value, size);
        if (c < 0) {
            av_free(value);
            return c;
        }
        value[c] = 0;
        av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
    }
    return 0;
}
示例#22
0
文件: bink.c 项目: simock85/libav
static int read_header(AVFormatContext *s)
{
    BinkDemuxContext *bink = s->priv_data;
    AVIOContext *pb = s->pb;
    uint32_t fps_num, fps_den;
    AVStream *vst, *ast;
    unsigned int i;
    uint32_t pos, next_pos;
    uint16_t flags;
    int keyframe;

    vst = avformat_new_stream(s, NULL);
    if (!vst)
        return AVERROR(ENOMEM);

    vst->codec->codec_tag = avio_rl32(pb);

    bink->file_size = avio_rl32(pb) + 8;
    vst->duration   = avio_rl32(pb);

    if (vst->duration > 1000000) {
        av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n");
        return AVERROR(EIO);
    }

    if (avio_rl32(pb) > bink->file_size) {
        av_log(s, AV_LOG_ERROR,
               "invalid header: largest frame size greater than file size\n");
        return AVERROR(EIO);
    }

    avio_skip(pb, 4);

    vst->codec->width  = avio_rl32(pb);
    vst->codec->height = avio_rl32(pb);

    fps_num = avio_rl32(pb);
    fps_den = avio_rl32(pb);
    if (fps_num == 0 || fps_den == 0) {
        av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den);
        return AVERROR(EIO);
    }
    avpriv_set_pts_info(vst, 64, fps_den, fps_num);

    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id   = CODEC_ID_BINKVIDEO;
    vst->codec->extradata  = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
    vst->codec->extradata_size = 4;
    avio_read(pb, vst->codec->extradata, 4);

    bink->num_audio_tracks = avio_rl32(pb);

    if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) {
        av_log(s, AV_LOG_ERROR,
               "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n",
               bink->num_audio_tracks);
        return AVERROR(EIO);
    }

    if (bink->num_audio_tracks) {
        avio_skip(pb, 4 * bink->num_audio_tracks);

        for (i = 0; i < bink->num_audio_tracks; i++) {
            ast = avformat_new_stream(s, NULL);
            if (!ast)
                return AVERROR(ENOMEM);
            ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
            ast->codec->codec_tag   = 0;
            ast->codec->sample_rate = avio_rl16(pb);
            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
            flags = avio_rl16(pb);
            ast->codec->codec_id = flags & BINK_AUD_USEDCT ?
                                   CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT;
            ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1;
            ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!ast->codec->extradata)
                return AVERROR(ENOMEM);
            ast->codec->extradata_size = 4;
            AV_WL32(ast->codec->extradata, vst->codec->codec_tag);
        }

        for (i = 0; i < bink->num_audio_tracks; i++)
            s->streams[i + 1]->id = avio_rl32(pb);
    }

    /* frame index table */
    next_pos = avio_rl32(pb);
    for (i = 0; i < vst->duration; i++) {
        pos = next_pos;
        if (i == vst->duration - 1) {
            next_pos = bink->file_size;
            keyframe = 0;
        } else {
            next_pos = avio_rl32(pb);
            keyframe = pos & 1;
        }
        pos &= ~1;
        next_pos &= ~1;

        if (next_pos <= pos) {
            av_log(s, AV_LOG_ERROR, "invalid frame index table\n");
            return AVERROR(EIO);
        }
        av_add_index_entry(vst, pos, i, next_pos - pos, 0,
                           keyframe ? AVINDEX_KEYFRAME : 0);
    }

    avio_skip(pb, 4);

    bink->current_track = -1;
    return 0;
}
示例#23
0
static int apng_read_header(AVFormatContext *s)
{
    APNGDemuxContext *ctx = s->priv_data;
    AVIOContext *pb = s->pb;
    uint32_t len, tag;
    AVStream *st;
    int acTL_found = 0;
    int64_t ret = AVERROR_INVALIDDATA;

    /* verify PNGSIG */
    if (avio_rb64(pb) != PNGSIG)
        return ret;

    /* parse IHDR (must be first chunk) */
    len = avio_rb32(pb);
    tag = avio_rl32(pb);
    if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R'))
        return ret;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    /* set the timebase to something large enough (1/100,000 of second)
     * to hopefully cope with all sane frame durations */
    avpriv_set_pts_info(st, 64, 1, 100000);
    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codecpar->codec_id   = AV_CODEC_ID_APNG;
    st->codecpar->width      = avio_rb32(pb);
    st->codecpar->height     = avio_rb32(pb);
    if ((ret = av_image_check_size(st->codecpar->width, st->codecpar->height, 0, s)) < 0)
        return ret;

    /* extradata will contain every chunk up to the first fcTL (excluded) */
    st->codecpar->extradata = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codecpar->extradata)
        return AVERROR(ENOMEM);
    st->codecpar->extradata_size = len + 12;
    AV_WB32(st->codecpar->extradata,    len);
    AV_WL32(st->codecpar->extradata+4,  tag);
    AV_WB32(st->codecpar->extradata+8,  st->codecpar->width);
    AV_WB32(st->codecpar->extradata+12, st->codecpar->height);
    if ((ret = avio_read(pb, st->codecpar->extradata+16, 9)) < 0)
        goto fail;

    while (!avio_feof(pb)) {
        if (acTL_found && ctx->num_play != 1) {
            int64_t size   = avio_size(pb);
            int64_t offset = avio_tell(pb);
            if (size < 0) {
                ret = size;
                goto fail;
            } else if (offset < 0) {
                ret = offset;
                goto fail;
            } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) {
                av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n");
                ctx->num_play = 1;
            }
        }
        if ((ctx->num_play == 1 || !acTL_found) &&
            ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0))
            goto fail;

        len = avio_rb32(pb);
        if (len > 0x7fffffff) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }

        tag = avio_rl32(pb);
        switch (tag) {
        case MKTAG('a', 'c', 'T', 'L'):
            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
                (ret = append_extradata(st->codecpar, pb, len + 12)) < 0)
                goto fail;
            acTL_found = 1;
            ctx->num_frames = AV_RB32(st->codecpar->extradata + ret + 8);
            ctx->num_play   = AV_RB32(st->codecpar->extradata + ret + 12);
            av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",
                                    ctx->num_frames, ctx->num_play);
            break;
        case MKTAG('f', 'c', 'T', 'L'):
            if (!acTL_found) {
               ret = AVERROR_INVALIDDATA;
               goto fail;
            }
            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
                goto fail;
            return 0;
        default:
            if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
                (ret = append_extradata(st->codecpar, pb, len + 12)) < 0)
                goto fail;
        }
    }

fail:
    if (st->codecpar->extradata_size) {
        av_freep(&st->codecpar->extradata);
        st->codecpar->extradata_size = 0;
    }
    return ret;
}
示例#24
0
static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
                                     AVStream *st, RMStream *ast, int read_all)
{
    char buf[256];
    uint32_t version;
    int ret;

    /* ra type header */
    version = avio_rb16(pb); /* version */
    if (version == 3) {
        unsigned bytes_per_minute;
        int header_size = avio_rb16(pb);
        int64_t startpos = avio_tell(pb);
        avio_skip(pb, 8);
        bytes_per_minute = avio_rb16(pb);
        avio_skip(pb, 4);
        rm_read_metadata(s, pb, 0);
        if ((startpos + header_size) >= avio_tell(pb) + 2) {
            // fourcc (should always be "lpcJ")
            avio_r8(pb);
            get_str8(pb, buf, sizeof(buf));
        }
        // Skip extra header crap (this should never happen)
        if ((startpos + header_size) > avio_tell(pb))
            avio_skip(pb, header_size + startpos - avio_tell(pb));
        if (bytes_per_minute)
            st->codec->bit_rate = 8LL * bytes_per_minute / 60;
        st->codec->sample_rate = 8000;
        st->codec->channels = 1;
        st->codec->channel_layout = AV_CH_LAYOUT_MONO;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = AV_CODEC_ID_RA_144;
        ast->deint_id = DEINT_ID_INT0;
    } else {
        int flavor, sub_packet_h, coded_framesize, sub_packet_size;
        int codecdata_length;
        unsigned bytes_per_minute;
        /* old version (4) */
        avio_skip(pb, 2); /* unused */
        avio_rb32(pb); /* .ra4 */
        avio_rb32(pb); /* data size */
        avio_rb16(pb); /* version2 */
        avio_rb32(pb); /* header size */
        flavor= avio_rb16(pb); /* add codec info / flavor */
        ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */
        avio_rb32(pb); /* ??? */
        bytes_per_minute = avio_rb32(pb);
        if (version == 4) {
            if (bytes_per_minute)
                st->codec->bit_rate = 8LL * bytes_per_minute / 60;
        }
        avio_rb32(pb); /* ??? */
        ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */
        st->codec->block_align= avio_rb16(pb); /* frame size */
        ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */
        avio_rb16(pb); /* ??? */
        if (version == 5) {
            avio_rb16(pb); avio_rb16(pb); avio_rb16(pb);
        }
        st->codec->sample_rate = avio_rb16(pb);
        avio_rb32(pb);
        st->codec->channels = avio_rb16(pb);
        if (version == 5) {
            ast->deint_id = avio_rl32(pb);
            avio_read(pb, buf, 4);
            buf[4] = 0;
        } else {
            get_str8(pb, buf, sizeof(buf)); /* desc */
            ast->deint_id = AV_RL32(buf);
            get_str8(pb, buf, sizeof(buf)); /* desc */
        }
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_tag  = AV_RL32(buf);
        st->codec->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
                                                st->codec->codec_tag);

        switch (st->codec->codec_id) {
        case AV_CODEC_ID_AC3:
            st->need_parsing = AVSTREAM_PARSE_FULL;
            break;
        case AV_CODEC_ID_RA_288:
            st->codec->extradata_size= 0;
            ast->audio_framesize = st->codec->block_align;
            st->codec->block_align = coded_framesize;
            break;
        case AV_CODEC_ID_COOK:
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
        case AV_CODEC_ID_ATRAC3:
        case AV_CODEC_ID_SIPR:
            if (read_all) {
                codecdata_length = 0;
            } else {
                avio_rb16(pb); avio_r8(pb);
                if (version == 5)
                    avio_r8(pb);
                codecdata_length = avio_rb32(pb);
                if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
                    av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                    return -1;
                }
            }

            ast->audio_framesize = st->codec->block_align;
            if (st->codec->codec_id == AV_CODEC_ID_SIPR) {
                if (flavor > 3) {
                    av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n",
                           flavor);
                    return -1;
                }
                st->codec->block_align = ff_sipr_subpk_size[flavor];
            } else {
                if(sub_packet_size <= 0){
                    av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
                    return -1;
                }
                st->codec->block_align = ast->sub_packet_size;
            }
            if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0)
                return ret;

            break;
        case AV_CODEC_ID_AAC:
            avio_rb16(pb); avio_r8(pb);
            if (version == 5)
                avio_r8(pb);
            codecdata_length = avio_rb32(pb);
            if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
                av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                return -1;
            }
            if (codecdata_length >= 1) {
                avio_r8(pb);
                if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0)
                    return ret;
            }
            break;
        default:
            av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name));
        }
        if (ast->deint_id == DEINT_ID_INT4 ||
            ast->deint_id == DEINT_ID_GENR ||
            ast->deint_id == DEINT_ID_SIPR) {
            if (st->codec->block_align <= 0 ||
                ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX ||
                ast->audio_framesize * sub_packet_h < st->codec->block_align)
                return AVERROR_INVALIDDATA;
            if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0)
                return AVERROR(ENOMEM);
        }
        switch (ast->deint_id) {
        case DEINT_ID_INT4:
            if (ast->coded_framesize > ast->audio_framesize ||
                sub_packet_h <= 1 ||
                ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize)
                return AVERROR_INVALIDDATA;
            break;
        case DEINT_ID_GENR:
            if (ast->sub_packet_size <= 0 ||
                ast->sub_packet_size > ast->audio_framesize)
                return AVERROR_INVALIDDATA;
            break;
        case DEINT_ID_SIPR:
        case DEINT_ID_INT0:
        case DEINT_ID_VBRS:
        case DEINT_ID_VBRF:
            break;
        default:
            av_log(s, AV_LOG_ERROR, "Unknown interleaver %X\n", ast->deint_id);
            return AVERROR_INVALIDDATA;
        }

        if (read_all) {
            avio_r8(pb);
            avio_r8(pb);
            avio_r8(pb);
            rm_read_metadata(s, pb, 0);
        }
    }
    return 0;
}
示例#25
0
static int dxa_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    DXAContext *c = s->priv_data;
    AVStream *st, *ast;
    uint32_t tag;
    int32_t fps;
    int w, h;
    int num, den;
    int flags;
    int ret;

    tag = avio_rl32(pb);
    if (tag != MKTAG('D', 'E', 'X', 'A'))
        return AVERROR_INVALIDDATA;
    flags = avio_r8(pb);
    c->frames = avio_rb16(pb);
    if(!c->frames){
        av_log(s, AV_LOG_ERROR, "File contains no frames ???\n");
        return AVERROR_INVALIDDATA;
    }

    fps = avio_rb32(pb);
    if(fps > 0){
        den = 1000;
        num = fps;
    }else if (fps < 0){
        den = 100000;
        num = -fps;
    }else{
        den = 10;
        num = 1;
    }
    w = avio_rb16(pb);
    h = avio_rb16(pb);
    c->has_sound = 0;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    // Parse WAV data header
    if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){
        uint32_t size, fsize;
        c->has_sound = 1;
        size = avio_rb32(pb);
        c->vidpos = avio_tell(pb) + size;
        avio_skip(pb, 16);
        fsize = avio_rl32(pb);

        ast = avformat_new_stream(s, NULL);
        if (!ast)
            return AVERROR(ENOMEM);
        ret = ff_get_wav_header(pb, ast->codec, fsize);
        if (ret < 0)
            return ret;
        if (ast->codec->sample_rate > 0)
            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
        // find 'data' chunk
        while(avio_tell(pb) < c->vidpos && !url_feof(pb)){
            tag = avio_rl32(pb);
            fsize = avio_rl32(pb);
            if(tag == MKTAG('d', 'a', 't', 'a')) break;
            avio_skip(pb, fsize);
        }
        c->bpc = (fsize + c->frames - 1) / c->frames;
        if(ast->codec->block_align)
            c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align;
        c->bytes_left = fsize;
        c->wavpos = avio_tell(pb);
        avio_seek(pb, c->vidpos, SEEK_SET);
    }

    /* now we are ready: build format streams */
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = AV_CODEC_ID_DXA;
    st->codec->width      = w;
    st->codec->height     = h;
    av_reduce(&den, &num, den, num, (1UL<<31)-1);
    avpriv_set_pts_info(st, 33, num, den);
    /* flags & 0x80 means that image is interlaced,
     * flags & 0x40 means that image has double height
     * either way set true height
     */
    if(flags & 0xC0){
        st->codec->height >>= 1;
    }
示例#26
0
int
ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
                           AVStream *st, RMStream *rst, int codec_data_size, const uint8_t *mime)
{
    unsigned int v;
    int size;
    int64_t codec_pos;
    int ret;

    avpriv_set_pts_info(st, 64, 1, 1000);
    codec_pos = avio_tell(pb);
    v = avio_rb32(pb);
    if (v == MKTAG(0xfd, 'a', 'r', '.')) {
        /* ra type header */
        if (rm_read_audio_stream_info(s, pb, st, rst, 0))
            return -1;
    } else if (v == MKBETAG('L', 'S', 'D', ':')) {
        avio_seek(pb, -4, SEEK_CUR);
        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size)) < 0)
            return ret;

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_tag  = AV_RL32(st->codec->extradata);
        st->codec->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
                                                st->codec->codec_tag);
    } else if(mime && !strcmp(mime, "logical-fileinfo")){
        int stream_count, rule_count, property_count, i;
        ff_free_stream(s, st);
        if (avio_rb16(pb) != 0) {
            av_log(s, AV_LOG_WARNING, "Unsupported version\n");
            goto skip;
        }
        stream_count = avio_rb16(pb);
        avio_skip(pb, 6*stream_count);
        rule_count = avio_rb16(pb);
        avio_skip(pb, 2*rule_count);
        property_count = avio_rb16(pb);
        for(i=0; i<property_count; i++){
            uint8_t name[128], val[128];
            avio_rb32(pb);
            if (avio_rb16(pb) != 0) {
                av_log(s, AV_LOG_WARNING, "Unsupported Name value property version\n");
                goto skip; //FIXME skip just this one
            }
            get_str8(pb, name, sizeof(name));
            switch(avio_rb32(pb)) {
            case 2: get_strl(pb, val, sizeof(val), avio_rb16(pb));
                av_dict_set(&s->metadata, name, val, 0);
                break;
            default: avio_skip(pb, avio_rb16(pb));
            }
        }
    } else {
        int fps;
        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
        fail1:
            av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v);
            goto skip;
        }
        st->codec->codec_tag = avio_rl32(pb);
        st->codec->codec_id  = ff_codec_get_id(ff_rm_codec_tags,
                                               st->codec->codec_tag);
        av_dlog(s, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
        if (st->codec->codec_id == AV_CODEC_ID_NONE)
            goto fail1;
        st->codec->width  = avio_rb16(pb);
        st->codec->height = avio_rb16(pb);
        avio_skip(pb, 2); // looks like bits per sample
        avio_skip(pb, 4); // always zero?
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
        fps = avio_rb32(pb);

        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
            return ret;

        av_reduce(&st->avg_frame_rate.den, &st->avg_frame_rate.num,
                  0x10000, fps, (1 << 30) - 1);
#if FF_API_R_FRAME_RATE
        st->r_frame_rate = st->avg_frame_rate;
#endif
    }

skip:
    /* skip codec info */
    size = avio_tell(pb) - codec_pos;
    avio_skip(pb, codec_data_size - size);

    return 0;
}
示例#27
0
文件: wv.c 项目: mfpgt/FFmpeg
static int wv_read_packet(AVFormatContext *s,
                          AVPacket *pkt)
{
    WVContext *wc = s->priv_data;
    int ret;
    int size, ver, off;
    int64_t pos;

    if (url_feof(s->pb))
        return AVERROR(EIO);
    if(wc->block_parsed){
        if(wv_read_block_header(s, s->pb, 0) < 0)
            return -1;
    }

    pos = wc->pos;
    off = wc->multichannel ? 4 : 0;
    if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
        return AVERROR(ENOMEM);
    if(wc->multichannel)
        AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12);
    memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE);
    ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize);
    if(ret != wc->blksize){
        av_free_packet(pkt);
        return AVERROR(EIO);
    }
    while(!(wc->flags & WV_END_BLOCK)){
        if(avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')){
            av_free_packet(pkt);
            return -1;
        }
        if((ret = av_append_packet(s->pb, pkt, 4)) < 0){
            av_free_packet(pkt);
            return ret;
        }
        size = AV_RL32(pkt->data + pkt->size - 4);
        if(size < 24 || size > WV_BLOCK_LIMIT){
            av_free_packet(pkt);
            av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size);
            return -1;
        }
        wc->blksize = size;
        ver = avio_rl16(s->pb);
        if(ver < 0x402 || ver > 0x410){
            av_free_packet(pkt);
            av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
            return -1;
        }
        avio_r8(s->pb); // track no
        avio_r8(s->pb); // track sub index
        wc->samples = avio_rl32(s->pb); // total samples in file
        wc->soff = avio_rl32(s->pb); // offset in samples of current block
        if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0){
            av_free_packet(pkt);
            return ret;
        }
        memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE);

        if(wv_read_block_header(s, s->pb, 1) < 0){
            av_free_packet(pkt);
            return -1;
        }
        ret = av_append_packet(s->pb, pkt, wc->blksize);
        if(ret < 0){
            av_free_packet(pkt);
            return ret;
        }
    }
    pkt->stream_index = 0;
    wc->block_parsed = 1;
    pkt->pts = wc->soff;
    av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
    return 0;
}
示例#28
0
static int rm_read_header(AVFormatContext *s)
{
    RMDemuxContext *rm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    unsigned int tag;
    int tag_size;
    unsigned int start_time, duration;
    unsigned int data_off = 0, indx_off = 0;
    char buf[128], mime[128];
    int flags = 0;

    tag = avio_rl32(pb);
    if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
        /* very old .ra format */
        return rm_read_header_old(s);
    } else if (tag != MKTAG('.', 'R', 'M', 'F')) {
        return AVERROR(EIO);
    }

    tag_size = avio_rb32(pb);
    avio_skip(pb, tag_size - 8);

    for(;;) {
        if (url_feof(pb))
            return -1;
        tag = avio_rl32(pb);
        tag_size = avio_rb32(pb);
        avio_rb16(pb);
        av_dlog(s, "tag=%c%c%c%c (%08x) size=%d\n",
                (tag      ) & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                tag,
                tag_size);
        if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A'))
            return -1;
        switch(tag) {
        case MKTAG('P', 'R', 'O', 'P'):
            /* file header */
            avio_rb32(pb); /* max bit rate */
            avio_rb32(pb); /* avg bit rate */
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            avio_rb32(pb); /* nb packets */
            duration = avio_rb32(pb); /* duration */
            s->duration = av_rescale(duration, AV_TIME_BASE, 1000);
            avio_rb32(pb); /* preroll */
            indx_off = avio_rb32(pb); /* index offset */
            data_off = avio_rb32(pb); /* data offset */
            avio_rb16(pb); /* nb streams */
            flags = avio_rb16(pb); /* flags */
            break;
        case MKTAG('C', 'O', 'N', 'T'):
            rm_read_metadata(s, pb, 1);
            break;
        case MKTAG('M', 'D', 'P', 'R'):
            st = avformat_new_stream(s, NULL);
            if (!st)
                return AVERROR(ENOMEM);
            st->id = avio_rb16(pb);
            avio_rb32(pb); /* max bit rate */
            st->codec->bit_rate = avio_rb32(pb); /* bit rate */
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            start_time = avio_rb32(pb); /* start time */
            avio_rb32(pb); /* preroll */
            duration = avio_rb32(pb); /* duration */
            st->start_time = start_time;
            st->duration = duration;
            if(duration>0)
                s->duration = AV_NOPTS_VALUE;
            get_str8(pb, buf, sizeof(buf)); /* desc */
            get_str8(pb, mime, sizeof(mime)); /* mimetype */
            st->codec->codec_type = AVMEDIA_TYPE_DATA;
            st->priv_data = ff_rm_alloc_rmstream();
            if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
                                          avio_rb32(pb), mime) < 0)
                return -1;
            break;
        case MKTAG('D', 'A', 'T', 'A'):
            goto header_end;
        default:
            /* unknown tag: skip it */
            avio_skip(pb, tag_size - 10);
            break;
        }
    }
 header_end:
    rm->nb_packets = avio_rb32(pb); /* number of packets */
    if (!rm->nb_packets && (flags & 4))
        rm->nb_packets = 3600 * 25;
    avio_rb32(pb); /* next data header */

    if (!data_off)
        data_off = avio_tell(pb) - 18;
    if (indx_off && pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
        avio_seek(pb, indx_off, SEEK_SET) >= 0) {
        rm_read_index(s);
        avio_seek(pb, data_off + 18, SEEK_SET);
    }

    return 0;
}
示例#29
0
文件: anm.c 项目: Unhelpful/ffmpeg
static int read_header(AVFormatContext *s,
                       AVFormatParameters *ap)
{
    AnmDemuxContext *anm = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    int i, ret;

    avio_skip(pb, 4); /* magic number */
    if (avio_rl16(pb) != MAX_PAGES) {
        av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n");
        return AVERROR_INVALIDDATA;
    }

    anm->nb_pages   = avio_rl16(pb);
    anm->nb_records = avio_rl32(pb);
    avio_skip(pb, 2); /* max records per page */
    anm->page_table_offset = avio_rl16(pb);
    if (avio_rl32(pb) != ANIM_TAG)
        return AVERROR_INVALIDDATA;

    /* video stream */
    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = CODEC_ID_ANM;
    st->codec->codec_tag  = 0; /* no fourcc */
    st->codec->width      = avio_rl16(pb);
    st->codec->height     = avio_rl16(pb);
    if (avio_r8(pb) != 0)
        goto invalid;
    avio_skip(pb, 1); /* frame rate multiplier info */

    /* ignore last delta record (used for looping) */
    if (avio_r8(pb))  /* has_last_delta */
        anm->nb_records = FFMAX(anm->nb_records - 1, 0);

    avio_skip(pb, 1); /* last_delta_valid */

    if (avio_r8(pb) != 0)
        goto invalid;

    if (avio_r8(pb) != 1)
        goto invalid;

    avio_skip(pb, 1); /* other recs per frame */

    if (avio_r8(pb) != 1)
        goto invalid;

    avio_skip(pb, 32); /* record_types */
    st->nb_frames = avio_rl32(pb);
    av_set_pts_info(st, 64, 1, avio_rl16(pb));
    avio_skip(pb, 58);

    /* color cycling and palette data */
    st->codec->extradata_size = 16*8 + 4*256;
    st->codec->extradata      = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata) {
        ret = AVERROR(ENOMEM);
        goto close_and_return;
    }
    ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size);
    if (ret < 0)
        goto close_and_return;

    /* read page table */
    ret = avio_seek(pb, anm->page_table_offset, SEEK_SET);
    if (ret < 0)
        goto close_and_return;

    for (i = 0; i < MAX_PAGES; i++) {
        Page *p = &anm->pt[i];
        p->base_record = avio_rl16(pb);
        p->nb_records  = avio_rl16(pb);
        p->size        = avio_rl16(pb);
    }

    /* find page of first frame */
    anm->page = find_record(anm, 0);
    if (anm->page < 0) {
        ret = anm->page;
        goto close_and_return;
    }

    anm->record = -1;
    return 0;

invalid:
    av_log_ask_for_sample(s, NULL);
    ret = AVERROR_INVALIDDATA;

close_and_return:
    av_close_input_stream(s);
    return ret;
}
示例#30
0
文件: aiffdec.c 项目: alexyr/libav
/* Returns the number of sound data frames or negative on error */
static unsigned int get_aiff_header(AVFormatContext *s, int size,
                                    unsigned version)
{
    AVIOContext *pb        = s->pb;
    AVCodecContext *codec  = s->streams[0]->codec;
    AIFFInputContext *aiff = s->priv_data;
    int exp;
    uint64_t val;
    double sample_rate;
    unsigned int num_frames;

    if (size & 1)
        size++;
    codec->codec_type = AVMEDIA_TYPE_AUDIO;
    codec->channels = avio_rb16(pb);
    num_frames = avio_rb32(pb);
    codec->bits_per_coded_sample = avio_rb16(pb);

    exp = avio_rb16(pb);
    val = avio_rb64(pb);
    sample_rate = ldexp(val, exp - 16383 - 63);
    codec->sample_rate = sample_rate;
    size -= 18;

    /* get codec id for AIFF-C */
    if (version == AIFF_C_VERSION1) {
        codec->codec_tag = avio_rl32(pb);
        codec->codec_id  = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag);
        size -= 4;
    }

    if (version != AIFF_C_VERSION1 || codec->codec_id == AV_CODEC_ID_PCM_S16BE) {
        codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
        codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
        aiff->block_duration = 1;
    } else {
        switch (codec->codec_id) {
        case AV_CODEC_ID_PCM_F32BE:
        case AV_CODEC_ID_PCM_F64BE:
        case AV_CODEC_ID_PCM_S16LE:
        case AV_CODEC_ID_PCM_ALAW:
        case AV_CODEC_ID_PCM_MULAW:
            aiff->block_duration = 1;
            break;
        case AV_CODEC_ID_ADPCM_IMA_QT:
            codec->block_align = 34*codec->channels;
            break;
        case AV_CODEC_ID_MACE3:
            codec->block_align = 2*codec->channels;
            break;
        case AV_CODEC_ID_ADPCM_G722:
        case AV_CODEC_ID_MACE6:
            codec->block_align = 1*codec->channels;
            break;
        case AV_CODEC_ID_GSM:
            codec->block_align = 33;
            break;
        case AV_CODEC_ID_QCELP:
            codec->block_align = 35;
            break;
        default:
            break;
        }
        if (codec->block_align > 0)
            aiff->block_duration = av_get_audio_frame_duration(codec,
                                                               codec->block_align);
    }

    /* Block align needs to be computed in all cases, as the definition
     * is specific to applications -> here we use the WAVE format definition */
    if (!codec->block_align)
        codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3;

    if (aiff->block_duration) {
        codec->bit_rate = codec->sample_rate * (codec->block_align << 3) /
                          aiff->block_duration;
    }

    /* Chunk is over */
    if (size)
        avio_skip(pb, size);

    return num_frames;
}