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