* Based off parse_packed_headers in Vorbis RTP */
| 222 | * Based off parse_packed_headers in Vorbis RTP |
| 223 | */ |
| 224 | static int |
| 225 | parse_packed_headers(AVFormatContext *s, |
| 226 | const uint8_t * packed_headers, |
| 227 | const uint8_t * packed_headers_end, |
| 228 | AVCodecParameters *par, PayloadContext * xiph_data) |
| 229 | { |
| 230 | |
| 231 | unsigned num_packed, num_headers, length, length1, length2, extradata_alloc; |
| 232 | int ret; |
| 233 | uint8_t *ptr; |
| 234 | |
| 235 | if (packed_headers_end - packed_headers < 9) { |
| 236 | av_log(s, AV_LOG_ERROR, |
| 237 | "Invalid %td byte packed header.", |
| 238 | packed_headers_end - packed_headers); |
| 239 | return AVERROR_INVALIDDATA; |
| 240 | } |
| 241 | |
| 242 | num_packed = bytestream_get_be32(&packed_headers); |
| 243 | xiph_data->ident = bytestream_get_be24(&packed_headers); |
| 244 | length = bytestream_get_be16(&packed_headers); |
| 245 | num_headers = get_base128(&packed_headers, packed_headers_end); |
| 246 | length1 = get_base128(&packed_headers, packed_headers_end); |
| 247 | length2 = get_base128(&packed_headers, packed_headers_end); |
| 248 | |
| 249 | if (num_packed != 1 || num_headers > 3) { |
| 250 | avpriv_report_missing_feature(s, "%u packed headers, %u headers", |
| 251 | num_packed, num_headers); |
| 252 | return AVERROR_PATCHWELCOME; |
| 253 | } |
| 254 | |
| 255 | if (packed_headers_end - packed_headers != length || |
| 256 | length1 > length || length2 > length - length1) { |
| 257 | av_log(s, AV_LOG_ERROR, |
| 258 | "Bad packed header lengths (%d,%d,%td,%u)\n", length1, |
| 259 | length2, packed_headers_end - packed_headers, length); |
| 260 | return AVERROR_INVALIDDATA; |
| 261 | } |
| 262 | |
| 263 | /* allocate extra space: |
| 264 | * -- length/255 +2 for xiphlacing |
| 265 | * -- one for the '2' marker |
| 266 | * -- AV_INPUT_BUFFER_PADDING_SIZE required */ |
| 267 | extradata_alloc = length + length/255 + 3 + AV_INPUT_BUFFER_PADDING_SIZE; |
| 268 | |
| 269 | if ((ret = ff_alloc_extradata(par, extradata_alloc)) < 0) { |
| 270 | av_log(s, AV_LOG_ERROR, "Out of memory\n"); |
| 271 | return ret; |
| 272 | } |
| 273 | ptr = par->extradata; |
| 274 | *ptr++ = 2; |
| 275 | ptr += av_xiphlacing(ptr, length1); |
| 276 | ptr += av_xiphlacing(ptr, length2); |
| 277 | memcpy(ptr, packed_headers, length); |
| 278 | ptr += length; |
| 279 | par->extradata_size = ptr - par->extradata; |
| 280 | // clear out remaining parts of the buffer |
| 281 | memset(ptr, 0, extradata_alloc - par->extradata_size); |
no test coverage detected