> No but I wonder if the variables "y" and "t" can have more useful names
> (that may or may not make the comment unneeded),

I've made the variable names more self-explanatory and condensed the comments

> Please do not remove the empty line.

And fixed this as well.

Thanks,

Joshua Breeden
From 65b33b5ed716712118d6cc9a9a0b3b6c260daa03 Mon Sep 17 00:00:00 2001
From: Joshua Breeden <jbree...@me.com>
Date: Wed, 1 Nov 2017 13:27:20 -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 a592febfab5d5a7c534f6d21a42bf23289ff3ffa Mon Sep 17 00:00:00 2001
From: Joshua Breeden <jbree...@me.com>
Date: Wed, 1 Nov 2017 13:39:54 -0400
Subject: [PATCH 2/2] Add support for non-interleaved H.264 SVC over RTP

---
 Changelog                    |  1 +
 libavformat/rtpdec.c         |  1 +
 libavformat/rtpdec_formats.h |  1 +
 libavformat/rtpdec_h264.c    | 79 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/Changelog b/Changelog
index 8c45b2946d..4e816bffd4 100644
--- a/Changelog
+++ b/Changelog
@@ -7,6 +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:
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..25b67f3571 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -308,6 +308,68 @@ 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 tl0_pic_idx_bytes, donc_bytes;
+    int opt_offset;
+
+    if (len < 5)
+        return AVERROR_INVALIDDATA;
+
+    src     += 4;
+    src_len -= 4;
+
+    tl0_pic_idx_bytes = 3 * ((src[0] >> 6) & 1);
+    donc_bytes        = 2 * ((src[0] >> 5) & 1);
+
+    opt_offset = tl0_pic_idx_bytes + donc_bytes + 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
+    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;
+
+    // copy NALs with start codes
+    while (src_len > 2) {
+        uint16_t nal_size = AV_RB16(src);
+        src     += 2;
+        src_len -= 2;
+
+        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 +422,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 +484,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

Reply via email to