2 * RTP H264 Protocol (RFC3984)
3 * Copyright (c) 2006 Ryan Martell
5 * This file is part of FFmpeg.
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.
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.
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
24 * @brief H.264 / RTP Code (RFC3984)
25 * @author Ryan Martell <rdm4@martellventures.com>
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,
36 #include "libavutil/attributes.h"
37 #include "libavutil/base64.h"
38 #include "libavutil/avstring.h"
39 #include "libavcodec/get_bits.h"
46 #include "rtpdec_formats.h"
48 struct PayloadContext
{
49 // sdp setup parameters
53 int packetization_mode
;
55 int packet_types_received
[32];
60 #define COUNT_NAL_TYPE(data, nal) data->packet_types_received[(nal) & 0x1f]++
62 #define COUNT_NAL_TYPE(data, nal) do { } while (0)
65 static const uint8_t start_sequence
[] = { 0, 0, 0, 1 };
67 static int sdp_parse_fmtp_config_h264(AVFormatContext
*s
,
69 PayloadContext
*h264_data
,
70 char *attr
, char *value
)
72 AVCodecContext
*codec
= stream
->codec
;
73 assert(codec
->codec_id
== AV_CODEC_ID_H264
);
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
);
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.
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) {
92 // 6 characters=3 bytes, in hex.
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);
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
;
115 } else if (!strcmp(attr
, "sprop-parameter-sets")) {
116 codec
->extradata_size
= 0;
117 av_freep(&codec
->extradata
);
120 char base64packet
[1024];
121 uint8_t decoded_packet
[1024];
123 char *dst
= base64packet
;
125 while (*value
&& *value
!= ','
126 && (dst
- base64packet
) < sizeof(base64packet
) - 1) {
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
);
141 av_log(s
, AV_LOG_ERROR
,
142 "Unable to allocate memory for extradata!\n");
143 return AVERROR(ENOMEM
);
145 if (codec
->extradata_size
) {
146 memcpy(dest
, codec
->extradata
, codec
->extradata_size
);
147 av_free(codec
->extradata
);
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
);
157 codec
->extradata
= dest
;
158 codec
->extradata_size
+= sizeof(start_sequence
) + packet_size
;
161 av_log(s
, AV_LOG_DEBUG
, "Extradata set to %p (size: %d)!\n",
162 codec
->extradata
, codec
->extradata_size
);
167 // return 0 on packet, no more left, 1 on packet, 1 on partial packet
168 static 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
,
178 av_log(ctx
, AV_LOG_ERROR
, "Empty H264 RTP packet\n");
179 return AVERROR_INVALIDDATA
;
187 /* Simplify the case (these are all the nal types used internally by
188 * the h264 codec). */
189 if (type
>= 1 && type
<= 23)
192 case 0: // undefined, but pass them through
194 if ((result
= av_new_packet(pkt
, len
+ sizeof(start_sequence
))) < 0)
196 memcpy(pkt
->data
, start_sequence
, sizeof(start_sequence
));
197 memcpy(pkt
->data
+ sizeof(start_sequence
), buf
, len
);
198 COUNT_NAL_TYPE(data
, nal
);
201 case 24: // STAP-A (one packet, multiple nals)
202 // consume the STAP-A NAL
205 // first we are going to figure out the total size
208 int total_length
= 0;
211 for (pass
= 0; pass
< 2; pass
++) {
212 const uint8_t *src
= buf
;
215 while (src_len
> 2) {
216 uint16_t nal_size
= AV_RB16(src
);
218 // consume the length of the aggregate
222 if (nal_size
<= src_len
) {
225 total_length
+= sizeof(start_sequence
) + nal_size
;
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
);
236 av_log(ctx
, AV_LOG_ERROR
,
237 "nal size exceeds length: %d %d\n", nal_size
, src_len
);
240 // eat what we handled
245 av_log(ctx
, AV_LOG_ERROR
,
246 "Consumed more bytes than we got! (%d)\n", src_len
);
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)
256 assert(dst
- pkt
->data
== total_length
);
266 av_log(ctx
, AV_LOG_ERROR
,
267 "Unhandled type (%d) (See RFC for implementation details\n",
269 result
= AVERROR(ENOSYS
);
272 case 28: // FU-A (fragmented nal)
274 len
--; // skip the fu_indicator
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
;
284 // Reconstruct this packet's true nal; only the data follows.
285 /* The original nal forbidden bit and NRI are stored in this
287 reconstructed_nal
= fu_indicator
& 0xe0;
288 reconstructed_nal
|= nal_type
;
290 // skip the fu_header
295 COUNT_NAL_TYPE(data
, nal_type
);
297 /* copy in the start sequence, and the reconstructed nal */
298 if ((result
= av_new_packet(pkt
, sizeof(start_sequence
) + sizeof(nal
) + len
)) < 0)
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
);
304 if ((result
= av_new_packet(pkt
, len
)) < 0)
306 memcpy(pkt
->data
, buf
, len
);
309 av_log(ctx
, AV_LOG_ERROR
, "Too short data for FU-A H264 RTP packet\n");
310 result
= AVERROR_INVALIDDATA
;
314 case 30: // undefined
315 case 31: // undefined
317 av_log(ctx
, AV_LOG_ERROR
, "Undefined type (%d)\n", type
);
318 result
= AVERROR_INVALIDDATA
;
322 pkt
->stream_index
= st
->index
;
327 static PayloadContext
*h264_new_context(void)
329 return av_mallocz(sizeof(PayloadContext
) + FF_INPUT_BUFFER_PADDING_SIZE
);
332 static void h264_free_context(PayloadContext
*data
)
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
);
347 static av_cold
int h264_init(AVFormatContext
*s
, int st_index
,
348 PayloadContext
*data
)
352 s
->streams
[st_index
]->need_parsing
= AVSTREAM_PARSE_FULL
;
356 static int parse_h264_sdp_line(AVFormatContext
*s
, int st_index
,
357 PayloadContext
*h264_data
, const char *line
)
360 AVCodecContext
*codec
;
361 const char *p
= line
;
366 stream
= s
->streams
[st_index
];
367 codec
= stream
->codec
;
369 if (av_strstart(p
, "framesize:", &p
)) {
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)
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.
397 RTPDynamicProtocolHandler ff_h264_dynamic_handler
= {
399 .codec_type
= AVMEDIA_TYPE_VIDEO
,
400 .codec_id
= AV_CODEC_ID_H264
,
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