示例#1
0
文件: fsb.c 项目: AleXoundOS/FFmpeg
static int fsb_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    unsigned format, version, c;
    int64_t offset;
    AVCodecContext *codec;
    AVStream *st = avformat_new_stream(s, NULL);

    avio_skip(pb, 3); // "FSB"
    version = avio_r8(pb) - '0';
    if (version != 4 && version != 3) {
        avpriv_request_sample(s, "version %d", version);
        return AVERROR_PATCHWELCOME;
    }

    avio_skip(pb, 4);

    if (!st)
        return AVERROR(ENOMEM);
    codec = st->codec;
    codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    codec->codec_tag   = 0;

    if (version == 3) {
        offset = avio_rl32(pb) + 0x18;
        avio_skip(pb, 44);
        st->duration = avio_rl32(pb);
        avio_skip(pb, 12);
        format = avio_rl32(pb);
        codec->sample_rate = avio_rl32(pb);
        if (codec->sample_rate <= 0)
            return AVERROR_INVALIDDATA;
        avio_skip(pb, 6);
        codec->channels    = avio_rl16(pb);
        if (!codec->channels)
            return AVERROR_INVALIDDATA;

        if (format & 0x00000100) {
            codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
            codec->block_align = 4096 * codec->channels;
        } else if (format & 0x00400000) {
            codec->bits_per_coded_sample = 4;
            codec->codec_id    = AV_CODEC_ID_ADPCM_IMA_WAV;
            codec->block_align = 36 * codec->channels;
        } else if (format & 0x00800000) {
            codec->codec_id    = AV_CODEC_ID_ADPCM_PSX;
            codec->block_align = 16 * codec->channels;
        } else if (format & 0x02000000) {
            codec->codec_id    = AV_CODEC_ID_ADPCM_THP;
            codec->block_align = 8 * codec->channels;
            if (codec->channels > INT_MAX / 32)
                return AVERROR_INVALIDDATA;
            ff_alloc_extradata(codec, 32 * codec->channels);
            if (!codec->extradata)
                return AVERROR(ENOMEM);
            avio_seek(pb, 0x68, SEEK_SET);
            for (c = 0; c < codec->channels; c++) {
                avio_read(pb, codec->extradata + 32 * c, 32);
                avio_skip(pb, 14);
            }
        } else {
            avpriv_request_sample(s, "format 0x%X", format);
            return AVERROR_PATCHWELCOME;
        }
    } else if (version == 4) {
        offset = avio_rl32(pb) + 0x30;
        avio_skip(pb, 80);
        st->duration = avio_rl32(pb);

        format = avio_rb32(pb);
        switch(format) {
        case 0x40001001:
        case 0x00001005:
        case 0x40001081:
        case 0x40200001:
            codec->codec_id = AV_CODEC_ID_XMA2;
            break;
        case 0x40000802:
            codec->codec_id = AV_CODEC_ID_ADPCM_THP;
            break;
        default:
            avpriv_request_sample(s, "format 0x%X", format);
            return AVERROR_PATCHWELCOME;
        }

        codec->sample_rate = avio_rl32(pb);
        if (codec->sample_rate <= 0)
            return AVERROR_INVALIDDATA;
        avio_skip(pb, 6);

        codec->channels    = avio_rl16(pb);
        if (!codec->channels)
            return AVERROR_INVALIDDATA;

        switch (codec->codec_id) {
        case AV_CODEC_ID_XMA2:
            ff_alloc_extradata(codec, 34);
            if (!codec->extradata)
                return AVERROR(ENOMEM);
            memset(codec->extradata, 0, 34);
            codec->block_align = 2048;
            break;
        case AV_CODEC_ID_ADPCM_THP:
            if (codec->channels > INT_MAX / 32)
                return AVERROR_INVALIDDATA;
            ff_alloc_extradata(codec, 32 * codec->channels);
            if (!codec->extradata)
                return AVERROR(ENOMEM);
            avio_seek(pb, 0x80, SEEK_SET);
            for (c = 0; c < codec->channels; c++) {
                avio_read(pb, codec->extradata + 32 * c, 32);
                avio_skip(pb, 14);
            }
            codec->block_align = 8 * codec->channels;
            break;
        }
    } else {
        av_assert0(0);
    }

    avio_skip(pb, offset - avio_tell(pb));
    s->internal->data_offset = avio_tell(pb);

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

    return 0;
}
示例#2
0
文件: smjpegdec.c 项目: komh/kmp
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)
        av_log_ask_for_sample(s, "unknown version %d\n", 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) {
                av_log_ask_for_sample(s, "multiple audio streams not supported\n");
                return AVERROR_INVALIDDATA;
            }
            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) {
                av_log_ask_for_sample(s, "multiple video streams not supported\n");
                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 %x\n", htype);
            return AVERROR_INVALIDDATA;
        }
    }

    return AVERROR_EOF;
}
示例#3
0
文件: rmdec.c 项目: BlackOmega/FFmpeg
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 {
            AV_WL32(buf, 0);
            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;
        }
        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;
            if (ast->coded_framesize * sub_packet_h != 2*ast->audio_framesize) {
                avpriv_request_sample(s, "mismatching interleaver parameters");
                return AVERROR_INVALIDDATA;
            }
            break;
        case DEINT_ID_GENR:
            if (ast->sub_packet_size <= 0 ||
                ast->sub_packet_size > ast->audio_framesize)
                return AVERROR_INVALIDDATA;
            if (ast->audio_framesize % ast->sub_packet_size)
                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 %"PRIX32"\n", ast->deint_id);
            return AVERROR_INVALIDDATA;
        }
        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);
        }

        if (read_all) {
            avio_r8(pb);
            avio_r8(pb);
            avio_r8(pb);
            rm_read_metadata(s, pb, 0);
        }
    }
    return 0;
}
示例#4
0
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,
                      uint8_t block_type, AVFormatContext *s)
{
    uint8_t * vidbuf_start = NULL;
    int vidbuf_nbytes = 0;
    int code;
    int bytes_copied = 0;
    int position, duration, npixels;
    unsigned int vidbuf_capacity;
    int ret = 0;
    AVStream *st;

    if (vid->video_index < 0) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        vid->video_index = st->index;
        if (vid->audio_index < 0) {
            av_log_ask_for_sample(s, "No audio packet before first video "
                                  "packet. Using default video time base.\n");
        }
        avpriv_set_pts_info(st, 64, 185, vid->sample_rate);
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;
        st->codec->width      = vid->width;
        st->codec->height     = vid->height;
    }
    st      = s->streams[vid->video_index];
    npixels = st->codec->width * st->codec->height;

    vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE);
    if(!vidbuf_start)
        return AVERROR(ENOMEM);

    // save the file position for the packet, include block type
    position = avio_tell(pb) - 1;

    vidbuf_start[vidbuf_nbytes++] = block_type;

    // get the current packet duration
    duration = vid->bethsoft_global_delay + avio_rl16(pb);

    // set the y offset if it exists (decoder header data should be in data section)
    if(block_type == VIDEO_YOFF_P_FRAME){
        if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) {
            ret = AVERROR(EIO);
            goto fail;
        }
        vidbuf_nbytes += 2;
    }

    do{
        vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE);
        if(!vidbuf_start)
            return AVERROR(ENOMEM);

        code = avio_r8(pb);
        vidbuf_start[vidbuf_nbytes++] = code;

        if(code >= 0x80){ // rle sequence
            if(block_type == VIDEO_I_FRAME)
                vidbuf_start[vidbuf_nbytes++] = avio_r8(pb);
        } else if(code){ // plain sequence
            if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) {
                ret = AVERROR(EIO);
                goto fail;
            }
            vidbuf_nbytes += code;
        }
        bytes_copied += code & 0x7F;
        if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied
            // may contain a 0 byte even if read all pixels
            if(avio_r8(pb))
                avio_seek(pb, -1, SEEK_CUR);
            break;
        }
        if (bytes_copied > npixels) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
    } while(code);

    // copy data into packet
    if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)
        goto fail;
    memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);
    av_free(vidbuf_start);

    pkt->pos = position;
    pkt->stream_index = vid->video_index;
    pkt->duration = duration;
    if (block_type == VIDEO_I_FRAME)
        pkt->flags |= AV_PKT_FLAG_KEY;

    /* if there is a new palette available, add it to packet side data */
    if (vid->palette) {
        uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                                 BVID_PALETTE_SIZE);
        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
        av_freep(&vid->palette);
    }

    vid->nframes--;  // used to check if all the frames were read
    return 0;
fail:
    av_free(vidbuf_start);
    return ret;
}
/**
 * @return 0 when a packet was written into /p pkt, and no more data is left;
 *         1 when a packet was written into /p pkt, and more packets might be left;
 *        <0 when not enough data was provided to return a full packet, or on error.
 */
