Mercurial > libavformat.hg
comparison rtpdec_mpeg4.c @ 6178:7aca26f37b02 libavformat
rtpdec: Move AAC depacketization code in rtpdec to a proper payload handler
Patch by Josh Allmann, joshua dot allmann at gmail
author | mstorsjo |
---|---|
date | Fri, 25 Jun 2010 08:01:20 +0000 |
parents | 3a0c63aea9e9 |
children | 736165b749f8 |
comparison
equal
deleted
inserted
replaced
6177:3a0c63aea9e9 | 6178:7aca26f37b02 |
---|---|
28 */ | 28 */ |
29 | 29 |
30 #include "rtpdec_mpeg4.h" | 30 #include "rtpdec_mpeg4.h" |
31 #include "internal.h" | 31 #include "internal.h" |
32 #include "libavutil/avstring.h" | 32 #include "libavutil/avstring.h" |
33 #include "libavcodec/get_bits.h" | |
33 #include <strings.h> | 34 #include <strings.h> |
34 | 35 |
35 #include "rtsp.h" //XXX remove this dependency | 36 #include "rtsp.h" //XXX remove this dependency |
36 | 37 |
37 /* return the length and optionally the data */ | 38 /* return the length and optionally the data */ |
101 codec->extradata_size = len; | 102 codec->extradata_size = len; |
102 hex_to_data(codec->extradata, value); | 103 hex_to_data(codec->extradata, value); |
103 return 0; | 104 return 0; |
104 } | 105 } |
105 | 106 |
107 static int rtp_parse_mp4_au(RTSPStream *rtsp_st, const uint8_t *buf) | |
108 { | |
109 int au_headers_length, au_header_size, i; | |
110 GetBitContext getbitcontext; | |
111 RTPPayloadData *infos; | |
112 | |
113 infos = &rtsp_st->rtp_payload_data; | |
114 if (infos == NULL) | |
115 return -1; | |
116 | |
117 /* decode the first 2 bytes where the AUHeader sections are stored | |
118 length in bits */ | |
119 au_headers_length = AV_RB16(buf); | |
120 | |
121 if (au_headers_length > RTP_MAX_PACKET_LENGTH) | |
122 return -1; | |
123 | |
124 infos->au_headers_length_bytes = (au_headers_length + 7) / 8; | |
125 | |
126 /* skip AU headers length section (2 bytes) */ | |
127 buf += 2; | |
128 | |
129 init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8); | |
130 | |
131 /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */ | |
132 au_header_size = infos->sizelength + infos->indexlength; | |
133 if (au_header_size <= 0 || (au_headers_length % au_header_size != 0)) | |
134 return -1; | |
135 | |
136 infos->nb_au_headers = au_headers_length / au_header_size; | |
137 if (!infos->au_headers || infos->au_headers_allocated < infos->nb_au_headers) { | |
138 av_free(infos->au_headers); | |
139 infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers); | |
140 infos->au_headers_allocated = infos->nb_au_headers; | |
141 } | |
142 | |
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 infos->au_headers[0].size = 0; | |
147 infos->au_headers[0].index = 0; | |
148 for (i = 0; i < infos->nb_au_headers; ++i) { | |
149 infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength); | |
150 infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength); | |
151 } | |
152 | |
153 infos->nb_au_headers = 1; | |
154 | |
155 return 0; | |
156 } | |
157 | |
158 | |
159 /* Follows RFC 3640 */ | |
160 static int aac_parse_packet(AVFormatContext *ctx, | |
161 PayloadContext *data, | |
162 AVStream *st, | |
163 AVPacket *pkt, | |
164 uint32_t *timestamp, | |
165 const uint8_t *buf, int len, int flags) | |
166 { | |
167 RTSPStream *rtsp_st = st->priv_data; | |
168 RTPPayloadData *infos; | |
169 | |
170 if (rtp_parse_mp4_au(rtsp_st, buf)) | |
171 return -1; | |
172 | |
173 infos = &rtsp_st->rtp_payload_data; | |
174 if (infos == NULL) | |
175 return -1; | |
176 buf += infos->au_headers_length_bytes + 2; | |
177 len -= infos->au_headers_length_bytes + 2; | |
178 | |
179 /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define | |
180 one au_header */ | |
181 av_new_packet(pkt, infos->au_headers[0].size); | |
182 memcpy(pkt->data, buf, infos->au_headers[0].size); | |
183 | |
184 pkt->stream_index = st->index; | |
185 return 0; | |
186 } | |
187 | |
106 static int parse_sdp_line(AVFormatContext *s, int st_index, | 188 static int parse_sdp_line(AVFormatContext *s, int st_index, |
107 PayloadContext *data, const char *line) | 189 PayloadContext *data, const char *line) |
108 { | 190 { |
109 const char *p; | 191 const char *p; |
110 char value[4096], attr[25]; | 192 char value[4096], attr[25]; |
165 .codec_type = AVMEDIA_TYPE_AUDIO, | 247 .codec_type = AVMEDIA_TYPE_AUDIO, |
166 .codec_id = CODEC_ID_AAC, | 248 .codec_id = CODEC_ID_AAC, |
167 .parse_sdp_a_line = parse_sdp_line, | 249 .parse_sdp_a_line = parse_sdp_line, |
168 .open = NULL, | 250 .open = NULL, |
169 .close = NULL, | 251 .close = NULL, |
170 .parse_packet = NULL | 252 .parse_packet = aac_parse_packet |
171 }; | 253 }; |