- if (codec->codec_id == CODEC_ID_AAC) {
- /* Looking for a known attribute */
- for (i = 0; attr_names[i].str; ++i) {
- if (!strcasecmp(attr, attr_names[i].str)) {
- if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
- *(int *)((char *)rtp_payload_data +
- attr_names[i].offset) = atoi(value);
- } else if (attr_names[i].type == ATTR_NAME_TYPE_STR)
- *(char **)((char *)rtp_payload_data +
- attr_names[i].offset) = av_strdup(value);
- }
- }
+ if (len < data->au_headers_length_bytes)
+ return AVERROR_INVALIDDATA;
+
+ init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
+
+ /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
+ au_header_size = data->sizelength + data->indexlength;
+ if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
+ return -1;
+
+ data->nb_au_headers = au_headers_length / au_header_size;
+ if (!data->au_headers || data->au_headers_allocated < data->nb_au_headers) {
+ av_free(data->au_headers);
+ data->au_headers = av_malloc(sizeof(struct AUHeaders) * data->nb_au_headers);
+ if (!data->au_headers)
+ return AVERROR(ENOMEM);
+ data->au_headers_allocated = data->nb_au_headers;
+ }
+
+ for (i = 0; i < data->nb_au_headers; ++i) {
+ data->au_headers[i].size = get_bits_long(&getbitcontext, data->sizelength);
+ data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength);
+ }
+
+ return 0;
+}
+
+
+/* Follows RFC 3640 */
+static int aac_parse_packet(AVFormatContext *ctx, PayloadContext *data,
+ AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+ const uint8_t *buf, int len, uint16_t seq,
+ int flags)
+{
+ int ret;
+
+ if (!buf) {
+ if (data->cur_au_index > data->nb_au_headers) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid parser state\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (data->buf_size - data->buf_pos < data->au_headers[data->cur_au_index].size) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid AU size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if ((ret = av_new_packet(pkt, data->au_headers[data->cur_au_index].size)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Out of memory\n");
+ return ret;
+ }
+ memcpy(pkt->data, &data->buf[data->buf_pos], data->au_headers[data->cur_au_index].size);
+ data->buf_pos += data->au_headers[data->cur_au_index].size;
+ pkt->stream_index = st->index;
+ data->cur_au_index++;
+
+ if (data->cur_au_index == data->nb_au_headers) {
+ data->buf_pos = 0;
+ return 0;
+ }
+
+ return 1;
+ }
+
+ if (rtp_parse_mp4_au(data, buf, len)) {
+ av_log(ctx, AV_LOG_ERROR, "Error parsing AU headers\n");
+ return -1;
+ }
+
+ buf += data->au_headers_length_bytes + 2;
+ len -= data->au_headers_length_bytes + 2;
+ if (data->nb_au_headers == 1 && len < data->au_headers[0].size) {
+ /* Packet is fragmented */
+
+ if (!data->buf_pos) {
+ if (data->au_headers[0].size > MAX_AAC_HBR_FRAME_SIZE) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid AU size\n");
+ return AVERROR_INVALIDDATA;