Libav
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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
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 };
uint8_t profile_idc
Definition: rtpdec_h264.c:50
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
int ff_parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *p, int(*parse_fmtp)(AVFormatContext *s, AVStream *stream, PayloadContext *data, char *attr, char *value))
Definition: rtpdec.c:829
RTP/JPEG specific private data.
Definition: rdt.c:83
int index
stream index in AVFormatContext
Definition: avformat.h:700
int packetization_mode
Definition: rtpdec_h264.c:53
RTPDynamicProtocolHandler ff_h264_dynamic_handler
Definition: rtpdec_h264.c:397
Macro definitions for various function/variable attributes.
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
Format I/O context.
Definition: avformat.h:922
static void h264_free_context(PayloadContext *data)
Definition: rtpdec_h264.c:332
uint8_t
#define av_cold
Definition: attributes.h:66
enum AVStreamParseType need_parsing
Definition: avformat.h:867
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1164
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:990
const char data[16]
Definition: mxf.c:70
uint8_t * data
Definition: avcodec.h:973
static av_cold int h264_init(AVFormatContext *s, int st_index, PayloadContext *data)
Definition: rtpdec_h264.c:347
static int flags
Definition: log.c:44
bitstream reader API header.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:81
static PayloadContext * h264_new_context(void)
Definition: rtpdec_h264.c:327
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:186
#define AV_RB16
Definition: intreadwrite.h:53
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:144
Definition: graph2dot.c:49
static int parse_h264_sdp_line(AVFormatContext *s, int st_index, PayloadContext *h264_data, const char *line)
Definition: rtpdec_h264.c:356
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
#define pass
Definition: fft_template.c:335
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:718
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:531
int width
picture width / height.
Definition: avcodec.h:1229
static char buffer[20]
Definition: seek-test.c:31
uint8_t profile_iop
Definition: rtpdec_h264.c:51
#define COUNT_NAL_TYPE(data, nal)
Definition: rtpdec_h264.c:62
Stream structure.
Definition: avformat.h:699
static int sdp_parse_fmtp_config_h264(AVFormatContext *s, AVStream *stream, PayloadContext *h264_data, char *attr, char *value)
Definition: rtpdec_h264.c:67
NULL
Definition: eval.c:55
enum AVCodecID codec_id
Definition: avcodec.h:1067
main external API structure.
Definition: avcodec.h:1050
int extradata_size
Definition: avcodec.h:1165
uint8_t level_idc
Definition: rtpdec_h264.c:52
const char enc_name[50]
Definition: rtpdec.h:116
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:32
full parsing and repack
Definition: avformat.h:653
Main libavformat public API header.
static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags)
Definition: rtpdec_h264.c:168
int len
static const uint8_t start_sequence[]
Definition: rtpdec_h264.c:65
int av_base64_decode(uint8_t *out, const char *in, int out_size)
Decode a base64-encoded string.
Definition: base64.c:45
int stream_index
Definition: avcodec.h:975
This structure stores compressed data.
Definition: avcodec.h:950
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
#define av_unused
Definition: attributes.h:86