FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtpdec_h264.c
Go to the documentation of this file.
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 
48 struct PayloadContext {
49  // sdp setup parameters
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 
65 static const uint8_t start_sequence[] = { 0, 0, 0, 1 };
66 
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)
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 +
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
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 
328 {
330 }
331 
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 
347 static av_cold int h264_init(AVFormatContext *s, int st_index,
349 {
350  if (st_index < 0)
351  return 0;
352  s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
353  return 0;
354 }
355 
356 static 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 
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 };