static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
                               AVStream *st, AVPacket *pkt,
                               uint32_t *timestamp,
                               const uint8_t *buf, int len, uint16_t seq,
                               int flags)
{
    AVIOContext *pb = &asf->pb;
    int res, mflags, len_off;
    RTSPState *rt = s->priv_data;

    if (!rt->asf_ctx)
        return -1;

    if (len > 0) {
        int off, out_len = 0;

        if (len < 4)
            return -1;

        av_freep(&asf->buf);

        ffio_init_context(pb, buf, len, 0, NULL, NULL, NULL, NULL);

        while (avio_tell(pb) + 4 < len) {
            int start_off = avio_tell(pb);

            mflags = avio_r8(pb);
            if (mflags & 0x80)
                flags |= RTP_FLAG_KEY;
            len_off = avio_rb24(pb);
            if (mflags & 0x20)   /**< relative timestamp */
                avio_skip(pb, 4);
            if (mflags & 0x10)   /**< has duration */
                avio_skip(pb, 4);
            if (mflags & 0x8)    /**< has location ID */
                avio_skip(pb, 4);
            off = avio_tell(pb);

            if (!(mflags & 0x40)) {
                /**
                 * If 0x40 is not set, the len_off field specifies an offset
                 * of this packet's payload data in the complete (reassembled)
                 * ASF packet. This is used to spread one ASF packet over
                 * multiple RTP packets.
                 */
                if (asf->pktbuf && len_off != avio_tell(asf->pktbuf)) {
                    uint8_t *p;
                    avio_close_dyn_buf(asf->pktbuf, &p);
                    asf->pktbuf = NULL;
                    av_free(p);
                }
                if (!len_off && !asf->pktbuf &&
                    (res = avio_open_dyn_buf(&asf->pktbuf)) < 0)
                    return res;
                if (!asf->pktbuf)
                    return AVERROR(EIO);

                avio_write(asf->pktbuf, buf + off, len - off);
                avio_skip(pb, len - off);
                if (!(flags & RTP_FLAG_MARKER))
                    return -1;
                out_len     = avio_close_dyn_buf(asf->pktbuf, &asf->buf);
                asf->pktbuf = NULL;
            } else {
                /**
                 * If 0x40 is set, the len_off field specifies the length of
                 * the next ASF packet that can be read from this payload
                 * data alone. This is commonly the same as the payload size,
                 * but could be less in case of packet splitting (i.e.
                 * multiple ASF packets in one RTP packet).
                 */

                int cur_len = start_off + len_off - off;
                int prev_len = out_len;
                out_len += cur_len;
                if (FFMIN(cur_len, len - off) < 0)
                    return -1;
                if ((res = av_reallocp(&asf->buf, out_len)) < 0)
                    return res;
                memcpy(asf->buf + prev_len, buf + off,
                       FFMIN(cur_len, len - off));
                avio_skip(pb, cur_len);
            }
        }

        init_packetizer(pb, asf->buf, out_len);
        pb->pos += rt->asf_pb_pos;
        pb->eof_reached = 0;
        rt->asf_ctx->pb = pb;
    }

    for (;;) {
        int i;

        res = ff_read_packet(rt->asf_ctx, pkt);
        rt->asf_pb_pos = avio_tell(pb);
        if (res != 0)
            break;
        for (i = 0; i < s->nb_streams; i++) {
            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
                pkt->stream_index = i;
                return 1; // FIXME: return 0 if last packet
            }
        }
        av_free_packet(pkt);
    }

    return res == 1 ? -1 : res;
}
示例#6
0
static void get_str8(AVIOContext *pb, char *buf, int buf_size)
{
    get_strl(pb, buf, buf_size, avio_r8(pb));
}
static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    enum IEC61937DataType data_type;
    enum CodecID codec_id;
    uint32_t state = 0;
    int pkt_size_bits, offset, ret;

    while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
        state = (state << 8) | avio_r8(pb);
        if (url_feof(pb))
            return AVERROR_EOF;
    }

    data_type = (IEC61937DataType)avio_rl16(pb);
    pkt_size_bits = avio_rl16(pb);

    if (pkt_size_bits % 16)
        av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary.");

    ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
    if (ret)
        return ret;

    pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE;

    if (avio_read(pb, pkt->data, pkt->size) < pkt->size) {
        av_free_packet(pkt);
        return AVERROR_EOF;
    }
    ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1);

    ret = spdif_get_offset_and_codec(s, data_type, (const char *)pkt->data,
                                     &offset, &codec_id);
    if (ret) {
        av_free_packet(pkt);
        return ret;
    }

    /* skip over the padding to the beginning of the next frame */
    avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE);

    if (!s->nb_streams) {
        /* first packet, create a stream */
        AVStream *st = avformat_new_stream(s, NULL);
        if (!st) {
            av_free_packet(pkt);
            return AVERROR(ENOMEM);
        }
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = codec_id;
    } else if (codec_id != s->streams[0]->codec->codec_id) {
        av_log_missing_feature(s, "codec change in IEC 61937", 0);
        return AVERROR_PATCHWELCOME;
    }

    if (!s->bit_rate && s->streams[0]->codec->sample_rate)
        /* stream bitrate matches 16-bit stereo PCM bitrate for currently
           supported codecs */
        s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate;

    return 0;
}
示例#8
0
文件: pva.c 项目: 2BReality/xbmc
static int read_part_of_packet(AVFormatContext *s, int64_t *pts,
                               int *len, int *strid, int read_packet) {
    AVIOContext *pb = s->pb;
    PVAContext *pvactx = s->priv_data;
    int syncword, streamid, reserved, flags, length, pts_flag;
    int64_t pva_pts = AV_NOPTS_VALUE, startpos;

recover:
    startpos = avio_tell(pb);

    syncword = avio_rb16(pb);
    streamid = avio_r8(pb);
    avio_r8(pb);               /* counter not used */
    reserved = avio_r8(pb);
    flags    = avio_r8(pb);
    length   = avio_rb16(pb);

    pts_flag = flags & 0x10;

    if (syncword != PVA_MAGIC) {
        pva_log(s, AV_LOG_ERROR, "invalid syncword\n");
        return AVERROR(EIO);
    }
    if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) {
        pva_log(s, AV_LOG_ERROR, "invalid streamid\n");
        return AVERROR(EIO);
    }
    if (reserved != 0x55) {
        pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n");
    }
    if (length > PVA_MAX_PAYLOAD_LENGTH) {
        pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length);
        return AVERROR(EIO);
    }

    if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) {
        pva_pts = avio_rb32(pb);
        length -= 4;
    } else if (streamid == PVA_AUDIO_PAYLOAD) {
        /* PVA Audio Packets either start with a signaled PES packet or
         * are a continuation of the previous PES packet. New PES packets
         * always start at the beginning of a PVA Packet, never somewhere in
         * the middle. */
        if (!pvactx->continue_pes) {
            int pes_signal, pes_header_data_length, pes_packet_length,
                pes_flags;
            unsigned char pes_header_data[256];

            pes_signal             = avio_rb24(pb);
            avio_r8(pb);
            pes_packet_length      = avio_rb16(pb);
            pes_flags              = avio_rb16(pb);
            pes_header_data_length = avio_r8(pb);

            if (pes_signal != 1) {
                pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, "
                                          "trying to recover\n");
                avio_skip(pb, length - 9);
                if (!read_packet)
                    return AVERROR(EIO);
                goto recover;
            }

            avio_read(pb, pes_header_data, pes_header_data_length);
            length -= 9 + pes_header_data_length;

            pes_packet_length -= 3 + pes_header_data_length;

            pvactx->continue_pes = pes_packet_length;

            if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20)
                pva_pts = ff_parse_pes_pts(pes_header_data);
        }

        pvactx->continue_pes -= length;

        if (pvactx->continue_pes < 0) {
            pva_log(s, AV_LOG_WARNING, "audio data corruption\n");
            pvactx->continue_pes = 0;
        }
    }

    if (pva_pts != AV_NOPTS_VALUE)
        av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME);

    *pts   = pva_pts;
    *len   = length;
    *strid = streamid;
    return 0;
}
示例#9
0
文件: nuv.c 项目: jhludwig/mythtv
static int nuv_header(AVFormatContext *s) {
    NUVContext *ctx = s->priv_data;
    AVIOContext *pb = s->pb;
    char id_string[12];
    double aspect, fps;
    int is_mythtv, width, height, v_packs, a_packs;
    int stream_nr = 0;
    AVStream *vst = NULL, *ast = NULL;
    avio_read(pb, id_string, 12);
    is_mythtv = !memcmp(id_string, "MythTVVideo", 12);
    avio_skip(pb, 5); // version string
    avio_skip(pb, 3); // padding
    width = avio_rl32(pb);
    height = avio_rl32(pb);
    avio_rl32(pb); // unused, "desiredwidth"
    avio_rl32(pb); // unused, "desiredheight"
    avio_r8(pb); // 'P' == progressive, 'I' == interlaced
    avio_skip(pb, 3); // padding
    aspect = av_int2double(avio_rl64(pb));
    if (aspect > 0.9999 && aspect < 1.0001)
        aspect = 4.0 / 3.0;
    fps = av_int2double(avio_rl64(pb));

    // number of packets per stream type, -1 means unknown, e.g. streaming
    v_packs = avio_rl32(pb);
    a_packs = avio_rl32(pb);
    avio_rl32(pb); // text

    avio_rl32(pb); // keyframe distance (?)

    if (v_packs) {
        ctx->v_id = stream_nr++;
        vst = avformat_new_stream(s, NULL);
        if (!vst)
            return AVERROR(ENOMEM);
        vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        vst->codec->codec_id = CODEC_ID_NUV;
        vst->codec->width = width;
        vst->codec->height = height;
        vst->codec->bits_per_coded_sample = 10;
        vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000);
        vst->r_frame_rate = av_d2q(fps, 60000);
        avpriv_set_pts_info(vst, 32, 1, 1000);
    } else
        ctx->v_id = -1;

    if (a_packs) {
        ctx->a_id = stream_nr++;
        ast = avformat_new_stream(s, NULL);
        if (!ast)
            return AVERROR(ENOMEM);
        ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        ast->codec->codec_id = CODEC_ID_PCM_S16LE;
        ast->codec->channels = 2;
        ast->codec->sample_rate = 44100;
        ast->codec->bit_rate = 2 * 2 * 44100 * 8;
        ast->codec->block_align = 2 * 2;
        ast->codec->bits_per_coded_sample = 16;
        avpriv_set_pts_info(ast, 32, 1, 1000);
    } else
        ctx->a_id = -1;

    get_codec_data(pb, vst, ast, is_mythtv);
    ctx->rtjpg_video = vst && vst->codec->codec_id == CODEC_ID_NUV;
    return 0;
}
示例#10
0
文件: iff.c 项目: AleXoundOS/FFmpeg
static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof)
{
    AVIOContext *pb = s->pb;
    char abss[24];
    int hour, min, sec, i, ret, config;
    int dsd_layout[6];
    ID3v2ExtraMeta *id3v2_extra_meta;

    while (avio_tell(pb) + 12 <= eof) {
        uint32_t tag      = avio_rl32(pb);
        uint64_t size     = avio_rb64(pb);
        uint64_t orig_pos = avio_tell(pb);

        switch(tag) {
        case MKTAG('A','B','S','S'):
            if (size < 8)
                return AVERROR_INVALIDDATA;
            hour = avio_rb16(pb);
            min  = avio_r8(pb);
            sec  = avio_r8(pb);
            snprintf(abss, sizeof(abss), "%02dh:%02dm:%02ds:%d", hour, min, sec, avio_rb32(pb));
            av_dict_set(&st->metadata, "absolute_start_time", abss, 0);
            break;

        case MKTAG('C','H','N','L'):
            if (size < 2)
                return AVERROR_INVALIDDATA;
            st->codec->channels       = avio_rb16(pb);
            if (size < 2 + st->codec->channels * 4)
                return AVERROR_INVALIDDATA;
            st->codec->channel_layout = 0;
            if (st->codec->channels > FF_ARRAY_ELEMS(dsd_layout)) {
                avpriv_request_sample(s, "channel layout");
                break;
            }
            for (i = 0; i < st->codec->channels; i++)
                dsd_layout[i] = avio_rl32(pb);
            for (i = 0; i < FF_ARRAY_ELEMS(dsd_channel_layout); i++) {
                const DSDLayoutDesc * d = &dsd_channel_layout[i];
                if (av_get_channel_layout_nb_channels(d->layout) == st->codec->channels &&
                    !memcmp(d->dsd_layout, dsd_layout, st->codec->channels * sizeof(uint32_t))) {
                    st->codec->channel_layout = d->layout;
                    break;
                }
            }
            break;

        case MKTAG('C','M','P','R'):
            if (size < 4)
                return AVERROR_INVALIDDATA;
            tag = avio_rl32(pb);
            st->codec->codec_id = ff_codec_get_id(dsd_codec_tags, tag);
            if (!st->codec->codec_id) {
                av_log(s, AV_LOG_ERROR, "'%c%c%c%c' compression is not supported\n",
                    tag&0xFF, (tag>>8)&0xFF, (tag>>16)&0xFF, (tag>>24)&0xFF);
                return AVERROR_PATCHWELCOME;
            }
            break;

        case MKTAG('F','S',' ',' '):
            if (size < 4)
                return AVERROR_INVALIDDATA;
            st->codec->sample_rate = avio_rb32(pb) / 8;
            break;

        case MKTAG('I','D','3',' '):
            id3v2_extra_meta = NULL;
            ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size);
            if (id3v2_extra_meta) {
                if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) {
                    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
                    return ret;
                }
                ff_id3v2_free_extra_meta(&id3v2_extra_meta);
            }

            if (size < avio_tell(pb) - orig_pos) {
                av_log(s, AV_LOG_ERROR, "id3 exceeds chunk size\n");
                return AVERROR_INVALIDDATA;
            }
            break;

        case MKTAG('L','S','C','O'):
            if (size < 2)
                return AVERROR_INVALIDDATA;
            config = avio_rb16(pb);
            if (config != 0xFFFF) {
                if (config < FF_ARRAY_ELEMS(dsd_loudspeaker_config))
                    st->codec->channel_layout = dsd_loudspeaker_config[config];
                if (!st->codec->channel_layout)
                    avpriv_request_sample(s, "loudspeaker configuration %d", config);
            }
            break;
        }

        avio_skip(pb, size - (avio_tell(pb) - orig_pos) + (size & 1));
    }
