[FFmpeg-devel] [PATCH] mp4: Support writing declarative SEis to hvcC

Vittorio Giovara vittorio.giovara at gmail.com
Thu Aug 17 14:54:44 EEST 2017


Signed-off-by: Vittorio Giovara <vittorio.giovara at gmail.com>
---
Right now only one SEI type is added, there could be more declarative
ones, but I'm not sure how to properly identify them.
Also, the way to check for the seiPayloadType could be improved,
suggestions are welcome.
Vittorio

 libavcodec/extract_extradata_bsf.c |  1 +
 libavformat/hevc.c                 | 28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c
index 4cd0ca1137..e0d8aa99b5 100644
--- a/libavcodec/extract_extradata_bsf.c
+++ b/libavcodec/extract_extradata_bsf.c
@@ -54,6 +54,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
 {
     static const int extradata_nal_types_hevc[] = {
         HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS,
+        HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX,
     };
     static const int extradata_nal_types_h264[] = {
         H264_NAL_SPS, H264_NAL_PPS,
diff --git a/libavformat/hevc.c b/libavformat/hevc.c
index 1a2d6cdd2b..9ff2b858dd 100644
--- a/libavformat/hevc.c
+++ b/libavformat/hevc.c
@@ -22,6 +22,7 @@
 #include "libavcodec/get_bits.h"
 #include "libavcodec/golomb.h"
 #include "libavcodec/hevc.h"
+#include "libavcodec/hevc_sei.h"
 #include "libavutil/intreadwrite.h"
 #include "avc.h"
 #include "avio.h"
@@ -763,17 +764,10 @@ static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size,
 
     nal_unit_parse_header(&gbc, &nal_type);
 
-    /*
-     * Note: only 'declarative' SEI messages are allowed in
-     * hvcC. Perhaps the SEI playload type should be checked
-     * and non-declarative SEI messages discarded?
-     */
     switch (nal_type) {
     case HEVC_NAL_VPS:
     case HEVC_NAL_SPS:
     case HEVC_NAL_PPS:
-    case HEVC_NAL_SEI_PREFIX:
-    case HEVC_NAL_SEI_SUFFIX:
         ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type,
                                       ps_array_completeness, hvcc);
         if (ret < 0)
@@ -787,6 +781,15 @@ static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size,
         if (ret < 0)
             goto end;
         break;
+    case HEVC_NAL_SEI_PREFIX:
+    case HEVC_NAL_SEI_SUFFIX:
+        if (nal_size > 2 && *(nal_buf + 2) == HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO) {
+            ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type,
+                                          ps_array_completeness, hvcc);
+            if (ret < 0)
+                goto end;
+        }
+        break;
     default:
         ret = AVERROR_INVALIDDATA;
         goto end;
@@ -835,6 +838,7 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc)
 {
     uint8_t i;
     uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0;
+    int sei_prefix_count = 0, sei_suffix_count = 0;
 
     /*
      * We only support writing HEVCDecoderConfigurationRecord version 1.
@@ -925,12 +929,20 @@ static int hvcc_write(AVIOContext *pb, HEVCDecoderConfigurationRecord *hvcc)
         case HEVC_NAL_PPS:
             pps_count += hvcc->array[i].numNalus;
             break;
+        case HEVC_NAL_SEI_PREFIX:
+            sei_suffix_count += hvcc->array[i].numNalus;
+            break;
+        case HEVC_NAL_SEI_SUFFIX:
+            sei_prefix_count += hvcc->array[i].numNalus;
+            break;
         default:
             break;
         }
     if (!vps_count || vps_count > HEVC_MAX_VPS_COUNT ||
         !sps_count || sps_count > HEVC_MAX_SPS_COUNT ||
-        !pps_count || pps_count > HEVC_MAX_PPS_COUNT)
+        !pps_count || pps_count > HEVC_MAX_PPS_COUNT ||
+        sei_prefix_count > UINT16_MAX ||
+        sei_suffix_count > UINT16_MAX)
         return AVERROR_INVALIDDATA;
 
     /* unsigned int(8) configurationVersion = 1; */
-- 
2.13.2



More information about the ffmpeg-devel mailing list