/* There are (invalid) samples in the wild with mp4-style extradata, where the * parameter sets are stored unescaped (i.e. as RBSP). * This function catches the parameter set decoding failure and tries again * after escaping it */ static int decode_extradata_ps_mp4(const uint8_t *buf, int buf_size, H264ParamSets *ps, int err_recognition, void *logctx) { int ret; ret = decode_extradata_ps(buf, buf_size, ps, 1, logctx); if (ret < 0 && !(err_recognition & AV_EF_EXPLODE)) { GetByteContext gbc; PutByteContext pbc; uint8_t *escaped_buf; int escaped_buf_size; av_log(logctx, AV_LOG_WARNING, "SPS decoding failure, trying again after escaping the NAL\n"); if (buf_size / 2 >= (INT16_MAX - AV_INPUT_BUFFER_PADDING_SIZE) / 3) return AVERROR(ERANGE); escaped_buf_size = buf_size * 3 / 2 + AV_INPUT_BUFFER_PADDING_SIZE; escaped_buf = av_mallocz(escaped_buf_size); if (!escaped_buf) return AVERROR(ENOMEM); bytestream2_init(&gbc, buf, buf_size); bytestream2_init_writer(&pbc, escaped_buf, escaped_buf_size); while (bytestream2_get_bytes_left(&gbc)) { if (bytestream2_get_bytes_left(&gbc) >= 3 && bytestream2_peek_be24(&gbc) <= 3) { bytestream2_put_be24(&pbc, 3); bytestream2_skip(&gbc, 2); } else bytestream2_put_byte(&pbc, bytestream2_get_byte(&gbc)); } escaped_buf_size = bytestream2_tell_p(&pbc); AV_WB16(escaped_buf, escaped_buf_size - 2); ret = decode_extradata_ps(escaped_buf, escaped_buf_size, ps, 1, logctx); av_freep(&escaped_buf); if (ret < 0) return ret; } return 0; }
static uint8_t* ffat_get_magic_cookie(AVCodecContext *avctx, UInt32 *cookie_size) { ATDecodeContext *at = avctx->priv_data; if (avctx->codec_id == AV_CODEC_ID_AAC) { char *extradata; PutByteContext pb; *cookie_size = 5 + 3 + 5+13 + 5+at->extradata_size; if (!(extradata = av_malloc(*cookie_size))) return NULL; bytestream2_init_writer(&pb, extradata, *cookie_size); // ES descriptor put_descr(&pb, 0x03, 3 + 5+13 + 5+at->extradata_size); bytestream2_put_be16(&pb, 0); bytestream2_put_byte(&pb, 0x00); // flags (= no flags) // DecoderConfig descriptor put_descr(&pb, 0x04, 13 + 5+at->extradata_size); // Object type indication bytestream2_put_byte(&pb, 0x40); bytestream2_put_byte(&pb, 0x15); // flags (= Audiostream) bytestream2_put_be24(&pb, 0); // Buffersize DB bytestream2_put_be32(&pb, 0); // maxbitrate bytestream2_put_be32(&pb, 0); // avgbitrate // DecoderSpecific info descriptor put_descr(&pb, 0x05, at->extradata_size); bytestream2_put_buffer(&pb, at->extradata, at->extradata_size); return extradata; } else { *cookie_size = at->extradata_size; return at->extradata; } }