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 
39 #include "libavutil/base64.h"
40 #include "libavutil/avstring.h"
41 #include "libavcodec/get_bits.h"
42 #include "avformat.h"
43 #include "mpegts.h"
44 
45 #include <unistd.h>
46 #include "network.h"
47 #include <assert.h>
48 
49 #include "rtpdec.h"
50 #include "rtpdec_formats.h"
51 
55 struct PayloadContext {
56  unsigned long cookie;
57 
58  //sdp setup parameters
59  uint8_t profile_idc;
60  uint8_t profile_iop;
61  uint8_t level_idc;
63 #ifdef DEBUG
64  int packet_types_received[32];
65 #endif
66 };
67 
68 #define MAGIC_COOKIE (0xdeadbeef)
69 #define DEAD_COOKIE (0xdeaddead)
70 
71 /* ---------------- private code */
73  PayloadContext * h264_data,
74  char *attr, char *value)
75 {
76  AVCodecContext *codec = stream->codec;
77  assert(codec->codec_id == CODEC_ID_H264);
78  assert(h264_data != NULL);
79 
80  if (!strcmp(attr, "packetization-mode")) {
81  av_log(codec, AV_LOG_DEBUG, "RTP Packetization Mode: %d\n", atoi(value));
82  h264_data->packetization_mode = atoi(value);
83  /*
84  Packetization Mode:
85  0 or not present: Single NAL mode (Only nals from 1-23 are allowed)
86  1: Non-interleaved Mode: 1-23, 24 (STAP-A), 28 (FU-A) are allowed.
87  2: Interleaved Mode: 25 (STAP-B), 26 (MTAP16), 27 (MTAP24), 28 (FU-A), and 29 (FU-B) are allowed.
88  */
89  if (h264_data->packetization_mode > 1)
90  av_log(codec, AV_LOG_ERROR,
91  "Interleaved RTP mode is not supported yet.");
92  } else if (!strcmp(attr, "profile-level-id")) {
93  if (strlen(value) == 6) {
94  char buffer[3];
95  // 6 characters=3 bytes, in hex.
96  uint8_t profile_idc;
97  uint8_t profile_iop;
98  uint8_t level_idc;
99 
100  buffer[0] = value[0]; buffer[1] = value[1]; buffer[2] = '\0';
101  profile_idc = strtol(buffer, NULL, 16);
102  buffer[0] = value[2]; buffer[1] = value[3];
103  profile_iop = strtol(buffer, NULL, 16);
104  buffer[0] = value[4]; buffer[1] = value[5];
105  level_idc = strtol(buffer, NULL, 16);
106 
107  // set the parameters...
108  av_log(codec, 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  uint8_t start_sequence[]= { 0, 0, 1 };
117  codec->extradata_size= 0;
118  codec->extradata= NULL;
119 
120  while (*value) {
121  char base64packet[1024];
122  uint8_t decoded_packet[1024];
123  int packet_size;
124  char *dst = base64packet;
125 
126  while (*value && *value != ','
127  && (dst - base64packet) < sizeof(base64packet) - 1) {
128  *dst++ = *value++;
129  }
130  *dst++ = '\0';
131 
132  if (*value == ',')
133  value++;
134 
135  packet_size= av_base64_decode(decoded_packet, base64packet, 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  {
142  if(codec->extradata_size)
143  {
144  // av_realloc?
145  memcpy(dest, codec->extradata, codec->extradata_size);
146  av_free(codec->extradata);
147  }
148 
149  memcpy(dest+codec->extradata_size, start_sequence, sizeof(start_sequence));
150  memcpy(dest+codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size);
151  memset(dest+codec->extradata_size+sizeof(start_sequence)+
152  packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
153 
154  codec->extradata= dest;
155  codec->extradata_size+= sizeof(start_sequence)+packet_size;
156  } else {
157  av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!");
158  return AVERROR(ENOMEM);
159  }
160  }
161  }
162  av_log(codec, AV_LOG_DEBUG, "Extradata set to %p (size: %d)!", 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...
170  AVStream *st,
171  AVPacket * pkt,
172  uint32_t * timestamp,
173  const uint8_t * buf,
174  int len, int flags)
175 {
176  uint8_t nal = buf[0];
177  uint8_t type = (nal & 0x1f);
178  int result= 0;
179  uint8_t start_sequence[]= {0, 0, 1};
180 
181 #ifdef DEBUG
182  assert(data);
183  assert(data->cookie == MAGIC_COOKIE);
184 #endif
185  assert(buf);
186 
187  if (type >= 1 && type <= 23)
188  type = 1; // simplify the case. (these are all the nal types used internally by the h264 codec)
189  switch (type) {
190  case 0: // undefined, but pass them through
191  case 1:
192  av_new_packet(pkt, len+sizeof(start_sequence));
193  memcpy(pkt->data, start_sequence, sizeof(start_sequence));
194  memcpy(pkt->data+sizeof(start_sequence), buf, len);
195 #ifdef DEBUG
196  data->packet_types_received[nal & 0x1f]++;
197 #endif
198  break;
199 
200  case 24: // STAP-A (one packet, multiple nals)
201  // consume the STAP-A NAL
202  buf++;
203  len--;
204  // first we are going to figure out the total size....
205  {
206  int pass= 0;
207  int total_length= 0;
208  uint8_t *dst= NULL;
209 
210  for(pass= 0; pass<2; pass++) {
211  const uint8_t *src= buf;
212  int src_len= len;
213 
214  do {
215  uint16_t nal_size = AV_RB16(src); // this going to be a problem if unaligned (can it be?)
216 
217  // consume the length of the aggregate...
218  src += 2;
219  src_len -= 2;
220 
221  if (nal_size <= src_len) {
222  if(pass==0) {
223  // counting...
224  total_length+= sizeof(start_sequence)+nal_size;
225  } else {
226  // copying
227  assert(dst);
228  memcpy(dst, start_sequence, sizeof(start_sequence));
229  dst+= sizeof(start_sequence);
230  memcpy(dst, src, nal_size);
231 #ifdef DEBUG
232  data->packet_types_received[*src & 0x1f]++;
233 #endif
234  dst+= nal_size;
235  }
236  } else {
237  av_log(ctx, AV_LOG_ERROR,
238  "nal size exceeds length: %d %d\n", nal_size, src_len);
239  }
240 
241  // eat what we handled...
242  src += nal_size;
243  src_len -= nal_size;
244 
245  if (src_len < 0)
246  av_log(ctx, AV_LOG_ERROR,
247  "Consumed more bytes than we got! (%d)\n", src_len);
248  } while (src_len > 2); // because there could be rtp padding..
249 
250  if(pass==0) {
251  // now we know the total size of the packet (with the start sequences added)
252  av_new_packet(pkt, total_length);
253  dst= pkt->data;
254  } else {
255  assert(dst-pkt->data==total_length);
256  }
257  }
258  }
259  break;
260 
261  case 25: // STAP-B
262  case 26: // MTAP-16
263  case 27: // MTAP-24
264  case 29: // FU-B
265  av_log(ctx, AV_LOG_ERROR,
266  "Unhandled type (%d) (See RFC for implementation details\n",
267  type);
268  result= -1;
269  break;
270 
271  case 28: // FU-A (fragmented nal)
272  buf++;
273  len--; // skip the fu_indicator
274  {
275  // these are the same as above, we just redo them here for clarity...
276  uint8_t fu_indicator = nal;
277  uint8_t fu_header = *buf; // read the fu_header.
278  uint8_t start_bit = fu_header >> 7;
279 // uint8_t end_bit = (fu_header & 0x40) >> 6;
280  uint8_t nal_type = (fu_header & 0x1f);
281  uint8_t reconstructed_nal;
282 
283  // reconstruct this packet's true nal; only the data follows..
284  reconstructed_nal = fu_indicator & (0xe0); // the original nal forbidden bit and NRI are stored in this packet's nal;
285  reconstructed_nal |= nal_type;
286 
287  // skip the fu_header...
288  buf++;
289  len--;
290 
291 #ifdef DEBUG
292  if (start_bit)
293  data->packet_types_received[nal_type]++;
294 #endif
295  if(start_bit) {
296  // copy in the start sequence, and the reconstructed nal....
297  av_new_packet(pkt, sizeof(start_sequence)+sizeof(nal)+len);
298  memcpy(pkt->data, start_sequence, sizeof(start_sequence));
299  pkt->data[sizeof(start_sequence)]= reconstructed_nal;
300  memcpy(pkt->data+sizeof(start_sequence)+sizeof(nal), buf, len);
301  } else {
302  av_new_packet(pkt, len);
303  memcpy(pkt->data, buf, len);
304  }
305  }
306  break;
307 
308  case 30: // undefined
309  case 31: // undefined
310  default:
311  av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)", type);
312  result= -1;
313  break;
314  }
315 
316  pkt->stream_index = st->index;
317 
318  return result;
319 }
320 
321 /* ---------------- public code */
323 {
325  av_mallocz(sizeof(PayloadContext) +
327 
328  if (data) {
329  data->cookie = MAGIC_COOKIE;
330  }
331 
332  return data;
333 }
334 
336 {
337 #ifdef DEBUG
338  int ii;
339 
340  for (ii = 0; ii < 32; ii++) {
341  if (data->packet_types_received[ii])
342  av_log(NULL, AV_LOG_DEBUG, "Received %d packets of type %d\n",
343  data->packet_types_received[ii], ii);
344  }
345 #endif
346 
347  assert(data);
348  assert(data->cookie == MAGIC_COOKIE);
349 
350  // avoid stale pointers (assert)
351  data->cookie = DEAD_COOKIE;
352 
353  // and clear out this...
354  av_free(data);
355 }
356 
357 static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
358  PayloadContext *h264_data, const char *line)
359 {
360  AVStream *stream = s->streams[st_index];
361  AVCodecContext *codec = stream->codec;
362  const char *p = line;
363 
364  assert(h264_data->cookie == MAGIC_COOKIE);
365 
366  if (av_strstart(p, "framesize:", &p)) {
367  char buf1[50];
368  char *dst = buf1;
369 
370  // remove the protocol identifier..
371  while (*p && *p == ' ') p++; // strip spaces.
372  while (*p && *p != ' ') p++; // eat protocol identifier
373  while (*p && *p == ' ') p++; // strip trailing spaces.
374  while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {
375  *dst++ = *p++;
376  }
377  *dst = '\0';
378 
379  // a='framesize:96 320-240'
380  // set our parameters..
381  codec->width = atoi(buf1);
382  codec->height = atoi(p + 1); // skip the -
383  codec->pix_fmt = PIX_FMT_YUV420P;
384  } else if (av_strstart(p, "fmtp:", &p)) {
385  return ff_parse_fmtp(stream, h264_data, p, sdp_parse_fmtp_config_h264);
386  } else if (av_strstart(p, "cliprect:", &p)) {
387  // could use this if we wanted.
388  }
389 
390  return 0; // keep processing it the normal way...
391 }
392 
397  .enc_name = "H264",
398  .codec_type = AVMEDIA_TYPE_VIDEO,
399  .codec_id = CODEC_ID_H264,
400  .parse_sdp_a_line = parse_h264_sdp_line,
401  .alloc = h264_new_context,
402  .free = h264_free_context,
403  .parse_packet = h264_handle_packet
404 };