示例#11
0
文件: mp3dec.c 项目: changbiao/libav
static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
                               MPADecodeHeader *c, uint32_t spf)
{
#define LAST_BITS(k, n) ((k) & ((1 << (n)) - 1))
#define MIDDLE_BITS(k, m, n) LAST_BITS((k) >> (m), ((n) - (m)))

    uint16_t crc;
    uint32_t v;

    char version[10];

    uint32_t peak   = 0;
    int32_t  r_gain = INT32_MIN, a_gain = INT32_MIN;

    MP3DecContext *mp3 = s->priv_data;
    const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};

    /* Check for Xing / Info tag */
    avio_skip(s->pb, xing_offtbl[c->lsf == 1][c->nb_channels == 1]);
    v = avio_rb32(s->pb);
    mp3->is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
    if (v != MKBETAG('X', 'i', 'n', 'g') && !mp3->is_cbr)
        return;

    v = avio_rb32(s->pb);
    if (v & XING_FLAG_FRAMES)
        mp3->frames = avio_rb32(s->pb);
    if (v & XING_FLAG_SIZE)
        mp3->size = avio_rb32(s->pb);
    if (v & XING_FLAG_TOC && mp3->frames)
        read_xing_toc(s, mp3->size, av_rescale_q(mp3->frames,
                                       (AVRational){spf, c->sample_rate},
                                       st->time_base));

    /* VBR quality */
    if (v & XING_FLAC_QSCALE)
        avio_rb32(s->pb);

    /* Encoder short version string */
    memset(version, 0, sizeof(version));
    avio_read(s->pb, version, 9);

    /* Info Tag revision + VBR method */
    avio_r8(s->pb);

    /* Lowpass filter value */
    avio_r8(s->pb);

    /* ReplayGain peak */
    v    = avio_rb32(s->pb);
    peak = av_rescale(v, 100000, 1 << 23);

    /* Radio ReplayGain */
    v = avio_rb16(s->pb);

    if (MIDDLE_BITS(v, 13, 15) == 1) {
        r_gain = MIDDLE_BITS(v, 0, 8) * 10000;

        if (v & (1 << 9))
            r_gain *= -1;
    }

    /* Audiophile ReplayGain */
    v = avio_rb16(s->pb);

    if (MIDDLE_BITS(v, 13, 15) == 2) {
        a_gain = MIDDLE_BITS(v, 0, 8) * 10000;

        if (v & (1 << 9))
            a_gain *= -1;
    }

    /* Encoding flags + ATH Type */
    avio_r8(s->pb);

    /* if ABR {specified bitrate} else {minimal bitrate} */
    avio_r8(s->pb);

    /* Encoder delays */
    avio_rb24(s->pb);

    /* Misc */
    avio_r8(s->pb);

    /* MP3 gain */
    avio_r8(s->pb);

    /* Preset and surround info */
    avio_rb16(s->pb);

    /* Music length */
    avio_rb32(s->pb);

    /* Music CRC */
    avio_rb16(s->pb);

    /* Info Tag CRC */
    crc = ffio_get_checksum(s->pb);
    v   = avio_rb16(s->pb);

    if (v == crc) {
        ff_replaygain_export_raw(st, r_gain, peak, a_gain, 0);
        av_dict_set(&st->metadata, "encoder", version, 0);
    }
}
示例#12
0
文件: ape.c 项目: AleXoundOS/FFmpeg
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 AVERROR_INVALIDDATA;

    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 AVERROR_PATCHWELCOME;
    }

    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 AVERROR_INVALIDDATA;
    }
    if (ape->seektablelength / sizeof(*ape->seektable) < ape->totalframes) {
        av_log(s, AV_LOG_ERROR,
               "Number of seek entries is less than number of frames: %"SIZE_SPECIFIER" vs. %"PRIu32"\n",
               ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
        return AVERROR_INVALIDDATA;
    }
    ape->frames       = av_malloc_array(ape->totalframes, sizeof(APEFrame));
    if(!ape->frames)
        return AVERROR(ENOMEM);
    ape->firstframe   = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength;
    if (ape->fileversion < 3810)
        ape->firstframe += ape->totalframes;
    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_mallocz(ape->seektablelength);
        if (!ape->seektable)
            return AVERROR(ENOMEM);
        for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++)
            ape->seektable[i] = avio_rl32(pb);
        if (ape->fileversion < 3810) {
            ape->bittable = av_mallocz(ape->totalframes);
            if (!ape->bittable)
                return AVERROR(ENOMEM);
            for (i = 0; i < ape->totalframes && !pb->eof_reached; i++)
                ape->bittable[i] = avio_r8(pb);
        }
        if (pb->eof_reached)
            av_log(s, AV_LOG_WARNING, "File truncated\n");
    }

    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;
    }
    if (ape->fileversion < 3810) {
        for (i = 0; i < ape->totalframes; i++) {
            if (i < ape->totalframes - 1 && ape->bittable[i + 1])
                ape->frames[i].size += 4;
            ape->frames[i].skip <<= 3;
            ape->frames[i].skip  += ape->bittable[i];
        }
    }

    ape_dumpinfo(s, ape);

    av_log(s, AV_LOG_VERBOSE, "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 AVERROR(ENOMEM);

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

    st->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id        = AV_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;
    avpriv_set_pts_info(st, 64, 1, ape->samplerate);

    if (ff_alloc_extradata(st->codec, APE_EXTRADATA_SIZE))
        return AVERROR(ENOMEM);
    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;
    }

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

    return 0;
}
示例#13
0
文件: rmdec.c 项目: bavison/libav
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
                                   RMDemuxContext *rm, RMStream *vst,
                                   AVPacket *pkt, int len, int *pseq,
                                   int64_t *timestamp)
{
    int hdr, seq, pic_num, len2, pos;
    int type;

    hdr = avio_r8(pb); len--;
    type = hdr >> 6;

    if(type != 3){  // not frame as a part of packet
        seq = avio_r8(pb); len--;
    }
    if(type != 1){  // not whole frame
        len2 = get_num(pb, &len);
        pos  = get_num(pb, &len);
        pic_num = avio_r8(pb); len--;
    }
    if(len<0)
        return -1;
    rm->remaining_len = len;
    if(type&1){     // frame, not slice
        if(type == 3){  // frame as a part of packet
            len= len2;
            *timestamp = pos;
        }
        if(rm->remaining_len < len)
            return -1;
        rm->remaining_len -= len;
        if(av_new_packet(pkt, len + 9) < 0)
            return AVERROR(EIO);
        pkt->data[0] = 0;
        AV_WL32(pkt->data + 1, 1);
        AV_WL32(pkt->data + 5, 0);
        avio_read(pb, pkt->data + 9, len);
        return 0;
    }
    //now we have to deal with single slice

    *pseq = seq;
    if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
        vst->slices = ((hdr & 0x3F) << 1) + 1;
        vst->videobufsize = len2 + 8*vst->slices + 1;
        av_free_packet(&vst->pkt); //FIXME this should be output.
        if(av_new_packet(&vst->pkt, vst->videobufsize) < 0)
            return AVERROR(ENOMEM);
        vst->videobufpos = 8*vst->slices + 1;
        vst->cur_slice = 0;
        vst->curpic_num = pic_num;
        vst->pktpos = avio_tell(pb);
    }
    if(type == 2)
        len = FFMIN(len, pos);

    if(++vst->cur_slice > vst->slices)
        return 1;
    AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
    AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
    if(vst->videobufpos + len > vst->videobufsize)
        return 1;
    if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len)
        return AVERROR(EIO);
    vst->videobufpos += len;
    rm->remaining_len-= len;

    if (type == 2 || vst->videobufpos == vst->videobufsize) {
        vst->pkt.data[0] = vst->cur_slice-1;
        *pkt= vst->pkt;
        vst->pkt.data= NULL;
        vst->pkt.size= 0;
        vst->pkt.buf = NULL;
#if FF_API_DESTRUCT_PACKET
        vst->pkt.destruct = NULL;
#endif
        if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
            memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
                vst->videobufpos - 1 - 8*vst->slices);
        pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices);
        pkt->pts = AV_NOPTS_VALUE;
        pkt->pos = vst->pktpos;
        vst->slices = 0;
        return 0;
    }

    return 1;
}
示例#14
0
static int yuv4_read_header(AVFormatContext *s)
{
    char header[MAX_YUV4_HEADER + 10];  // Include headroom for
                                        // the longest option
    char *tokstart, *tokend, *header_end;
    int i;
    AVIOContext *pb = s->pb;
    int width = -1, height  = -1, raten   = 0,
        rated =  0, aspectn =  0, aspectd = 0;
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE, alt_pix_fmt = AV_PIX_FMT_NONE;
    enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;
    enum AVFieldOrder field_order = AV_FIELD_UNKNOWN;
    AVStream *st;

    for (i = 0; i < MAX_YUV4_HEADER; i++) {
        header[i] = avio_r8(pb);
        if (header[i] == '\n') {
            header[i + 1] = 0x20;  // Add a space after last option.
                                   // Makes parsing "444" vs "444alpha" easier.
            header[i + 2] = 0;
            break;
        }
    }
    if (i == MAX_YUV4_HEADER)
        return -1;
    if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC)))
        return -1;

    header_end = &header[i + 1]; // Include space
    for (tokstart = &header[strlen(Y4M_MAGIC) + 1];
         tokstart < header_end; tokstart++) {
        if (*tokstart == 0x20)
            continue;
        switch (*tokstart++) {
        case 'W': // Width. Required.
            width    = strtol(tokstart, &tokend, 10);
            tokstart = tokend;
            break;
        case 'H': // Height. Required.
            height   = strtol(tokstart, &tokend, 10);
            tokstart = tokend;
            break;
        case 'C': // Color space
            if (strncmp("420jpeg", tokstart, 7) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P;
                chroma_sample_location = AVCHROMA_LOC_CENTER;
            } else if (strncmp("420mpeg2", tokstart, 8) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P;
                chroma_sample_location = AVCHROMA_LOC_LEFT;
            } else if (strncmp("420paldv", tokstart, 8) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P;
                chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
            } else if (strncmp("420p16", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P16;
            } else if (strncmp("422p16", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P16;
            } else if (strncmp("444p16", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P16;
            } else if (strncmp("420p14", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P14;
            } else if (strncmp("422p14", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P14;
            } else if (strncmp("444p14", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P14;
            } else if (strncmp("420p12", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P12;
            } else if (strncmp("422p12", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P12;
            } else if (strncmp("444p12", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P12;
            } else if (strncmp("420p10", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P10;
            } else if (strncmp("422p10", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P10;
            } else if (strncmp("444p10", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P10;
            } else if (strncmp("420p9", tokstart, 5) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P9;
            } else if (strncmp("422p9", tokstart, 5) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P9;
            } else if (strncmp("444p9", tokstart, 5) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P9;
            } else if (strncmp("420", tokstart, 3) == 0) {
                pix_fmt = AV_PIX_FMT_YUV420P;
                chroma_sample_location = AVCHROMA_LOC_CENTER;
            } else if (strncmp("411", tokstart, 3) == 0) {
                pix_fmt = AV_PIX_FMT_YUV411P;
            } else if (strncmp("422", tokstart, 3) == 0) {
                pix_fmt = AV_PIX_FMT_YUV422P;
            } else if (strncmp("444alpha", tokstart, 8) == 0 ) {
                av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 "
                       "YUV4MPEG stream.\n");
                return -1;
            } else if (strncmp("444", tokstart, 3) == 0) {
                pix_fmt = AV_PIX_FMT_YUV444P;
            } else if (strncmp("mono16", tokstart, 6) == 0) {
                pix_fmt = AV_PIX_FMT_GRAY16;
            } else if (strncmp("mono", tokstart, 4) == 0) {
                pix_fmt = AV_PIX_FMT_GRAY8;
            } else {
                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
                       "pixel format.\n");
                return -1;
            }
            while (tokstart < header_end && *tokstart != 0x20)
                tokstart++;
            break;
        case 'I': // Interlace type
            switch (*tokstart++){
            case '?':
                field_order = AV_FIELD_UNKNOWN;
                break;
            case 'p':
                field_order = AV_FIELD_PROGRESSIVE;
                break;
            case 't':
                field_order = AV_FIELD_TT;
                break;
            case 'b':
                field_order = AV_FIELD_BB;
                break;
            case 'm':
                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
                       "interlaced and non-interlaced frames.\n");
            default:
                av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
                return AVERROR(EINVAL);
            }
            break;
        case 'F': // Frame rate
            sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
            while (tokstart < header_end && *tokstart != 0x20)
                tokstart++;
            break;
        case 'A': // Pixel aspect
            sscanf(tokstart, "%d:%d", &aspectn, &aspectd); // 0:0 if unknown
            while (tokstart < header_end && *tokstart != 0x20)
                tokstart++;
            break;
        case 'X': // Vendor extensions
            if (strncmp("YSCSS=", tokstart, 6) == 0) {
                // Older nonstandard pixel format representation
                tokstart += 6;
                if (strncmp("420JPEG", tokstart, 7) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P;
                else if (strncmp("420MPEG2", tokstart, 8) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P;
                else if (strncmp("420PALDV", tokstart, 8) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P;
                else if (strncmp("420P9", tokstart, 5) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P9;
                else if (strncmp("422P9", tokstart, 5) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P9;
                else if (strncmp("444P9", tokstart, 5) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P9;
                else if (strncmp("420P10", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P10;
                else if (strncmp("422P10", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P10;
                else if (strncmp("444P10", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P10;
                else if (strncmp("420P12", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P12;
                else if (strncmp("422P12", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P12;
                else if (strncmp("444P12", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P12;
                else if (strncmp("420P14", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P14;
                else if (strncmp("422P14", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P14;
                else if (strncmp("444P14", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P14;
                else if (strncmp("420P16", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV420P16;
                else if (strncmp("422P16", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P16;
                else if (strncmp("444P16", tokstart, 6) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P16;
                else if (strncmp("411", tokstart, 3) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV411P;
                else if (strncmp("422", tokstart, 3) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV422P;
                else if (strncmp("444", tokstart, 3) == 0)
                    alt_pix_fmt = AV_PIX_FMT_YUV444P;
            }
            while (tokstart < header_end && *tokstart != 0x20)
                tokstart++;
            break;
        }
    }

    if (width == -1 || height == -1) {
        av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
        return -1;
    }

    if (pix_fmt == AV_PIX_FMT_NONE) {
        if (alt_pix_fmt == AV_PIX_FMT_NONE)
            pix_fmt = AV_PIX_FMT_YUV420P;
        else
            pix_fmt = alt_pix_fmt;
    }

    if (raten <= 0 || rated <= 0) {
        // Frame rate unknown
        raten = 25;
        rated = 1;
    }

    if (aspectn == 0 && aspectd == 0) {
        // Pixel aspect unknown
        aspectd = 1;
    }

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->width  = width;
    st->codec->height = height;
    av_reduce(&raten, &rated, raten, rated, (1UL << 31) - 1);
    avpriv_set_pts_info(st, 64, rated, raten);
    st->avg_frame_rate                = av_inv_q(st->time_base);
    st->codec->pix_fmt                = pix_fmt;
    st->codec->codec_type             = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id               = AV_CODEC_ID_RAWVIDEO;
    st->sample_aspect_ratio           = (AVRational){ aspectn, aspectd };
    st->codec->chroma_sample_location = chroma_sample_location;
    st->codec->field_order            = field_order;
    s->packet_size = av_image_get_buffer_size(st->codec->pix_fmt, width, height, 1) + Y4M_FRAME_MAGIC_LEN;
    if ((int) s->packet_size < 0)
        return s->packet_size;
    s->internal->data_offset = avio_tell(pb);

    st->duration = (avio_size(pb) - avio_tell(pb)) / s->packet_size;

    return 0;
}
示例#15
0
文件: sauce.c 项目: AVLeo/libav
int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int get_height)
{
    AVIOContext *pb = avctx->pb;
    char buf[36];
    int datatype, filetype, t1, t2, nb_comments;
    uint64_t start_pos = avio_size(pb) - 128;

    avio_seek(pb, start_pos, SEEK_SET);
    if (avio_read(pb, buf, 7) != 7)
        return -1;
    if (memcmp(buf, "SAUCE00", 7))
        return -1;

#define GET_SAUCE_META(name,size) \
    if (avio_read(pb, buf, size) == size && buf[0]) { \
        buf[size] = 0; \
        av_dict_set(&avctx->metadata, name, buf, 0); \
    }

    GET_SAUCE_META("title",     35)
    GET_SAUCE_META("artist",    20)
    GET_SAUCE_META("publisher", 20)
    GET_SAUCE_META("date",      8)
    avio_skip(pb, 4);
    datatype    = avio_r8(pb);
    filetype    = avio_r8(pb);
    t1          = avio_rl16(pb);
    t2          = avio_rl16(pb);
    nb_comments = avio_r8(pb);
    avio_skip(pb, 1); /* flags */
    avio_skip(pb, 4);
    GET_SAUCE_META("encoder",   22);

    if (got_width && datatype && filetype) {
        if ((datatype == 1 && filetype <=2) || (datatype == 5 && filetype == 255) || datatype == 6) {
            if (t1) {
                avctx->streams[0]->codecpar->width = t1<<3;
                *got_width = 1;
            }
            if (get_height && t2)
                avctx->streams[0]->codecpar->height = t2<<4;
        } else if (datatype == 5) {
            if (filetype > 1) {
                avctx->streams[0]->codecpar->width = (filetype == 1 ? t1 : filetype) << 4;
                *got_width = 1;
            }
            if (get_height && t2)
                avctx->streams[0]->codecpar->height = t2<<4;
        }
    }

    *fsize -= 128;

    if (nb_comments > 0) {
        avio_seek(pb, start_pos - 64*nb_comments - 5, SEEK_SET);
        if (avio_read(pb, buf, 5) == 5 && !memcmp(buf, "COMNT", 5)) {
            int i;
            char *str = av_malloc(65*nb_comments + 1);
            *fsize -= 64*nb_comments + 5;
            if (!str)
                return 0;
            for (i = 0; i < nb_comments; i++) {
                if (avio_read(pb, str + 65*i, 64) != 64)
                    break;
                str[65*i + 64] = '\n';
            }
            str[65*i] = 0;
            av_dict_set(&avctx->metadata, "comment", str, AV_DICT_DONT_STRDUP_VAL);
        }
    }

    return 0;
}
示例#16
0
文件: nuv.c 项目: jhludwig/mythtv
/**
 * @brief read until we found all data needed for decoding
 * @param vst video stream of which to change parameters
 * @param ast video stream of which to change parameters
 * @param myth set if this is a MythTV Video format file
 * @return 1 if all required codec data was found
 */
static int get_codec_data(AVIOContext *pb, AVStream *vst,
                          AVStream *ast, int myth) {
    nuv_frametype frametype;
    if (!vst && !myth)
        return 1; // no codec data needed
    while (!url_feof(pb)) {
        int size, subtype;
        frametype = avio_r8(pb);
        switch (frametype) {
            case NUV_EXTRADATA:
                subtype = avio_r8(pb);
                avio_skip(pb, 6);
                size = PKTSIZE(avio_rl32(pb));
                if (vst && subtype == 'R') {
                    vst->codec->extradata_size = size;
                    vst->codec->extradata = av_malloc(size);
                    avio_read(pb, vst->codec->extradata, size);
                    size = 0;
                    if (!myth)
                        return 1;
                }
                break;
            case NUV_MYTHEXT:
                avio_skip(pb, 7);
                size = PKTSIZE(avio_rl32(pb));
                if (size != 128 * 4)
                    break;
                avio_rl32(pb); // version
                if (vst) {
                    vst->codec->codec_tag = avio_rl32(pb);
                    vst->codec->codec_id =
                        ff_codec_get_id(ff_codec_bmp_tags, vst->codec->codec_tag);
                    if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G'))
                        vst->codec->codec_id = CODEC_ID_NUV;
                } else
                    avio_skip(pb, 4);

                if (ast) {
                    ast->codec->codec_tag = avio_rl32(pb);
                    ast->codec->sample_rate = avio_rl32(pb);
                    ast->codec->bits_per_coded_sample = avio_rl32(pb);
                    ast->codec->channels = avio_rl32(pb);
                    ast->codec->codec_id =
                        ff_wav_codec_get_id(ast->codec->codec_tag,
                                         ast->codec->bits_per_coded_sample);
                    ast->need_parsing = AVSTREAM_PARSE_FULL;
                } else
                    avio_skip(pb, 4 * 4);

                size -= 6 * 4;
                avio_skip(pb, size);
                return 1;
            case NUV_SEEKP:
                size = 11;
                break;
            default:
                avio_skip(pb, 7);
                size = PKTSIZE(avio_rl32(pb));
                break;
        }
        avio_skip(pb, size);
    }
    return 0;
}
示例#17
0
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
                                   RMDemuxContext *rm, RMStream *vst,
                                   AVPacket *pkt, int len, int *pseq,
                                   int64_t *timestamp)
{
    int hdr;
    int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silcense compiler warning
    int type;
    int ret;

    hdr = avio_r8(pb); len--;
    type = hdr >> 6;

    if(type != 3){  // not frame as a part of packet
        seq = avio_r8(pb); len--;
    }
    if(type != 1){  // not whole frame
        len2 = get_num(pb, &len);
        pos  = get_num(pb, &len);
        pic_num = avio_r8(pb); len--;
    }
    if(len<0) {
        av_log(s, AV_LOG_ERROR, "Insufficient data\n");
        return -1;
    }
    rm->remaining_len = len;
    if(type&1){     // frame, not slice
        if(type == 3){  // frame as a part of packet
            len= len2;
            *timestamp = pos;
        }
        if(rm->remaining_len < len) {
            av_log(s, AV_LOG_ERROR, "Insufficient remaining len\n");
            return -1;
        }
        rm->remaining_len -= len;
        if(av_new_packet(pkt, len + 9) < 0)
            return AVERROR(EIO);
        pkt->data[0] = 0;
        AV_WL32(pkt->data + 1, 1);
        AV_WL32(pkt->data + 5, 0);
        if ((ret = avio_read(pb, pkt->data + 9, len)) != len) {
            av_free_packet(pkt);
            av_log(s, AV_LOG_ERROR, "Failed to read %d bytes\n", len);
            return ret < 0 ? ret : AVERROR(EIO);
        }
        return 0;
    }
    //now we have to deal with single slice

    *pseq = seq;
    if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
        if (len2 > ffio_limit(pb, len2)) {
            av_log(s, AV_LOG_ERROR, "Impossibly sized packet\n");
            return AVERROR_INVALIDDATA;
        }
        vst->slices = ((hdr & 0x3F) << 1) + 1;
        vst->videobufsize = len2 + 8*vst->slices + 1;
        av_free_packet(&vst->pkt); //FIXME this should be output.
        if(av_new_packet(&vst->pkt, vst->videobufsize) < 0)
            return AVERROR(ENOMEM);
        memset(vst->pkt.data, 0, vst->pkt.size);
        vst->videobufpos = 8*vst->slices + 1;
        vst->cur_slice = 0;
        vst->curpic_num = pic_num;
        vst->pktpos = avio_tell(pb);
    }
    if(type == 2)
        len = FFMIN(len, pos);

    if(++vst->cur_slice > vst->slices) {
        av_log(s, AV_LOG_ERROR, "cur slice %d, too large\n", vst->cur_slice);
        return 1;
    }
    if(!vst->pkt.data)
        return AVERROR(ENOMEM);
    AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
    AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
    if(vst->videobufpos + len > vst->videobufsize) {
        av_log(s, AV_LOG_ERROR, "outside videobufsize\n");
        return 1;
    }
    if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len)
        return AVERROR(EIO);
    vst->videobufpos += len;
    rm->remaining_len-= len;

    if (type == 2 || vst->videobufpos == vst->videobufsize) {
        vst->pkt.data[0] = vst->cur_slice-1;
        *pkt= vst->pkt;
        vst->pkt.data= NULL;
        vst->pkt.size= 0;
        vst->pkt.buf = NULL;
#if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
        vst->pkt.destruct = NULL;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
        if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
            memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
                vst->videobufpos - 1 - 8*vst->slices);
        pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices);
        pkt->pts = AV_NOPTS_VALUE;
        pkt->pos = vst->pktpos;
        vst->slices = 0;
        return 0;
    }
示例#18
0
static int rsd_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    int i, version, start = 0x800;
    AVCodecContext *codec;
    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)
        return AVERROR(ENOMEM);

    avio_skip(pb, 3); // "RSD"
    version = avio_r8(pb) - '0';

    codec = st->codec;
    codec->codec_type = AVMEDIA_TYPE_AUDIO;
    codec->codec_tag  = avio_rl32(pb);
    codec->codec_id   = ff_codec_get_id(rsd_tags, codec->codec_tag);
    if (!codec->codec_id) {
        char tag_buf[5];

        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag);
        for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) {
            if (codec->codec_tag == rsd_unsupported_tags[i]) {
                avpriv_request_sample(s, "Codec tag: %s", tag_buf);
                return AVERROR_PATCHWELCOME;
            }
        }
        av_log(s, AV_LOG_ERROR, "Unknown codec tag: %s\n", tag_buf);
        return AVERROR_INVALIDDATA;
    }

    codec->channels = avio_rl32(pb);
    if (!codec->channels)
        return AVERROR_INVALIDDATA;

    avio_skip(pb, 4); // Bit depth
    codec->sample_rate = avio_rl32(pb);
    if (!codec->sample_rate)
        return AVERROR_INVALIDDATA;

    avio_skip(pb, 4); // Unknown

    switch (codec->codec_id) {
    case AV_CODEC_ID_ADPCM_IMA_RAD:
        codec->block_align = 20 * codec->channels;
        if (pb->seekable)
            st->duration = av_get_audio_frame_duration(codec, avio_size(pb) - start);
        break;
    case AV_CODEC_ID_ADPCM_THP:
        /* RSD3GADP is mono, so only alloc enough memory
           to store the coeff table for a single channel. */

        start = avio_rl32(pb);

        if (ff_get_extradata(codec, s->pb, 32) < 0)
            return AVERROR(ENOMEM);

        for (i = 0; i < 16; i++)
            AV_WB16(codec->extradata + i * 2, AV_RL16(codec->extradata + i * 2));

        if (pb->seekable)
            st->duration = (avio_size(pb) - start) / 8 * 14;
        break;
    case AV_CODEC_ID_PCM_S16LE:
    case AV_CODEC_ID_PCM_S16BE:
        if (version != 4)
            start = avio_rl32(pb);

        if (pb->seekable)
            st->duration = (avio_size(pb) - start) / 2 / codec->channels;
        break;
    }

    avio_skip(pb, start - avio_tell(pb));

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

    return 0;
}
示例#19
0
static int seq_parse_frame_data(SeqDemuxContext *seq, AVIOContext *pb)
{
	unsigned int offset_table[4], buffer_num[4];
	TiertexSeqFrameBuffer *seq_buffer;
	int i, e, err;

	seq->current_frame_offs += SEQ_FRAME_SIZE;
	avio_seek(pb, seq->current_frame_offs, SEEK_SET);

	/* sound data */
	seq->current_audio_data_offs = avio_rl16(pb);
	if (seq->current_audio_data_offs)
	{
		seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2;
	}
	else
	{
		seq->current_audio_data_size = 0;
	}

	/* palette data */
	seq->current_pal_data_offs = avio_rl16(pb);
	if (seq->current_pal_data_offs)
	{
		seq->current_pal_data_size = 768;
	}
	else
	{
		seq->current_pal_data_size = 0;
	}

	/* video data */
	for (i = 0; i < 4; i++)
		buffer_num[i] = avio_r8(pb);

	for (i = 0; i < 4; i++)
		offset_table[i] = avio_rl16(pb);

	for (i = 0; i < 3; i++)
	{
		if (offset_table[i])
		{
			for (e = i + 1; e < 3 && offset_table[e] == 0; e++);
			err = seq_fill_buffer(seq, pb, buffer_num[1 + i],
			                      offset_table[i],
			                      offset_table[e] - offset_table[i]);
			if (err)
				return err;
		}
	}

	if (buffer_num[0] != 255)
	{
		if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS)
			return AVERROR_INVALIDDATA;

		seq_buffer = &seq->frame_buffers[buffer_num[0]];
		seq->current_video_data_size = seq_buffer->fill_size;
		seq->current_video_data_ptr  = seq_buffer->data;
		seq_buffer->fill_size = 0;
	}
	else
	{
		seq->current_video_data_size = 0;
		seq->current_video_data_ptr  = 0;
	}

	return 0;
}
示例#20
0
static int ffm2_read_header(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    AVCodecContext *codec;

    ffm->packet_size = avio_rb32(pb);
    if (ffm->packet_size != FFM_PACKET_SIZE)
        goto fail;
    ffm->write_index = avio_rb64(pb);
    /* get also filesize */
    if (pb->seekable) {
        ffm->file_size = avio_size(pb);
        if (ffm->write_index && 0)
            adjust_write_index(s);
    } else {
        ffm->file_size = (UINT64_C(1) << 63) - 1;
    }

    while(!url_feof(pb)) {
        unsigned id = avio_rb32(pb);
        unsigned size = avio_rb32(pb);
        int64_t next = avio_tell(pb) + size;
        char rc_eq_buf[128];

        if(!id)
            break;

        switch(id) {
        case MKBETAG('M', 'A', 'I', 'N'):
            avio_rb32(pb); /* nb_streams */
            avio_rb32(pb); /* total bitrate */
            break;
        case MKBETAG('C', 'O', 'M', 'M'):
            st = avformat_new_stream(s, NULL);
            if (!st)
                goto fail;

            avpriv_set_pts_info(st, 64, 1, 1000000);

            codec = st->codec;
            /* generic info */
            codec->codec_id = avio_rb32(pb);
            codec->codec_type = avio_r8(pb);
            codec->bit_rate = avio_rb32(pb);
            codec->flags = avio_rb32(pb);
            codec->flags2 = avio_rb32(pb);
            codec->debug = avio_rb32(pb);
            if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
                if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
                    return AVERROR(ENOMEM);
            }
            avio_seek(pb, next, SEEK_SET);
            id = avio_rb32(pb);
            size = avio_rb32(pb);
            next = avio_tell(pb) + size;
            switch(id) {
            case MKBETAG('S', 'T', 'V', 'I'):
                codec->time_base.num = avio_rb32(pb);
                codec->time_base.den = avio_rb32(pb);
                codec->width = avio_rb16(pb);
                codec->height = avio_rb16(pb);
                codec->gop_size = avio_rb16(pb);
                codec->pix_fmt = avio_rb32(pb);
                codec->qmin = avio_r8(pb);
                codec->qmax = avio_r8(pb);
                codec->max_qdiff = avio_r8(pb);
                codec->qcompress = avio_rb16(pb) / 10000.0;
                codec->qblur = avio_rb16(pb) / 10000.0;
                codec->bit_rate_tolerance = avio_rb32(pb);
                avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
                codec->rc_eq = av_strdup(rc_eq_buf);
                codec->rc_max_rate = avio_rb32(pb);
                codec->rc_min_rate = avio_rb32(pb);
                codec->rc_buffer_size = avio_rb32(pb);
                codec->i_quant_factor = av_int2double(avio_rb64(pb));
                codec->b_quant_factor = av_int2double(avio_rb64(pb));
                codec->i_quant_offset = av_int2double(avio_rb64(pb));
                codec->b_quant_offset = av_int2double(avio_rb64(pb));
                codec->dct_algo = avio_rb32(pb);
                codec->strict_std_compliance = avio_rb32(pb);
                codec->max_b_frames = avio_rb32(pb);
                codec->mpeg_quant = avio_rb32(pb);
                codec->intra_dc_precision = avio_rb32(pb);
                codec->me_method = avio_rb32(pb);
                codec->mb_decision = avio_rb32(pb);
                codec->nsse_weight = avio_rb32(pb);
                codec->frame_skip_cmp = avio_rb32(pb);
                codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
                codec->codec_tag = avio_rb32(pb);
                codec->thread_count = avio_r8(pb);
                codec->coder_type = avio_rb32(pb);
                codec->me_cmp = avio_rb32(pb);
                codec->me_subpel_quality = avio_rb32(pb);
                codec->me_range = avio_rb32(pb);
                codec->keyint_min = avio_rb32(pb);
                codec->scenechange_threshold = avio_rb32(pb);
                codec->b_frame_strategy = avio_rb32(pb);
                codec->qcompress = av_int2double(avio_rb64(pb));
                codec->qblur = av_int2double(avio_rb64(pb));
                codec->max_qdiff = avio_rb32(pb);
                codec->refs = avio_rb32(pb);
                break;
            case MKBETAG('S', 'T', 'A', 'U'):
                codec->sample_rate = avio_rb32(pb);
                codec->channels = avio_rl16(pb);
                codec->frame_size = avio_rl16(pb);
                break;
            }
            break;
        }
        avio_seek(pb, next, SEEK_SET);
    }

    /* get until end of block reached */
    while ((avio_tell(pb) % ffm->packet_size) != 0)
        avio_r8(pb);

    /* init packet demux */
    ffm->packet_ptr = ffm->packet;
    ffm->packet_end = ffm->packet;
    ffm->frame_offset = 0;
    ffm->dts = 0;
    ffm->read_state = READ_HEADER;
    ffm->first_packet = 1;
    return 0;
 fail:
    ffm_close(s);
    return -1;
}
示例#21
0
static int vid_read_packet(AVFormatContext *s,
                           AVPacket *pkt)
{
    BVID_DemuxContext *vid = s->priv_data;
    AVIOContext *pb = s->pb;
    unsigned char block_type;
    int audio_length;
    int ret_value;

    if(vid->is_finished || pb->eof_reached)
        return AVERROR(EIO);

    block_type = avio_r8(pb);
    switch(block_type){
        case PALETTE_BLOCK:
            if (vid->palette) {
                av_log(s, AV_LOG_WARNING, "discarding unused palette\n");
                av_freep(&vid->palette);
            }
            vid->palette = av_malloc(BVID_PALETTE_SIZE);
            if (!vid->palette)
                return AVERROR(ENOMEM);
            if (avio_read(pb, vid->palette, BVID_PALETTE_SIZE) != BVID_PALETTE_SIZE) {
                av_freep(&vid->palette);
                return AVERROR(EIO);
            }
            return vid_read_packet(s, pkt);

        case FIRST_AUDIO_BLOCK:
            avio_rl16(pb);
            // soundblaster DAC used for sample rate, as on specification page (link above)
            vid->sample_rate = 1000000 / (256 - avio_r8(pb));
        case AUDIO_BLOCK:
            if (vid->audio_index < 0) {
                AVStream *st = avformat_new_stream(s, NULL);
                if (!st)
                    return AVERROR(ENOMEM);
                vid->audio_index                 = st->index;
                st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
                st->codec->codec_id              = AV_CODEC_ID_PCM_U8;
                st->codec->channels              = 1;
                st->codec->channel_layout        = AV_CH_LAYOUT_MONO;
                st->codec->bits_per_coded_sample = 8;
                st->codec->sample_rate           = vid->sample_rate;
                st->codec->bit_rate              = 8 * st->codec->sample_rate;
                st->start_time                   = 0;
                avpriv_set_pts_info(st, 64, 1, vid->sample_rate);
            }
            audio_length = avio_rl16(pb);
            if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) {
                if (ret_value < 0)
                    return ret_value;
                av_log(s, AV_LOG_ERROR, "incomplete audio block\n");
                return AVERROR(EIO);
            }
            pkt->stream_index = vid->audio_index;
            pkt->duration     = audio_length;
            pkt->flags |= AV_PKT_FLAG_KEY;
            return 0;

        case VIDEO_P_FRAME:
        case VIDEO_YOFF_P_FRAME:
        case VIDEO_I_FRAME:
            return read_frame(vid, pb, pkt, block_type, s);

        case EOF_BLOCK:
            if(vid->nframes != 0)
                av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n");
            vid->is_finished = 1;
            return AVERROR(EIO);
        default:
            av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n",
                   block_type, block_type, block_type);
            return AVERROR_INVALIDDATA;
    }
}
示例#22
0
static int ffm_read_header(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    AVCodecContext *codec;
    int i, nb_streams;
    uint32_t tag;

    /* header */
    tag = avio_rl32(pb);
    if (tag == MKTAG('F', 'F', 'M', '2'))
        return ffm2_read_header(s);
    if (tag != MKTAG('F', 'F', 'M', '1'))
        goto fail;
    ffm->packet_size = avio_rb32(pb);
    if (ffm->packet_size != FFM_PACKET_SIZE)
        goto fail;
    ffm->write_index = avio_rb64(pb);
    /* get also filesize */
    if (pb->seekable) {
        ffm->file_size = avio_size(pb);
        if (ffm->write_index && 0)
            adjust_write_index(s);
    } else {
        ffm->file_size = (UINT64_C(1) << 63) - 1;
    }

    nb_streams = avio_rb32(pb);
    avio_rb32(pb); /* total bitrate */
    /* read each stream */
    for(i=0;i<nb_streams;i++) {
        char rc_eq_buf[128];

        st = avformat_new_stream(s, NULL);
        if (!st)
            goto fail;

        avpriv_set_pts_info(st, 64, 1, 1000000);

        codec = st->codec;
        /* generic info */
        codec->codec_id = avio_rb32(pb);
        codec->codec_type = avio_r8(pb); /* codec_type */
        codec->bit_rate = avio_rb32(pb);
        codec->flags = avio_rb32(pb);
        codec->flags2 = avio_rb32(pb);
        codec->debug = avio_rb32(pb);
        /* specific info */
        switch(codec->codec_type) {
        case AVMEDIA_TYPE_VIDEO:
            codec->time_base.num = avio_rb32(pb);
            codec->time_base.den = avio_rb32(pb);
            codec->width = avio_rb16(pb);
            codec->height = avio_rb16(pb);
            codec->gop_size = avio_rb16(pb);
            codec->pix_fmt = avio_rb32(pb);
            codec->qmin = avio_r8(pb);
            codec->qmax = avio_r8(pb);
            codec->max_qdiff = avio_r8(pb);
            codec->qcompress = avio_rb16(pb) / 10000.0;
            codec->qblur = avio_rb16(pb) / 10000.0;
            codec->bit_rate_tolerance = avio_rb32(pb);
            avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
            codec->rc_eq = av_strdup(rc_eq_buf);
            codec->rc_max_rate = avio_rb32(pb);
            codec->rc_min_rate = avio_rb32(pb);
            codec->rc_buffer_size = avio_rb32(pb);
            codec->i_quant_factor = av_int2double(avio_rb64(pb));
            codec->b_quant_factor = av_int2double(avio_rb64(pb));
            codec->i_quant_offset = av_int2double(avio_rb64(pb));
            codec->b_quant_offset = av_int2double(avio_rb64(pb));
            codec->dct_algo = avio_rb32(pb);
            codec->strict_std_compliance = avio_rb32(pb);
            codec->max_b_frames = avio_rb32(pb);
            codec->mpeg_quant = avio_rb32(pb);
            codec->intra_dc_precision = avio_rb32(pb);
            codec->me_method = avio_rb32(pb);
            codec->mb_decision = avio_rb32(pb);
            codec->nsse_weight = avio_rb32(pb);
            codec->frame_skip_cmp = avio_rb32(pb);
            codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
            codec->codec_tag = avio_rb32(pb);
            codec->thread_count = avio_r8(pb);
            codec->coder_type = avio_rb32(pb);
            codec->me_cmp = avio_rb32(pb);
            codec->me_subpel_quality = avio_rb32(pb);
            codec->me_range = avio_rb32(pb);
            codec->keyint_min = avio_rb32(pb);
            codec->scenechange_threshold = avio_rb32(pb);
            codec->b_frame_strategy = avio_rb32(pb);
            codec->qcompress = av_int2double(avio_rb64(pb));
            codec->qblur = av_int2double(avio_rb64(pb));
            codec->max_qdiff = avio_rb32(pb);
            codec->refs = avio_rb32(pb);
            break;
        case AVMEDIA_TYPE_AUDIO:
            codec->sample_rate = avio_rb32(pb);
            codec->channels = avio_rl16(pb);
            codec->frame_size = avio_rl16(pb);
            break;
        default:
            goto fail;
        }
        if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
            if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
                return AVERROR(ENOMEM);
        }
    }

    /* get until end of block reached */
    while ((avio_tell(pb) % ffm->packet_size) != 0)
        avio_r8(pb);

    /* init packet demux */
    ffm->packet_ptr = ffm->packet;
    ffm->packet_end = ffm->packet;
    ffm->frame_offset = 0;
    ffm->dts = 0;
    ffm->read_state = READ_HEADER;
    ffm->first_packet = 1;
    return 0;
 fail:
    ffm_close(s);
    return -1;
}
示例#23
0
/* mmf input */
static int mmf_read_header(AVFormatContext *s)
{
    MMFContext *mmf = s->priv_data;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    AVStream *st;
    int64_t size;
    int rate, params;

    tag = avio_rl32(pb);
    if (tag != MKTAG('M', 'M', 'M', 'D'))
        return -1;
    avio_skip(pb, 4); /* file_size */

    /* Skip some unused chunks that may or may not be present */
    for(;; avio_skip(pb, size)) {
        tag = avio_rl32(pb);
        size = avio_rb32(pb);
        if(tag == MKTAG('C','N','T','I')) continue;
        if(tag == MKTAG('O','P','D','A')) continue;
        break;
    }

    /* Tag = "ATRx", where "x" = track number */
    if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n");
        return -1;
    }
    if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag);
        return -1;
    }

    avio_r8(pb); /* format type */
    avio_r8(pb); /* sequence type */
    params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */
    rate = mmf_rate(params & 0x0f);
    if(rate  < 0) {
        av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
        return -1;
    }
    avio_r8(pb); /* wave base bit */
    avio_r8(pb); /* time base d */
    avio_r8(pb); /* time base g */

    /* Skip some unused chunks that may or may not be present */
    for(;; avio_skip(pb, size)) {
        tag = avio_rl32(pb);
        size = avio_rb32(pb);
        if(tag == MKTAG('A','t','s','q')) continue;
        if(tag == MKTAG('A','s','p','I')) continue;
        break;
    }

    /* Make sure it's followed by an Awa chunk, aka wave data */
    if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) {
        av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag);
        return -1;
    }
    mmf->data_size = size;

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

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA;
    st->codec->sample_rate = rate;
    st->codec->channels = 1;
    st->codec->bits_per_coded_sample = 4;
    st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;

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

    return 0;
}
示例#24
0
文件: ipmovie.c 项目: eugenehp/ffmbc
static int ipmovie_read_header(AVFormatContext *s,
                               AVFormatParameters *ap)
{
    IPMVEContext *ipmovie = s->priv_data;
    AVIOContext *pb = s->pb;
    AVPacket pkt;
    AVStream *st;
    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
    int chunk_type;
    uint8_t signature_buffer[sizeof(signature)];

    avio_read(pb, signature_buffer, sizeof(signature_buffer));
    while (memcmp(signature_buffer, signature, sizeof(signature))) {
        memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
        signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
        if (url_feof(pb))
            return AVERROR_EOF;
    }
    /* initialize private context members */
    ipmovie->video_pts = ipmovie->audio_frame_count = 0;
    ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset =
    ipmovie->decode_map_chunk_offset = 0;

    /* on the first read, this will position the stream at the first chunk */
    ipmovie->next_chunk_offset = avio_tell(pb) + 4;

    /* process the first chunk which should be CHUNK_INIT_VIDEO */
    if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO)
        return AVERROR_INVALIDDATA;

    /* peek ahead to the next chunk-- if it is an init audio chunk, process
     * it; if it is the first video chunk, this is a silent file */
    if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
        CHUNK_PREAMBLE_SIZE)
        return AVERROR(EIO);
    chunk_type = AV_RL16(&chunk_preamble[2]);
    avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR);

    if (chunk_type == CHUNK_VIDEO)
        ipmovie->audio_type = CODEC_ID_NONE;  /* no audio */
    else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO)
        return AVERROR_INVALIDDATA;

    /* initialize the stream decoders */
    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);
    av_set_pts_info(st, 63, 1, 1000000);
    ipmovie->video_stream_index = st->index;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_INTERPLAY_VIDEO;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = ipmovie->video_width;
    st->codec->height = ipmovie->video_height;
    st->codec->bits_per_coded_sample = ipmovie->video_bpp;

    if (ipmovie->audio_type) {
        st = av_new_stream(s, 0);
        if (!st)
            return AVERROR(ENOMEM);
        av_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
        ipmovie->audio_stream_index = st->index;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = ipmovie->audio_type;
        st->codec->codec_tag = 0;  /* no tag */
        st->codec->channels = ipmovie->audio_channels;
        st->codec->sample_rate = ipmovie->audio_sample_rate;
        st->codec->bits_per_coded_sample = ipmovie->audio_bits;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
            st->codec->bits_per_coded_sample;
        if (st->codec->codec_id == CODEC_ID_INTERPLAY_DPCM)
            st->codec->bit_rate /= 2;
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
    }

    return 0;
}
示例#25
0
static int read_header(AVFormatContext *s)
{
    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) {
        avpriv_request_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES));
        return AVERROR_PATCHWELCOME;
    }

    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 = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = AV_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);
    avpriv_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) {
        return AVERROR(ENOMEM);
    }
    ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size);
    if (ret < 0)
        return ret;

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

    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) {
        return anm->page;
    }

    anm->record = -1;
    return 0;

invalid:
    avpriv_request_sample(s, "Invalid header element");
    return AVERROR_PATCHWELCOME;
}
示例#26
0
static int read_header(AVFormatContext *s)
{
    BRSTMDemuxContext *b = s->priv_data;
    int bom, major, minor, codec, chunk;
    int64_t pos, h1offset, toffset;
    uint32_t size, start, asize;
    AVStream *st;
    int ret = AVERROR_EOF;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    avio_skip(s->pb, 4);

    bom = avio_rb16(s->pb);
    if (bom != 0xFEFF && bom != 0xFFFE) {
        av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom);
        return AVERROR_INVALIDDATA;
    }
    if (bom == 0xFFFE) {
        av_log_ask_for_sample(s, "unsupported byte order");
        return AVERROR_PATCHWELCOME;
    }

    major = avio_r8(s->pb);
    minor = avio_r8(s->pb);
    avio_skip(s->pb, 4); // size of file
    size = avio_rb16(s->pb);
    if (size < 14)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, size - 14);
    pos = avio_tell(s->pb);
    if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
        return AVERROR_INVALIDDATA;
    size = avio_rb32(s->pb);
    if (size < 256)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 4); // unknown
    h1offset = avio_rb32(s->pb);
    if (h1offset > size)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 12);
    toffset = avio_rb32(s->pb) + 16LL;
    if (toffset > size)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb));
    codec = avio_r8(s->pb);

    switch (codec) {
    case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR;    break;
    case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break;
    case 2: codec = AV_CODEC_ID_ADPCM_THP;        break;
    default:
        av_log_ask_for_sample(s, "unsupported codec: %d", codec);
        return AVERROR_PATCHWELCOME;
    }

    avio_skip(s->pb, 1); // loop flag
    st->codec->codec_id = codec;
    st->codec->channels = avio_r8(s->pb);
    if (!st->codec->channels)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, 1); // padding
    st->codec->sample_rate = avio_rb16(s->pb);
    if (!st->codec->sample_rate)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, 2); // padding
    avio_skip(s->pb, 4); // loop start sample
    st->start_time = 0;
    st->duration = avio_rb32(s->pb);
    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    start = avio_rb32(s->pb);
    b->current_block = 0;
    b->block_count = avio_rb32(s->pb);
    if (b->block_count > UINT16_MAX) {
        av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count);
        return AVERROR_INVALIDDATA;
    }

    b->block_size = avio_rb32(s->pb);
    if (b->block_size > UINT16_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    b->block_size *= st->codec->channels;

    b->samples_per_block = avio_rb32(s->pb);
    b->last_block_used_bytes = avio_rb32(s->pb);
    if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    b->last_block_used_bytes *= st->codec->channels;

    avio_skip(s->pb, 4); // last block samples
    avio_skip(s->pb, 4); // last block size

    if (codec == AV_CODEC_ID_ADPCM_THP) {
        int ch;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        toffset = avio_rb32(s->pb) + 16LL;
        if (toffset > size)
            return AVERROR_INVALIDDATA;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        b->table = av_mallocz(32 * st->codec->channels);
        if (!b->table)
            return AVERROR(ENOMEM);

        for (ch = 0; ch < st->codec->channels; ch++) {
            if (avio_read(s->pb, b->table + ch * 32, 32) != 32) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, 24);
        }
    }

    if (size < (avio_tell(s->pb) - pos)) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }
    avio_skip(s->pb, size - (avio_tell(s->pb) - pos));

    while (!url_feof(s->pb)) {
        chunk = avio_rl32(s->pb);
        size  = avio_rb32(s->pb);
        if (size < 8) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
        size -= 8;
        switch (chunk) {
        case MKTAG('A','D','P','C'):
            if (codec != AV_CODEC_ID_ADPCM_THP)
                goto skip;

            asize = b->block_count * st->codec->channels * 4;
            if (size < asize) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            if (b->adpc) {
                av_log(s, AV_LOG_WARNING, "skipping additonal ADPC chunk\n");
                goto skip;
            } else {
                b->adpc = av_mallocz(asize);
                if (!b->adpc) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                avio_read(s->pb, b->adpc, asize);
                avio_skip(s->pb, size - asize);
            }
            break;
        case MKTAG('D','A','T','A'):
            if ((start < avio_tell(s->pb)) ||
                (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, start - avio_tell(s->pb));
            return 0;
        default:
            av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk);
skip:
            avio_skip(s->pb, size);
        }
    }

