Returns the number of sound data frames or negative on error */
| 93 | |
| 94 | /* Returns the number of sound data frames or negative on error */ |
| 95 | static int get_aiff_header(AVFormatContext *s, int64_t size, |
| 96 | unsigned version) |
| 97 | { |
| 98 | AVIOContext *pb = s->pb; |
| 99 | AVCodecParameters *par = s->streams[0]->codecpar; |
| 100 | AIFFInputContext *aiff = s->priv_data; |
| 101 | int exp; |
| 102 | uint64_t val; |
| 103 | int sample_rate; |
| 104 | unsigned int num_frames; |
| 105 | int channels; |
| 106 | |
| 107 | if (size & 1) |
| 108 | size++; |
| 109 | par->codec_type = AVMEDIA_TYPE_AUDIO; |
| 110 | channels = avio_rb16(pb); |
| 111 | if (par->ch_layout.nb_channels && par->ch_layout.nb_channels != channels) |
| 112 | return AVERROR_INVALIDDATA; |
| 113 | par->ch_layout.nb_channels = channels; |
| 114 | num_frames = avio_rb32(pb); |
| 115 | par->bits_per_coded_sample = avio_rb16(pb); |
| 116 | |
| 117 | exp = avio_rb16(pb) - 16383 - 63; |
| 118 | val = avio_rb64(pb); |
| 119 | if (exp <-63 || exp >63) { |
| 120 | av_log(s, AV_LOG_ERROR, "exp %d is out of range\n", exp); |
| 121 | return AVERROR_INVALIDDATA; |
| 122 | } |
| 123 | if (exp >= 0) |
| 124 | sample_rate = val << exp; |
| 125 | else |
| 126 | sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; |
| 127 | if (sample_rate <= 0) |
| 128 | return AVERROR_INVALIDDATA; |
| 129 | |
| 130 | par->sample_rate = sample_rate; |
| 131 | if (size < 18) |
| 132 | return AVERROR_INVALIDDATA; |
| 133 | size -= 18; |
| 134 | |
| 135 | /* get codec id for AIFF-C */ |
| 136 | if (size < 4) { |
| 137 | version = AIFF; |
| 138 | } else if (version == AIFF_C_VERSION1) { |
| 139 | par->codec_tag = avio_rl32(pb); |
| 140 | par->codec_id = ff_codec_get_id(ff_codec_aiff_tags, par->codec_tag); |
| 141 | if (par->codec_id == AV_CODEC_ID_NONE) |
| 142 | avpriv_request_sample(s, "unknown or unsupported codec tag: %s", |
| 143 | av_fourcc2str(par->codec_tag)); |
| 144 | size -= 4; |
| 145 | } |
| 146 | |
| 147 | if (version != AIFF_C_VERSION1 || par->codec_id == AV_CODEC_ID_PCM_S16BE) { |
| 148 | par->codec_id = aiff_codec_get_id(par->bits_per_coded_sample); |
| 149 | par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id); |
| 150 | aiff->block_duration = 1; |
| 151 | } else { |
| 152 | switch (par->codec_id) { |
no test coverage detected