112
static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
116
static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len)
114
118
int au_headers_length, au_header_size, i;
115
119
GetBitContext getbitcontext;
122
return AVERROR_INVALIDDATA;
117
124
/* decode the first 2 bytes where the AUHeader sections are stored
118
125
length in bits */
119
126
au_headers_length = AV_RB16(buf);
126
133
/* skip AU headers length section (2 bytes) */
137
if (len < data->au_headers_length_bytes)
138
return AVERROR_INVALIDDATA;
129
140
init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
137
148
if (!data->au_headers || data->au_headers_allocated < data->nb_au_headers) {
138
149
av_free(data->au_headers);
139
150
data->au_headers = av_malloc(sizeof(struct AUHeaders) * data->nb_au_headers);
151
if (!data->au_headers)
152
return AVERROR(ENOMEM);
140
153
data->au_headers_allocated = data->nb_au_headers;
143
/* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
144
In my test, the FAAD decoder does not behave correctly when sending each AU one by one
145
but does when sending the whole as one big packet... */
146
data->au_headers[0].size = 0;
147
data->au_headers[0].index = 0;
148
156
for (i = 0; i < data->nb_au_headers; ++i) {
149
data->au_headers[0].size += get_bits_long(&getbitcontext, data->sizelength);
150
data->au_headers[0].index = get_bits_long(&getbitcontext, data->indexlength);
157
data->au_headers[i].size = get_bits_long(&getbitcontext, data->sizelength);
158
data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength);
153
data->nb_au_headers = 1;
162
168
const uint8_t *buf, int len, uint16_t seq,
165
if (rtp_parse_mp4_au(data, buf))
174
if (data->cur_au_index > data->nb_au_headers)
175
return AVERROR_INVALIDDATA;
176
if (data->buf_size - data->buf_pos < data->au_headers[data->cur_au_index].size)
177
return AVERROR_INVALIDDATA;
178
if ((ret = av_new_packet(pkt, data->au_headers[data->cur_au_index].size)) < 0)
180
memcpy(pkt->data, &data->buf[data->buf_pos], data->au_headers[data->cur_au_index].size);
181
data->buf_pos += data->au_headers[data->cur_au_index].size;
182
pkt->stream_index = st->index;
183
data->cur_au_index++;
184
return data->cur_au_index < data->nb_au_headers;
187
if (rtp_parse_mp4_au(data, buf, len))
168
190
buf += data->au_headers_length_bytes + 2;
169
191
len -= data->au_headers_length_bytes + 2;
171
/* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
173
av_new_packet(pkt, data->au_headers[0].size);
193
if (len < data->au_headers[0].size)
194
return AVERROR_INVALIDDATA;
195
if ((ret = av_new_packet(pkt, data->au_headers[0].size)) < 0)
174
197
memcpy(pkt->data, buf, data->au_headers[0].size);
198
len -= data->au_headers[0].size;
199
buf += data->au_headers[0].size;
176
200
pkt->stream_index = st->index;
202
if (len > 0 && data->nb_au_headers > 1) {
203
data->buf_size = FFMIN(len, sizeof(data->buf));
204
memcpy(data->buf, buf, data->buf_size);
205
data->cur_au_index = 1;
256
static av_cold int init_video(AVFormatContext *s, int st_index,
257
PayloadContext *data)
261
s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
223
265
RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = {
224
266
.enc_name = "MP4V-ES",
225
267
.codec_type = AVMEDIA_TYPE_VIDEO,
226
268
.codec_id = AV_CODEC_ID_MPEG4,
227
270
.parse_sdp_a_line = parse_sdp_line,