示例#1
0
文件: qcp.c 项目: AleXoundOS/FFmpeg
static int qcp_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    QCPContext    *c  = s->priv_data;
    AVStream      *st = avformat_new_stream(s, NULL);
    uint8_t       buf[16];
    int           i, nb_rates;

    if (!st)
        return AVERROR(ENOMEM);

    avio_rb32(pb);                    // "RIFF"
    avio_skip(pb, 4 + 8 + 4 + 1 + 1);    // filesize + "QLCMfmt " + chunk-size + major-version + minor-version

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->channels   = 1;
    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
    avio_read(pb, buf, 16);
    if (is_qcelp_13k_guid(buf)) {
        st->codec->codec_id = AV_CODEC_ID_QCELP;
    } else if (!memcmp(buf, guid_evrc, 16)) {
        st->codec->codec_id = AV_CODEC_ID_EVRC;
    } else if (!memcmp(buf, guid_smv, 16)) {
        st->codec->codec_id = AV_CODEC_ID_SMV;
    } else if (!memcmp(buf, guid_4gv, 16)) {
        st->codec->codec_id = AV_CODEC_ID_4GV;
    } else {
        av_log(s, AV_LOG_ERROR, "Unknown codec GUID "FF_PRI_GUID".\n",
               FF_ARG_GUID(buf));
        return AVERROR_INVALIDDATA;
    }
    avio_skip(pb, 2 + 80); // codec-version + codec-name
    st->codec->bit_rate = avio_rl16(pb);

    s->packet_size = avio_rl16(pb);
    avio_skip(pb, 2); // block-size
    st->codec->sample_rate = avio_rl16(pb);
    avio_skip(pb, 2); // sample-size

    memset(c->rates_per_mode, -1, sizeof(c->rates_per_mode));
    nb_rates = avio_rl32(pb);
    nb_rates = FFMIN(nb_rates, 8);
    for (i=0; i<nb_rates; i++) {
        int size = avio_r8(pb);
        int mode = avio_r8(pb);
        if (mode > QCP_MAX_MODE) {
            av_log(s, AV_LOG_WARNING, "Unknown entry %d=>%d in rate-map-table.\n ", mode, size);
        } else
            c->rates_per_mode[mode] = size;
    }
    avio_skip(pb, 16 - 2*nb_rates + 20); // empty entries of rate-map-table + reserved

    return 0;
}
示例#2
0
static int qcp_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    ByteIOContext *pb = s->pb;
    QCPContext    *c  = s->priv_data;
    AVStream      *st = av_new_stream(s, 0);
    uint8_t       buf[16];
    int           i, nb_rates;

    if (!st)
        return AVERROR(ENOMEM);

    get_be32(pb);                    // "RIFF"
    s->file_size = get_le32(pb) + 8;
    url_fskip(pb, 8 + 4 + 1 + 1);    // "QLCMfmt " + chunk-size + major-version + minor-version

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->channels   = 1;
    get_buffer(pb, buf, 16);
    if (is_qcelp_13k_guid(buf)) {
        st->codec->codec_id = CODEC_ID_QCELP;
    } else if (!memcmp(buf, guid_evrc, 16)) {
        av_log(s, AV_LOG_ERROR, "EVRC codec is not supported.\n");
        return AVERROR_PATCHWELCOME;
    } else if (!memcmp(buf, guid_smv, 16)) {
        av_log(s, AV_LOG_ERROR, "SMV codec is not supported.\n");
        return AVERROR_PATCHWELCOME;
    } else {
        av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n");
        return AVERROR_INVALIDDATA;
    }
    url_fskip(pb, 2 + 80); // codec-version + codec-name
    st->codec->bit_rate = get_le16(pb);

    s->packet_size = get_le16(pb);
    url_fskip(pb, 2); // block-size
    st->codec->sample_rate = get_le16(pb);
    url_fskip(pb, 2); // sample-size

    memset(c->rates_per_mode, -1, sizeof(c->rates_per_mode));
    nb_rates = get_le32(pb);
    nb_rates = FFMIN(nb_rates, 8);
    for (i=0; i<nb_rates; i++) {
        int size = get_byte(pb);
        int mode = get_byte(pb);
        if (mode > QCP_MAX_MODE) {
            av_log(s, AV_LOG_WARNING, "Unknown entry %d=>%d in rate-map-table.\n ", mode, size);
        } else
            c->rates_per_mode[mode] = size;
    }
    url_fskip(pb, 16 - 2*nb_rates + 20); // empty entries of rate-map-table + reserved

    return 0;
}