fail:
    read_close(s);

    return ret;
}
示例#27
0
static int iff_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    IffDemuxContext *iff = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    uint32_t chunk_id, data_size;
    int compression = -1;

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

    st->codec->channels = 1;
    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);
                compression        = avio_r8(pb);
            }
            break;

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

        case ID_CHAN:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2;
            break;

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

        case ID_BMHD:
            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 >= 11) {
                avio_skip(pb, 1); // masking
                compression                  = avio_r8(pb);
            }
            if (data_size >= 16) {
                avio_skip(pb, 3); // paddding, transparent
                st->sample_aspect_ratio.num  = avio_r8(pb);
                st->sample_aspect_ratio.den  = avio_r8(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!", 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:
        av_set_pts_info(st, 32, 1, st->codec->sample_rate);

        switch(compression) {
        case COMP_NONE:
            st->codec->codec_id = CODEC_ID_PCM_S8;
            break;
        case COMP_FIB:
            st->codec->codec_id = CODEC_ID_8SVX_FIB;
            break;
        case COMP_EXP:
            st->codec->codec_id = CODEC_ID_8SVX_EXP;
            break;
        default:
            av_log(s, AV_LOG_ERROR, "unknown compression method\n");
            return -1;
        }

        st->codec->bits_per_coded_sample = 8;
        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:
        switch (compression) {
        case BITMAP_RAW:
            st->codec->codec_id = CODEC_ID_IFF_ILBM;
            break;
        case BITMAP_BYTERUN1:
            st->codec->codec_id = CODEC_ID_IFF_BYTERUN1;
            break;
        default:
            av_log(s, AV_LOG_ERROR, "unknown compression method\n");
            return AVERROR_INVALIDDATA;
        }
        break;
    default:
        return -1;
    }

    return 0;
}
示例#28
0
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 > INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
        av_log(s, AV_LOG_ERROR, "APE tag size too large.\n");
        return AVERROR_INVALIDDATA;
    }
    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_get_extradata(st->codec, s->pb, size) < 0)
                return AVERROR(ENOMEM);
            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;
}
示例#29
0
文件: rmdec.c 项目: BlackOmega/FFmpeg
static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){
    RMDemuxContext *rm = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    uint32_t state=0xFFFFFFFF;

    while(!avio_feof(pb)){
        int len, num, i;
        *pos= avio_tell(pb) - 3;
        if(rm->remaining_len > 0){
            num= rm->current_stream;
            len= rm->remaining_len;
            *timestamp = AV_NOPTS_VALUE;
            *flags= 0;
        }else{
            state= (state<<8) + avio_r8(pb);

            if(state == MKBETAG('I', 'N', 'D', 'X')){
                int n_pkts, expected_len;
                len = avio_rb32(pb);
                avio_skip(pb, 2);
                n_pkts = avio_rb32(pb);
                expected_len = 20 + n_pkts * 14;
                if (len == 20)
                    /* some files don't add index entries to chunk size... */
                    len = expected_len;
                else if (len != expected_len)
                    av_log(s, AV_LOG_WARNING,
                           "Index size %d (%d pkts) is wrong, should be %d.\n",
                           len, n_pkts, expected_len);
                len -= 14; // we already read part of the index header
                if(len<0)
                    continue;
                goto skip;
            } else if (state == MKBETAG('D','A','T','A')) {
                av_log(s, AV_LOG_WARNING,
                       "DATA tag in middle of chunk, file may be broken.\n");
            }

            if(state > (unsigned)0xFFFF || state <= 12)
                continue;
            len=state - 12;
            state= 0xFFFFFFFF;

            num = avio_rb16(pb);
            *timestamp = avio_rb32(pb);
            avio_r8(pb); /* reserved */
            *flags = avio_r8(pb); /* flags */
        }
        for(i=0;i<s->nb_streams;i++) {
            st = s->streams[i];
            if (num == st->id)
                break;
        }
        if (i == s->nb_streams) {
skip:
            /* skip packet if unknown number */
            avio_skip(pb, len);
            rm->remaining_len = 0;
            continue;
        }
        *stream_index= i;

        return len;
    }
    return -1;
}
示例#30
0
static int read_header(AVFormatContext *s)
{
    MviDemuxContext *mvi = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *ast, *vst;
    unsigned int version, frames_count, msecs_per_frame, player_version;

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

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

    if (ff_alloc_extradata(vst->codec, 2))
        return AVERROR(ENOMEM);

    version                  = avio_r8(pb);
    vst->codec->extradata[0] = avio_r8(pb);
    vst->codec->extradata[1] = avio_r8(pb);
    frames_count             = avio_rl32(pb);
    msecs_per_frame          = avio_rl32(pb);
    vst->codec->width        = avio_rl16(pb);
    vst->codec->height       = avio_rl16(pb);
    avio_r8(pb);
    ast->codec->sample_rate  = avio_rl16(pb);
    mvi->audio_data_size     = avio_rl32(pb);
    avio_r8(pb);
    player_version           = avio_rl32(pb);
    avio_rl16(pb);
    avio_r8(pb);

    if (frames_count == 0 || mvi->audio_data_size == 0)
        return AVERROR_INVALIDDATA;

    if (version != 7 || player_version > 213) {
        av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version);
        return AVERROR_INVALIDDATA;
    }

    avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
    ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
    ast->codec->codec_id        = AV_CODEC_ID_PCM_U8;
    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 * 8;

    avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000);
    vst->avg_frame_rate    = av_inv_q(vst->time_base);
    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_id   = AV_CODEC_ID_MOTIONPIXELS;

    mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24;

    mvi->audio_frame_size   = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count;
    if (mvi->audio_frame_size <= 1 << MVI_FRAC_BITS - 1) {
        av_log(s, AV_LOG_ERROR,
               "Invalid audio_data_size (%"PRIu32") or frames_count (%u)\n",
               mvi->audio_data_size, frames_count);
        return AVERROR_INVALIDDATA;
    }

    mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size;
    mvi->audio_size_left    = mvi->audio_data_size;

    return 0;
}