1/* 2 * RTP H264 Protocol (RFC3984) 3 * Copyright (c) 2006 Ryan Martell 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * @brief H.264 / RTP Code (RFC3984) 25 * @author Ryan Martell <rdm4@martellventures.com> 26 * 27 * @note Notes: 28 * Notes: 29 * This currently supports packetization mode: 30 * Single Nal Unit Mode (0), or 31 * Non-Interleaved Mode (1). It currently does not support 32 * Interleaved Mode (2). (This requires implementing STAP-B, MTAP16, MTAP24, 33 * FU-B packet types) 34 */ 35 36#include "libavutil/attributes.h" 37#include "libavutil/base64.h" 38#include "libavutil/avstring.h" 39#include "libavcodec/get_bits.h" 40#include "avformat.h" 41 42#include "network.h" 43#include <assert.h> 44 45#include "rtpdec.h" 46#include "rtpdec_formats.h" 47 48struct PayloadContext { 49 // sdp setup parameters 50 uint8_t profile_idc; 51 uint8_t profile_iop; 52 uint8_t level_idc; 53 int packetization_mode; 54#ifdef DEBUG 55 int packet_types_received[32]; 56#endif 57}; 58 59#ifdef DEBUG 60#define COUNT_NAL_TYPE(data, nal) data->packet_types_received[(nal) & 0x1f]++ 61#else 62#define COUNT_NAL_TYPE(data, nal) do { } while (0) 63#endif 64 65static const uint8_t start_sequence[] = { 0, 0, 0, 1 }; 66 67static int sdp_parse_fmtp_config_h264(AVFormatContext *s, 68 AVStream *stream, 69 PayloadContext *h264_data, 70 char *attr, char *value) 71{ 72 AVCodecContext *codec = stream->codec; 73 assert(codec->codec_id == AV_CODEC_ID_H264); 74 assert(h264_data != NULL); 75 76 if (!strcmp(attr, "packetization-mode")) { 77 av_log(s, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value)); 78 h264_data->packetization_mode = atoi(value); 79 /* 80 * Packetization Mode: 81 * 0 or not present: Single NAL mode (Only nals from 1-23 are allowed) 82 * 1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed. 83 * 2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), 84 * and 29 (FU-B) are allowed. 85 */ 86 if (h264_data->packetization_mode > 1) 87 av_log(s, AV_LOG_ERROR, 88 "Interleaved RTP mode is not supported yet.\n"); 89 } else if (!strcmp(attr, "profile-level-id")) { 90 if (strlen(value) == 6) { 91 char buffer[3]; 92 // 6 characters=3 bytes, in hex. 93 uint8_t profile_idc; 94 uint8_t profile_iop; 95 uint8_t level_idc; 96 97 buffer[0] = value[0]; 98 buffer[1] = value[1]; 99 buffer[2] = '\0'; 100 profile_idc = strtol(buffer, NULL, 16); 101 buffer[0] = value[2]; 102 buffer[1] = value[3]; 103 profile_iop = strtol(buffer, NULL, 16); 104 buffer[0] = value[4]; 105 buffer[1] = value[5]; 106 level_idc = strtol(buffer, NULL, 16); 107 108 av_log(s, AV_LOG_DEBUG, 109 "RTP Profile IDC: %x Profile IOP: %x Level: %x\n", 110 profile_idc, profile_iop, level_idc); 111 h264_data->profile_idc = profile_idc; 112 h264_data->profile_iop = profile_iop; 113 h264_data->level_idc = level_idc; 114 } 115 } else if (!strcmp(attr, "sprop-parameter-sets")) { 116 codec->extradata_size = 0; 117 av_freep(&codec->extradata); 118 119 while (*value) { 120 char base64packet[1024]; 121 uint8_t decoded_packet[1024]; 122 int packet_size; 123 char *dst = base64packet; 124 125 while (*value && *value != ',' 126 && (dst - base64packet) < sizeof(base64packet) - 1) { 127 *dst++ = *value++; 128 } 129 *dst++ = '\0'; 130 131 if (*value == ',') 132 value++; 133 134 packet_size = av_base64_decode(decoded_packet, base64packet, 135 sizeof(decoded_packet)); 136 if (packet_size > 0) { 137 uint8_t *dest = av_malloc(packet_size + sizeof(start_sequence) + 138 codec->extradata_size + 139 FF_INPUT_BUFFER_PADDING_SIZE); 140 if (!dest) { 141 av_log(s, AV_LOG_ERROR, 142 "Unable to allocate memory for extradata!\n"); 143 return AVERROR(ENOMEM); 144 } 145 if (codec->extradata_size) { 146 memcpy(dest, codec->extradata, codec->extradata_size); 147 av_free(codec->extradata); 148 } 149 150 memcpy(dest + codec->extradata_size, start_sequence, 151 sizeof(start_sequence)); 152 memcpy(dest + codec->extradata_size + sizeof(start_sequence), 153 decoded_packet, packet_size); 154 memset(dest + codec->extradata_size + sizeof(start_sequence) + 155 packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); 156 157 codec->extradata = dest; 158 codec->extradata_size += sizeof(start_sequence) + packet_size; 159 } 160 } 161 av_log(s, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!\n", 162 codec->extradata, codec->extradata_size); 163 } 164 return 0; 165} 166 167// return 0 on packet, no more left, 1 on packet, 1 on partial packet 168static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, 169 AVStream *st, AVPacket *pkt, uint32_t *timestamp, 170 const uint8_t *buf, int len, uint16_t seq, 171 int flags) 172{ 173 uint8_t nal; 174 uint8_t type; 175 int result = 0; 176 177 if (!len) { 178 av_log(ctx, AV_LOG_ERROR, "Empty H264 RTP packet\n"); 179 return AVERROR_INVALIDDATA; 180 } 181 nal = buf[0]; 182 type = nal & 0x1f; 183 184 assert(data); 185 assert(buf); 186 187 /* Simplify the case (these are all the nal types used internally by 188 * the h264 codec). */ 189 if (type >= 1 && type <= 23) 190 type = 1; 191 switch (type) { 192 case 0: // undefined, but pass them through 193 case 1: 194 if ((result = av_new_packet(pkt, len + sizeof(start_sequence))) < 0) 195 return result; 196 memcpy(pkt->data, start_sequence, sizeof(start_sequence)); 197 memcpy(pkt->data + sizeof(start_sequence), buf, len); 198 COUNT_NAL_TYPE(data, nal); 199 break; 200 201 case 24: // STAP-A (one packet, multiple nals) 202 // consume the STAP-A NAL 203 buf++; 204 len--; 205 // first we are going to figure out the total size 206 { 207 int pass = 0; 208 int total_length = 0; 209 uint8_t *dst = NULL; 210 211 for (pass = 0; pass < 2; pass++) { 212 const uint8_t *src = buf; 213 int src_len = len; 214 215 while (src_len > 2) { 216 uint16_t nal_size = AV_RB16(src); 217 218 // consume the length of the aggregate 219 src += 2; 220 src_len -= 2; 221 222 if (nal_size <= src_len) { 223 if (pass == 0) { 224 // counting 225 total_length += sizeof(start_sequence) + nal_size; 226 } else { 227 // copying 228 assert(dst); 229 memcpy(dst, start_sequence, sizeof(start_sequence)); 230 dst += sizeof(start_sequence); 231 memcpy(dst, src, nal_size); 232 COUNT_NAL_TYPE(data, *src); 233 dst += nal_size; 234 } 235 } else { 236 av_log(ctx, AV_LOG_ERROR, 237 "nal size exceeds length: %d %d\n", nal_size, src_len); 238 } 239 240 // eat what we handled 241 src += nal_size; 242 src_len -= nal_size; 243 244 if (src_len < 0) 245 av_log(ctx, AV_LOG_ERROR, 246 "Consumed more bytes than we got! (%d)\n", src_len); 247 } 248 249 if (pass == 0) { 250 /* now we know the total size of the packet (with the 251 * start sequences added) */ 252 if ((result = av_new_packet(pkt, total_length)) < 0) 253 return result; 254 dst = pkt->data; 255 } else { 256 assert(dst - pkt->data == total_length); 257 } 258 } 259 } 260 break; 261 262 case 25: // STAP-B 263 case 26: // MTAP-16 264 case 27: // MTAP-24 265 case 29: // FU-B 266 av_log(ctx, AV_LOG_ERROR, 267 "Unhandled type (%d) (See RFC for implementation details\n", 268 type); 269 result = AVERROR(ENOSYS); 270 break; 271 272 case 28: // FU-A (fragmented nal) 273 buf++; 274 len--; // skip the fu_indicator 275 if (len > 1) { 276 // these are the same as above, we just redo them here for clarity 277 uint8_t fu_indicator = nal; 278 uint8_t fu_header = *buf; 279 uint8_t start_bit = fu_header >> 7; 280 uint8_t av_unused end_bit = (fu_header & 0x40) >> 6; 281 uint8_t nal_type = fu_header & 0x1f; 282 uint8_t reconstructed_nal; 283 284 // Reconstruct this packet's true nal; only the data follows. 285 /* The original nal forbidden bit and NRI are stored in this 286 * packet's nal. */ 287 reconstructed_nal = fu_indicator & 0xe0; 288 reconstructed_nal |= nal_type; 289 290 // skip the fu_header 291 buf++; 292 len--; 293 294 if (start_bit) 295 COUNT_NAL_TYPE(data, nal_type); 296 if (start_bit) { 297 /* copy in the start sequence, and the reconstructed nal */ 298 if ((result = av_new_packet(pkt, sizeof(start_sequence) + sizeof(nal) + len)) < 0) 299 return result; 300 memcpy(pkt->data, start_sequence, sizeof(start_sequence)); 301 pkt->data[sizeof(start_sequence)] = reconstructed_nal; 302 memcpy(pkt->data + sizeof(start_sequence) + sizeof(nal), buf, len); 303 } else { 304 if ((result = av_new_packet(pkt, len)) < 0) 305 return result; 306 memcpy(pkt->data, buf, len); 307 } 308 } else { 309 av_log(ctx, AV_LOG_ERROR, "Too short data for FU-A H264 RTP packet\n"); 310 result = AVERROR_INVALIDDATA; 311 } 312 break; 313 314 case 30: // undefined 315 case 31: // undefined 316 default: 317 av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type); 318 result = AVERROR_INVALIDDATA; 319 break; 320 } 321 322 pkt->stream_index = st->index; 323 324 return result; 325} 326 327static PayloadContext *h264_new_context(void) 328{ 329 return av_mallocz(sizeof(PayloadContext) + FF_INPUT_BUFFER_PADDING_SIZE); 330} 331 332static void h264_free_context(PayloadContext *data) 333{ 334#ifdef DEBUG 335 int ii; 336 337 for (ii = 0; ii < 32; ii++) { 338 if (data->packet_types_received[ii]) 339 av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n", 340 data->packet_types_received[ii], ii); 341 } 342#endif 343 344 av_free(data); 345} 346 347static av_cold int h264_init(AVFormatContext *s, int st_index, 348 PayloadContext *data) 349{ 350 if (st_index < 0) 351 return 0; 352 s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL; 353 return 0; 354} 355 356static int parse_h264_sdp_line(AVFormatContext *s, int st_index, 357 PayloadContext *h264_data, const char *line) 358{ 359 AVStream *stream; 360 AVCodecContext *codec; 361 const char *p = line; 362 363 if (st_index < 0) 364 return 0; 365 366 stream = s->streams[st_index]; 367 codec = stream->codec; 368 369 if (av_strstart(p, "framesize:", &p)) { 370 char buf1[50]; 371 char *dst = buf1; 372 373 // remove the protocol identifier 374 while (*p && *p == ' ') 375 p++; // strip spaces. 376 while (*p && *p != ' ') 377 p++; // eat protocol identifier 378 while (*p && *p == ' ') 379 p++; // strip trailing spaces. 380 while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) 381 *dst++ = *p++; 382 *dst = '\0'; 383 384 // a='framesize:96 320-240' 385 // set our parameters 386 codec->width = atoi(buf1); 387 codec->height = atoi(p + 1); // skip the - 388 } else if (av_strstart(p, "fmtp:", &p)) { 389 return ff_parse_fmtp(s, stream, h264_data, p, sdp_parse_fmtp_config_h264); 390 } else if (av_strstart(p, "cliprect:", &p)) { 391 // could use this if we wanted. 392 } 393 394 return 0; 395} 396 397RTPDynamicProtocolHandler ff_h264_dynamic_handler = { 398 .enc_name = "H264", 399 .codec_type = AVMEDIA_TYPE_VIDEO, 400 .codec_id = AV_CODEC_ID_H264, 401 .init = h264_init, 402 .parse_sdp_a_line = parse_h264_sdp_line, 403 .alloc = h264_new_context, 404 .free = h264_free_context, 405 .parse_packet = h264_handle_packet 406}; 407