Imported Debian version 2.5.0~trusty1.1
[deb_ffmpeg.git] / ffmpeg / libavformat / rtpdec_hevc.c
CommitLineData
2ba45a60
DM
1/*
2 * RTP parser for HEVC/H.265 payload format (draft version 6)
3 * Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.com>
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#include "libavutil/avstring.h"
f6fa7814 24#include "libavutil/base64.h"
2ba45a60
DM
25
26#include "avformat.h"
27#include "rtpdec.h"
28
29#define RTP_HEVC_PAYLOAD_HEADER_SIZE 2
30#define RTP_HEVC_FU_HEADER_SIZE 1
31#define RTP_HEVC_DONL_FIELD_SIZE 2
32#define HEVC_SPECIFIED_NAL_UNIT_TYPES 48
33
34/* SDP out-of-band signaling data */
35struct PayloadContext {
36 int using_donl_field;
37 int profile_id;
f6fa7814
DM
38 uint8_t *sps, *pps, *vps, *sei;
39 int sps_size, pps_size, vps_size, sei_size;
2ba45a60
DM
40};
41
42static const uint8_t start_sequence[] = { 0x00, 0x00, 0x00, 0x01 };
43
44static av_cold PayloadContext *hevc_new_context(void)
45{
46 return av_mallocz(sizeof(PayloadContext));
47}
48
49static av_cold void hevc_free_context(PayloadContext *data)
50{
51 av_free(data);
52}
53
54static av_cold int hevc_init(AVFormatContext *ctx, int st_index,
55 PayloadContext *data)
56{
57 av_dlog(ctx, "hevc_init() for stream %d\n", st_index);
58
59 if (st_index < 0)
60 return 0;
61
62 ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
63
64 return 0;
65}
66
67static av_cold int hevc_sdp_parse_fmtp_config(AVFormatContext *s,
68 AVStream *stream,
69 PayloadContext *hevc_data,
70 char *attr, char *value)
71{
72 /* profile-space: 0-3 */
73 /* profile-id: 0-31 */
74 if (!strcmp(attr, "profile-id")) {
75 hevc_data->profile_id = atoi(value);
76 av_dlog(s, "SDP: found profile-id: %d\n", hevc_data->profile_id);
77 }
78
79 /* tier-flag: 0-1 */
80 /* level-id: 0-255 */
81 /* interop-constraints: [base16] */
82 /* profile-compatibility-indicator: [base16] */
83 /* sprop-sub-layer-id: 0-6, defines highest possible value for TID, default: 6 */
84 /* recv-sub-layer-id: 0-6 */
85 /* max-recv-level-id: 0-255 */
86 /* tx-mode: MSM,SSM */
87 /* sprop-vps: [base64] */
88 /* sprop-sps: [base64] */
89 /* sprop-pps: [base64] */
90 /* sprop-sei: [base64] */
f6fa7814
DM
91 if (!strcmp(attr, "sprop-vps") || !strcmp(attr, "sprop-sps") ||
92 !strcmp(attr, "sprop-pps") || !strcmp(attr, "sprop-sei")) {
93 uint8_t **data_ptr;
94 int *size_ptr;
95 if (!strcmp(attr, "sprop-vps")) {
96 data_ptr = &hevc_data->vps;
97 size_ptr = &hevc_data->vps_size;
98 } else if (!strcmp(attr, "sprop-sps")) {
99 data_ptr = &hevc_data->sps;
100 size_ptr = &hevc_data->sps_size;
101 } else if (!strcmp(attr, "sprop-pps")) {
102 data_ptr = &hevc_data->pps;
103 size_ptr = &hevc_data->pps_size;
104 } else if (!strcmp(attr, "sprop-sei")) {
105 data_ptr = &hevc_data->sei;
106 size_ptr = &hevc_data->sei_size;
107 }
108
109 while (*value) {
110 char base64packet[1024];
111 uint8_t decoded_packet[1024];
112 int decoded_packet_size;
113 char *dst = base64packet;
114
115 while (*value && *value != ',' &&
116 (dst - base64packet) < sizeof(base64packet) - 1) {
117 *dst++ = *value++;
118 }
119 *dst++ = '\0';
120
121 if (*value == ',')
122 value++;
123
124 decoded_packet_size = av_base64_decode(decoded_packet, base64packet,
125 sizeof(decoded_packet));
126 if (decoded_packet_size > 0) {
127 uint8_t *tmp = av_realloc(*data_ptr, decoded_packet_size +
128 sizeof(start_sequence) + *size_ptr);
129 if (!tmp) {
130 av_log(s, AV_LOG_ERROR,
131 "Unable to allocate memory for extradata!\n");
132 return AVERROR(ENOMEM);
133 }
134 *data_ptr = tmp;
135
136 memcpy(*data_ptr + *size_ptr, start_sequence,
137 sizeof(start_sequence));
138 memcpy(*data_ptr + *size_ptr + sizeof(start_sequence),
139 decoded_packet, decoded_packet_size);
140
141 *size_ptr += sizeof(start_sequence) + decoded_packet_size;
142 }
143 }
144 }
145
2ba45a60
DM
146 /* max-lsr, max-lps, max-cpb, max-dpb, max-br, max-tr, max-tc */
147 /* max-fps */
148
149 /* sprop-max-don-diff: 0-32767
150
151 When the RTP stream depends on one or more other RTP
152 streams (in this case tx-mode MUST be equal to "MSM" and
153 MSM is in use), this parameter MUST be present and the
154 value MUST be greater than 0.
155 */
156 if (!strcmp(attr, "sprop-max-don-diff")) {
157 if (atoi(value) > 0)
158 hevc_data->using_donl_field = 1;
159 av_dlog(s, "Found sprop-max-don-diff in SDP, DON field usage is: %d\n",
160 hevc_data->using_donl_field);
161 }
162
163 /* sprop-depack-buf-nalus: 0-32767 */
164 if (!strcmp(attr, "sprop-depack-buf-nalus")) {
165 if (atoi(value) > 0)
166 hevc_data->using_donl_field = 1;
167 av_dlog(s, "Found sprop-depack-buf-nalus in SDP, DON field usage is: %d\n",
168 hevc_data->using_donl_field);
169 }
170
171 /* sprop-depack-buf-bytes: 0-4294967295 */
172 /* depack-buf-cap */
173 /* sprop-segmentation-id: 0-3 */
174 /* sprop-spatial-segmentation-idc: [base16] */
175 /* dec-parallel-ca: */
176 /* include-dph */
177
178 return 0;
179}
180
181static av_cold int hevc_parse_sdp_line(AVFormatContext *ctx, int st_index,
182 PayloadContext *hevc_data, const char *line)
183{
184 AVStream *current_stream;
185 AVCodecContext *codec;
186 const char *sdp_line_ptr = line;
187
188 if (st_index < 0)
189 return 0;
190
191 current_stream = ctx->streams[st_index];
192 codec = current_stream->codec;
193
194 if (av_strstart(sdp_line_ptr, "framesize:", &sdp_line_ptr)) {
195 char str_video_width[50];
196 char *str_video_width_ptr = str_video_width;
197
198 /*
199 * parse "a=framesize:96 320-240"
200 */
201
202 /* ignore spaces */
203 while (*sdp_line_ptr && *sdp_line_ptr == ' ')
204 sdp_line_ptr++;
205 /* ignore RTP payload ID */
206 while (*sdp_line_ptr && *sdp_line_ptr != ' ')
207 sdp_line_ptr++;
208 /* ignore spaces */
209 while (*sdp_line_ptr && *sdp_line_ptr == ' ')
210 sdp_line_ptr++;
211 /* extract the actual video resolution description */
212 while (*sdp_line_ptr && *sdp_line_ptr != '-' &&
213 (str_video_width_ptr - str_video_width) < sizeof(str_video_width) - 1)
214 *str_video_width_ptr++ = *sdp_line_ptr++;
215 /* add trailing zero byte */
216 *str_video_width_ptr = '\0';
217
218 /* determine the width value */
219 codec->width = atoi(str_video_width);
220 /* jump beyond the "-" and determine the height value */
221 codec->height = atoi(sdp_line_ptr + 1);
222 } else if (av_strstart(sdp_line_ptr, "fmtp:", &sdp_line_ptr)) {
f6fa7814
DM
223 int ret = ff_parse_fmtp(ctx, current_stream, hevc_data, sdp_line_ptr,
224 hevc_sdp_parse_fmtp_config);
225 if (hevc_data->vps_size || hevc_data->sps_size ||
226 hevc_data->pps_size || hevc_data->sei_size) {
227 av_freep(&codec->extradata);
228 codec->extradata_size = hevc_data->vps_size + hevc_data->sps_size +
229 hevc_data->pps_size + hevc_data->sei_size;
230 codec->extradata = av_malloc(codec->extradata_size +
231 FF_INPUT_BUFFER_PADDING_SIZE);
232 if (!codec->extradata) {
233 ret = AVERROR(ENOMEM);
234 codec->extradata_size = 0;
235 } else {
236 int pos = 0;
237 memcpy(codec->extradata + pos, hevc_data->vps, hevc_data->vps_size);
238 pos += hevc_data->vps_size;
239 memcpy(codec->extradata + pos, hevc_data->sps, hevc_data->sps_size);
240 pos += hevc_data->sps_size;
241 memcpy(codec->extradata + pos, hevc_data->pps, hevc_data->pps_size);
242 pos += hevc_data->pps_size;
243 memcpy(codec->extradata + pos, hevc_data->sei, hevc_data->sei_size);
244 pos += hevc_data->sei_size;
245 memset(codec->extradata + pos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
246 }
247
248 av_freep(&hevc_data->vps);
249 av_freep(&hevc_data->sps);
250 av_freep(&hevc_data->pps);
251 av_freep(&hevc_data->sei);
252 hevc_data->vps_size = 0;
253 hevc_data->sps_size = 0;
254 hevc_data->pps_size = 0;
255 hevc_data->sei_size = 0;
256 }
257 return ret;
2ba45a60
DM
258 }
259
260 return 0;
261}
262
263static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx,
264 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
265 const uint8_t *buf, int len, uint16_t seq,
266 int flags)
267{
268 const uint8_t *rtp_pl = buf;
269 int tid, lid, nal_type;
270 int first_fragment, last_fragment, fu_type;
271 uint8_t new_nal_header[2];
272 int res = 0;
273
274 /* sanity check for size of input packet: 1 byte payload at least */
275 if (len < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) {
276 av_log(ctx, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", len);
277 return AVERROR_INVALIDDATA;
278 }
279
280 /*
281 decode the HEVC payload header according to section 4 of draft version 6:
282
283 0 1
284 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
285 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
286 |F| Type | LayerId | TID |
287 +-------------+-----------------+
288
289 Forbidden zero (F): 1 bit
290 NAL unit type (Type): 6 bits
291 NUH layer ID (LayerId): 6 bits
292 NUH temporal ID plus 1 (TID): 3 bits
293 */
294 nal_type = (buf[0] >> 1) & 0x3f;
295 lid = ((buf[0] << 5) & 0x20) | ((buf[1] >> 3) & 0x1f);
296 tid = buf[1] & 0x07;
297
298 /* sanity check for correct layer ID */
299 if (lid) {
300 /* future scalable or 3D video coding extensions */
301 avpriv_report_missing_feature(ctx, "Multi-layer HEVC coding\n");
302 return AVERROR_PATCHWELCOME;
303 }
304
305 /* sanity check for correct temporal ID */
306 if (!tid) {
307 av_log(ctx, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n");
308 return AVERROR_INVALIDDATA;
309 }
310
311 /* sanity check for correct NAL unit type */
312 if (nal_type > 50) {
313 av_log(ctx, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", nal_type);
314 return AVERROR_INVALIDDATA;
315 }
316
317 switch (nal_type) {
318 /* aggregated packets (AP) */
319 case 48:
320 /* pass the HEVC payload header */
321 buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;
322 len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;
323
324 /* pass the HEVC DONL field */
325 if (rtp_hevc_ctx->using_donl_field) {
326 buf += RTP_HEVC_DONL_FIELD_SIZE;
327 len -= RTP_HEVC_DONL_FIELD_SIZE;
328 }
329
330 /* fall-through */
331 /* video parameter set (VPS) */
332 case 32:
333 /* sequence parameter set (SPS) */
334 case 33:
335 /* picture parameter set (PPS) */
336 case 34:
337 /* supplemental enhancement information (SEI) */
338 case 39:
339 /* single NAL unit packet */
340 default:
341 /* sanity check for size of input packet: 1 byte payload at least */
342 if (len < 1) {
343 av_log(ctx, AV_LOG_ERROR,
344 "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
345 len, nal_type);
346 return AVERROR_INVALIDDATA;
347 }
348
349 /* create A/V packet */
350 if ((res = av_new_packet(pkt, sizeof(start_sequence) + len)) < 0)
351 return res;
352 /* A/V packet: copy start sequence */
353 memcpy(pkt->data, start_sequence, sizeof(start_sequence));
354 /* A/V packet: copy NAL unit data */
355 memcpy(pkt->data + sizeof(start_sequence), buf, len);
356
357 break;
358 /* fragmentation unit (FU) */
359 case 49:
360 /* pass the HEVC payload header */
361 buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;
362 len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;
363
2ba45a60
DM
364 /*
365 decode the FU header
366
367 0 1 2 3 4 5 6 7
368 +-+-+-+-+-+-+-+-+
369 |S|E| FuType |
370 +---------------+
371
372 Start fragment (S): 1 bit
373 End fragment (E): 1 bit
374 FuType: 6 bits
375 */
376 first_fragment = buf[0] & 0x80;
377 last_fragment = buf[0] & 0x40;
378 fu_type = buf[0] & 0x3f;
379
380 /* pass the HEVC FU header */
381 buf += RTP_HEVC_FU_HEADER_SIZE;
382 len -= RTP_HEVC_FU_HEADER_SIZE;
383
384 /* pass the HEVC DONL field */
385 if (rtp_hevc_ctx->using_donl_field) {
386 buf += RTP_HEVC_DONL_FIELD_SIZE;
387 len -= RTP_HEVC_DONL_FIELD_SIZE;
388 }
389
390 av_dlog(ctx, " FU type %d with %d bytes\n", fu_type, len);
391
f6fa7814 392 /* sanity check for size of input packet: 1 byte payload at least */
2ba45a60
DM
393 if (len > 0) {
394 new_nal_header[0] = (rtp_pl[0] & 0x81) | (fu_type << 1);
395 new_nal_header[1] = rtp_pl[1];
396
397 /* start fragment vs. subsequent fragments */
398 if (first_fragment) {
399 if (!last_fragment) {
400 /* create A/V packet which is big enough */
401 if ((res = av_new_packet(pkt, sizeof(start_sequence) + sizeof(new_nal_header) + len)) < 0)
402 return res;
403 /* A/V packet: copy start sequence */
404 memcpy(pkt->data, start_sequence, sizeof(start_sequence));
405 /* A/V packet: copy new NAL header */
406 memcpy(pkt->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header));
407 /* A/V packet: copy NAL unit data */
408 memcpy(pkt->data + sizeof(start_sequence) + sizeof(new_nal_header), buf, len);
409 } else {
410 av_log(ctx, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n");
411 res = AVERROR_INVALIDDATA;
412 }
413 } else {
414 /* create A/V packet */
415 if ((res = av_new_packet(pkt, len)) < 0)
416 return res;
417 /* A/V packet: copy NAL unit data */
418 memcpy(pkt->data, buf, len);
419 }
420 } else {
f6fa7814
DM
421 if (len < 0) {
422 av_log(ctx, AV_LOG_ERROR,
423 "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
424 len, nal_type);
425 res = AVERROR_INVALIDDATA;
426 } else {
427 res = AVERROR(EAGAIN);
428 }
2ba45a60
DM
429 }
430
431 break;
432 /* PACI packet */
433 case 50:
434 /* Temporal scalability control information (TSCI) */
435 avpriv_report_missing_feature(ctx, "PACI packets for RTP/HEVC\n");
436 res = AVERROR_PATCHWELCOME;
437 break;
438 }
439
440 pkt->stream_index = st->index;
441
442 return res;
443}
444
445RTPDynamicProtocolHandler ff_hevc_dynamic_handler = {
2ba45a60
DM
446 .enc_name = "H265",
447 .codec_type = AVMEDIA_TYPE_VIDEO,
448 .codec_id = AV_CODEC_ID_HEVC,
449 .init = hevc_init,
450 .parse_sdp_a_line = hevc_parse_sdp_line,
451 .alloc = hevc_new_context,
452 .free = hevc_free_context,
453 .parse_packet = hevc_handle_packet
454};