Libav 0.7.1
|
00001 /* 00002 * RTP H264 Protocol (RFC3984) 00003 * Copyright (c) 2006 Ryan Martell 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00039 #include "libavutil/base64.h" 00040 #include "libavutil/avstring.h" 00041 #include "libavcodec/get_bits.h" 00042 #include "avformat.h" 00043 #include "mpegts.h" 00044 00045 #include <unistd.h> 00046 #include "network.h" 00047 #include <assert.h> 00048 00049 #include "rtpdec.h" 00050 #include "rtpdec_formats.h" 00051 00055 struct PayloadContext { 00056 unsigned long cookie; 00057 00058 //sdp setup parameters 00059 uint8_t profile_idc; 00060 uint8_t profile_iop; 00061 uint8_t level_idc; 00062 int packetization_mode; 00063 #ifdef DEBUG 00064 int packet_types_received[32]; 00065 #endif 00066 }; 00067 00068 #define MAGIC_COOKIE (0xdeadbeef) ///< Cookie for the extradata; to verify we are what we think we are, and that we haven't been freed. 00069 #define DEAD_COOKIE (0xdeaddead) ///< Cookie for the extradata; once it is freed. 00070 00071 /* ---------------- private code */ 00072 static int sdp_parse_fmtp_config_h264(AVStream * stream, 00073 PayloadContext * h264_data, 00074 char *attr, char *value) 00075 { 00076 AVCodecContext *codec = stream->codec; 00077 assert(codec->codec_id == CODEC_ID_H264); 00078 assert(h264_data != NULL); 00079 00080 if (!strcmp(attr, "packetization-mode")) { 00081 av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value)); 00082 h264_data->packetization_mode = atoi(value); 00083 /* 00084 Packetization Mode: 00085 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) 00086 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. 00087 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed. 00088 */ 00089 if (h264_data->packetization_mode > 1) 00090 av_log(codec, AV_LOG_ERROR, 00091 "Interleaved RTP mode is not supported yet."); 00092 } else if (!strcmp(attr, "profile-level-id")) { 00093 if (strlen(value) == 6) { 00094 char buffer[3]; 00095 // 6 characters=3 bytes, in hex. 00096 uint8_t profile_idc; 00097 uint8_t profile_iop; 00098 uint8_t level_idc; 00099 00100 buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0'; 00101 profile_idc = strtol(buffer, NULL, 16); 00102 buffer[0] = value[2]; buffer[1] = value[3]; 00103 profile_iop = strtol(buffer, NULL, 16); 00104 buffer[0] = value[4]; buffer[1] = value[5]; 00105 level_idc = strtol(buffer, NULL, 16); 00106 00107 // set the parameters... 00108 av_log(codec, AV_LOG_DEBUG, 00109 "RTP Profile IDC: %x Profile IOP: %x Level: %x\n", 00110 profile_idc, profile_iop, level_idc); 00111 h264_data->profile_idc = profile_idc; 00112 h264_data->profile_iop = profile_iop; 00113 h264_data->level_idc = level_idc; 00114 } 00115 } else if (!strcmp(attr, "sprop-parameter-sets")) { 00116 uint8_t start_sequence[]= { 0, 0, 1 }; 00117 codec->extradata_size= 0; 00118 codec->extradata= NULL; 00119 00120 while (*value) { 00121 char base64packet[1024]; 00122 uint8_t decoded_packet[1024]; 00123 int packet_size; 00124 char *dst = base64packet; 00125 00126 while (*value && *value != ',' 00127 && (dst - base64packet) < sizeof(base64packet) - 1) { 00128 *dst++ = *value++; 00129 } 00130 *dst++ = '\0'; 00131 00132 if (*value == ',') 00133 value++; 00134 00135 packet_size= av_base64_decode(decoded_packet, base64packet, sizeof(decoded_packet)); 00136 if (packet_size > 0) { 00137 uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) + 00138 codec->extradata_size + 00139 FF_INPUT_BUFFER_PADDING_SIZE); 00140 if(dest) 00141 { 00142 if(codec->extradata_size) 00143 { 00144 // av_realloc? 00145 memcpy(dest, codec->extradata, codec->extradata_size); 00146 av_free(codec->extradata); 00147 } 00148 00149 memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence)); 00150 memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); 00151 memset(dest+codec->extradata_size+sizeof(start_sequence)+ 00152 packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); 00153 00154 codec->extradata= dest; 00155 codec->extradata_size+= sizeof(start_sequence)+packet_size; 00156 } else { 00157 av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); 00158 return AVERROR(ENOMEM); 00159 } 00160 } 00161 } 00162 av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", codec->extradata, codec->extradata_size); 00163 } 00164 return 0; 00165 } 00166 00167 // return 0 on packet, no more left, 1 on packet, 1 on partial packet... 00168 static int h264_handle_packet(AVFormatContext *ctx, 00169 PayloadContext *data, 00170 AVStream *st, 00171 AVPacket * pkt, 00172 uint32_t * timestamp, 00173 const uint8_t * buf, 00174 int len, int flags) 00175 { 00176 uint8_t nal = buf[0]; 00177 uint8_t type = (nal & 0x1f); 00178 int result= 0; 00179 uint8_t start_sequence[]= {0, 0, 1}; 00180 00181 #ifdef DEBUG 00182 assert(data); 00183 assert(data->cookie == MAGIC_COOKIE); 00184 #endif 00185 assert(buf); 00186 00187 if (type >= 1 && type <= 23) 00188 type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec) 00189 switch (type) { 00190 case 0: // undefined, but pass them through 00191 case 1: 00192 av_new_packet(pkt, len+sizeof(start_sequence)); 00193 memcpy(pkt->data, start_sequence, sizeof(start_sequence)); 00194 memcpy(pkt->data+sizeof(start_sequence), buf, len); 00195 #ifdef DEBUG 00196 data->packet_types_received[nal & 0x1f]++; 00197 #endif 00198 break; 00199 00200 case 24: // STAP-A (one packet, multiple nals) 00201 // consume the STAP-A NAL 00202 buf++; 00203 len--; 00204 // first we are going to figure out the total size.... 00205 { 00206 int pass= 0; 00207 int total_length= 0; 00208 uint8_t *dst= NULL; 00209 00210 for(pass= 0; pass<2; pass++) { 00211 const uint8_t *src= buf; 00212 int src_len= len; 00213 00214 do { 00215 uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?) 00216 00217 // consume the length of the aggregate... 00218 src += 2; 00219 src_len -= 2; 00220 00221 if (nal_size <= src_len) { 00222 if(pass==0) { 00223 // counting... 00224 total_length+= sizeof(start_sequence)+nal_size; 00225 } else { 00226 // copying 00227 assert(dst); 00228 memcpy(dst, start_sequence, sizeof(start_sequence)); 00229 dst+= sizeof(start_sequence); 00230 memcpy(dst, src, nal_size); 00231 #ifdef DEBUG 00232 data->packet_types_received[*src & 0x1f]++; 00233 #endif 00234 dst+= nal_size; 00235 } 00236 } else { 00237 av_log(ctx, AV_LOG_ERROR, 00238 "nal size exceeds length: %d %d\n", nal_size, src_len); 00239 } 00240 00241 // eat what we handled... 00242 src += nal_size; 00243 src_len -= nal_size; 00244 00245 if (src_len < 0) 00246 av_log(ctx, AV_LOG_ERROR, 00247 "Consumed more bytes than we got! (%d)\n", src_len); 00248 } while (src_len > 2); // because there could be rtp padding.. 00249 00250 if(pass==0) { 00251 // now we know the total size of the packet (with the start sequences added) 00252 av_new_packet(pkt, total_length); 00253 dst= pkt->data; 00254 } else { 00255 assert(dst-pkt->data==total_length); 00256 } 00257 } 00258 } 00259 break; 00260 00261 case 25: // STAP-B 00262 case 26: // MTAP-16 00263 case 27: // MTAP-24 00264 case 29: // FU-B 00265 av_log(ctx, AV_LOG_ERROR, 00266 "Unhandled type (%d) (See RFC for implementation details\n", 00267 type); 00268 result= -1; 00269 break; 00270 00271 case 28: // FU-A (fragmented nal) 00272 buf++; 00273 len--; // skip the fu_indicator 00274 { 00275 // these are the same as above, we just redo them here for clarity... 00276 uint8_t fu_indicator = nal; 00277 uint8_t fu_header = *buf; // read the fu_header. 00278 uint8_t start_bit = fu_header >> 7; 00279 // uint8_t end_bit = (fu_header & 0x40) >> 6; 00280 uint8_t nal_type = (fu_header & 0x1f); 00281 uint8_t reconstructed_nal; 00282 00283 // reconstruct this packet's true nal; only the data follows.. 00284 reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal; 00285 reconstructed_nal |= nal_type; 00286 00287 // skip the fu_header... 00288 buf++; 00289 len--; 00290 00291 #ifdef DEBUG 00292 if (start_bit) 00293 data->packet_types_received[nal_type]++; 00294 #endif 00295 if(start_bit) { 00296 // copy in the start sequence, and the reconstructed nal.... 00297 av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len); 00298 memcpy(pkt->data, start_sequence, sizeof(start_sequence)); 00299 pkt->data[sizeof(start_sequence)]= reconstructed_nal; 00300 memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len); 00301 } else { 00302 av_new_packet(pkt, len); 00303 memcpy(pkt->data, buf, len); 00304 } 00305 } 00306 break; 00307 00308 case 30: // undefined 00309 case 31: // undefined 00310 default: 00311 av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type); 00312 result= -1; 00313 break; 00314 } 00315 00316 pkt->stream_index = st->index; 00317 00318 return result; 00319 } 00320 00321 /* ---------------- public code */ 00322 static PayloadContext *h264_new_context(void) 00323 { 00324 PayloadContext *data = 00325 av_mallocz(sizeof(PayloadContext) + 00326 FF_INPUT_BUFFER_PADDING_SIZE); 00327 00328 if (data) { 00329 data->cookie = MAGIC_COOKIE; 00330 } 00331 00332 return data; 00333 } 00334 00335 static void h264_free_context(PayloadContext *data) 00336 { 00337 #ifdef DEBUG 00338 int ii; 00339 00340 for (ii = 0; ii < 32; ii++) { 00341 if (data->packet_types_received[ii]) 00342 av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n", 00343 data->packet_types_received[ii], ii); 00344 } 00345 #endif 00346 00347 assert(data); 00348 assert(data->cookie == MAGIC_COOKIE); 00349 00350 // avoid stale pointers (assert) 00351 data->cookie = DEAD_COOKIE; 00352 00353 // and clear out this... 00354 av_free(data); 00355 } 00356 00357 static int parse_h264_sdp_line(AVFormatContext *s, int st_index, 00358 PayloadContext *h264_data, const char *line) 00359 { 00360 AVStream *stream = s->streams[st_index]; 00361 AVCodecContext *codec = stream->codec; 00362 const char *p = line; 00363 00364 assert(h264_data->cookie == MAGIC_COOKIE); 00365 00366 if (av_strstart(p, "framesize:", &p)) { 00367 char buf1[50]; 00368 char *dst = buf1; 00369 00370 // remove the protocol identifier.. 00371 while (*p && *p == ' ') p++; // strip spaces. 00372 while (*p && *p != ' ') p++; // eat protocol identifier 00373 while (*p && *p == ' ') p++; // strip trailing spaces. 00374 while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) { 00375 *dst++ = *p++; 00376 } 00377 *dst = '\0'; 00378 00379 // a='framesize:96 320-240' 00380 // set our parameters.. 00381 codec->width = atoi(buf1); 00382 codec->height = atoi(p + 1); // skip the - 00383 codec->pix_fmt = PIX_FMT_YUV420P; 00384 } else if (av_strstart(p, "fmtp:", &p)) { 00385 return ff_parse_fmtp(stream, h264_data, p, sdp_parse_fmtp_config_h264); 00386 } else if (av_strstart(p, "cliprect:", &p)) { 00387 // could use this if we wanted. 00388 } 00389 00390 return 0; // keep processing it the normal way... 00391 } 00392 00396 RTPDynamicProtocolHandler ff_h264_dynamic_handler = { 00397 .enc_name = "H264", 00398 .codec_type = AVMEDIA_TYPE_VIDEO, 00399 .codec_id = CODEC_ID_H264, 00400 .parse_sdp_a_line = parse_h264_sdp_line, 00401 .alloc = h264_new_context, 00402 .free = h264_free_context, 00403 .parse_packet = h264_handle_packet 00404 };