> Your patches contain a lot of trailing whitespace (afaict...) > that cannot be committed to our repository, please remove it.
Thanks for pointing this out. I've attached new patches to fix this problem. patcheck complains about my non-doxy comments, and about possible unused variables. Variables are definitely being used. Is the etiquette to remove all comments? Also, I added a Changelog entry for the RTP depacketization of SVC as patcheck suggested. Joshua Breeden
From 61109072b7c83974e3945bcdba0505034b1e62aa Mon Sep 17 00:00:00 2001 From: Joshua Breeden <jbree...@me.com> Date: Wed, 1 Nov 2017 11:15:21 -0400 Subject: [PATCH 1/2] Parse NAL type 15 (subset SPS) in H.264 extradata --- libavcodec/h264.h | 1 + libavcodec/h264_parse.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 650580bf3a..cffcda7d92 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -41,6 +41,7 @@ enum { H264_NAL_END_STREAM = 11, H264_NAL_FILLER_DATA = 12, H264_NAL_SPS_EXT = 13, + H264_NAL_SUBSET_SPS = 15, H264_NAL_AUXILIARY_SLICE = 19, }; diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index a7c71d9bbb..f771600c3e 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -372,6 +372,12 @@ static int decode_extradata_ps(const uint8_t *data, int size, H264ParamSets *ps, if (ret < 0) goto fail; break; + case H264_NAL_SUBSET_SPS: + ret = ff_h264_decode_seq_parameter_set(&nal->gb, logctx, ps, 0); + + if (ret < 0) + goto fail; + break; default: av_log(logctx, AV_LOG_VERBOSE, "Ignoring NAL type %d in extradata\n", nal->type); -- 2.11.0
From ad0571ed5fb4fbd751891f07f40c4e206ebbe0d1 Mon Sep 17 00:00:00 2001 From: Joshua Breeden <jbree...@me.com> Date: Wed, 1 Nov 2017 11:16:19 -0400 Subject: [PATCH 2/2] Add support for non-interleaved H.264/SVC over RTP --- Changelog | 2 +- libavformat/rtpdec.c | 1 + libavformat/rtpdec_formats.h | 1 + libavformat/rtpdec_h264.c | 80 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 8c45b2946d..8c3a1683a2 100644 --- a/Changelog +++ b/Changelog @@ -7,7 +7,7 @@ version <next>: requires 2.1 (or later) and pkg-config. - VDA dropped (use VideoToolbox instead) - MagicYUV encoder - +- RTP depacketization of non-interleaved H.264/SVC (RFC 6190) version 3.4: - deflicker video filter diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 4acb1ca629..1c5814749a 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -96,6 +96,7 @@ void ff_register_rtp_dynamic_payload_handlers(void) ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_h264_svc_dynamic_handler); ff_register_dynamic_payload_handler(&ff_hevc_dynamic_handler); ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler); ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler); diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h index a436c9d62c..b67d1e338f 100644 --- a/libavformat/rtpdec_formats.h +++ b/libavformat/rtpdec_formats.h @@ -64,6 +64,7 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler; extern RTPDynamicProtocolHandler ff_h264_dynamic_handler; +extern RTPDynamicProtocolHandler ff_h264_svc_dynamic_handler; extern RTPDynamicProtocolHandler ff_hevc_dynamic_handler; extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler; extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler; diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c index 6f8148ab6d..485a494892 100644 --- a/libavformat/rtpdec_h264.c +++ b/libavformat/rtpdec_h264.c @@ -308,6 +308,69 @@ static int h264_handle_packet_fu_a(AVFormatContext *ctx, PayloadContext *data, A return ff_h264_handle_frag_packet(pkt, buf, len, start_bit, &nal, 1); } +static int h264_handle_packet_pacsi(AVFormatContext *ctx, PayloadContext *data, AVPacket *pkt, + const uint8_t *buf, int len, + int *nal_counters, int nal_mask) +{ + uint8_t *dst = NULL; + const uint8_t *src = buf; + int src_len = len; + int total_length = 0; + int ret; + int y, t; + int opt_offset; + + if (len < 5) + return AVERROR_INVALIDDATA; + + // skip some NAL header info + src += 4; + src_len -= 4; + + // skip optional fields if present + y = (src[0] >> 6) & 1; + t = (src[0] >> 5) & 1; + // 3 bytes indicated by y, 2 bytes for t, and skip over current byte + opt_offset = y * 3 + t * 2 + 1; + src += opt_offset; + src_len -= opt_offset; + + // calculate size of NALs plus start codes + while (src_len > 2) { + uint16_t nal_size = AV_RB16(src); + + total_length += sizeof(start_sequence) + nal_size; + src += 2 + nal_size; + src_len -= 2 + nal_size; + } + + // create packet to hold NALs, reset buffer to first NAL + if ((ret = av_new_packet(pkt, total_length)) < 0) + return ret; + dst = pkt->data; + src = buf + 4 + opt_offset; + src_len = len - 4 - opt_offset; + + while (src_len > 2) { + uint16_t nal_size = AV_RB16(src); + src += 2; + src_len -= 2; + // copying + memcpy(dst, start_sequence, sizeof(start_sequence)); + dst += sizeof(start_sequence); + memcpy(dst, src, nal_size); + if (nal_counters) + nal_counters[(*src) & nal_mask]++; + dst += nal_size; + + // eat what we handled + src += nal_size; + src_len -= nal_size; + } + + return 0; +} + // return 0 on packet, no more left, 1 on packet, 1 on partial packet static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, @@ -360,7 +423,11 @@ static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, NAL_COUNTERS, NAL_MASK); break; - case 30: // undefined + case 30: // PACSI (Annex G - SVC) + result = h264_handle_packet_pacsi(ctx, data, pkt, buf, len, + NAL_COUNTERS, NAL_MASK); + break; + case 31: // undefined default: av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type); @@ -418,3 +485,14 @@ RTPDynamicProtocolHandler ff_h264_dynamic_handler = { .close = h264_close_context, .parse_packet = h264_handle_packet, }; + +RTPDynamicProtocolHandler ff_h264_svc_dynamic_handler = { + .enc_name = "H264-SVC", + .codec_type = AVMEDIA_TYPE_VIDEO, + .codec_id = AV_CODEC_ID_H264, + .need_parsing = AVSTREAM_PARSE_FULL, + .priv_data_size = sizeof(PayloadContext), + .parse_sdp_a_line = parse_h264_sdp_line, + .close = h264_close_context, + .parse_packet = h264_handle_packet, +}; -- 2.11.0
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel