d3d12: Encode H264/HEVC - Do not write PPS unless different from active
authorSil Vilerino <sivileri@microsoft.com>
Thu, 23 Mar 2023 14:56:14 +0000 (10:56 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 23 Mar 2023 18:15:44 +0000 (18:15 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22091>

src/gallium/drivers/d3d12/d3d12_video_enc.h
src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp
src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp
src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_h264.h
src/gallium/drivers/d3d12/d3d12_video_encoder_bitstream_builder_hevc.h

index 9a9c40b..7c5b23a 100644 (file)
@@ -259,6 +259,7 @@ struct d3d12_video_encoder
    };
 
    std::vector<uint8_t> m_BitstreamHeadersBuffer;
+   std::vector<uint8_t> m_StagingHeadersBuffer;
    std::vector<EncodedBitstreamResolvedMetadata> m_spEncodedFrameMetadata;
 
    struct D3D12EncodeCapabilities m_currentEncodeCapabilities = {};
index 9b5ee0e..37b7eab 100644 (file)
@@ -860,10 +860,21 @@ d3d12_video_encoder_build_codec_headers_h264(struct d3d12_video_encoder *pD3D12E
                                     *currentPicParams.pH264PicData,
                                     currentPicParams.pH264PicData->pic_parameter_set_id,
                                     active_seq_parameter_set_id,
-                                    pD3D12Enc->m_BitstreamHeadersBuffer,
-                                    pD3D12Enc->m_BitstreamHeadersBuffer.begin() + writtenSPSBytesCount,
+                                    pD3D12Enc->m_StagingHeadersBuffer,
+                                    pD3D12Enc->m_StagingHeadersBuffer.begin(),
                                     writtenPPSBytesCount);
 
+   std::vector<uint8_t>& active_pps = pH264BitstreamBuilder->get_active_pps();
+   if ( (writtenPPSBytesCount != active_pps.size()) ||
+         memcmp(pD3D12Enc->m_StagingHeadersBuffer.data(), active_pps.data(), writtenPPSBytesCount)) {
+      active_pps = pD3D12Enc->m_StagingHeadersBuffer;
+      pD3D12Enc->m_BitstreamHeadersBuffer.resize(writtenSPSBytesCount + writtenPPSBytesCount);
+      memcpy(&pD3D12Enc->m_BitstreamHeadersBuffer.data()[writtenSPSBytesCount], pD3D12Enc->m_StagingHeadersBuffer.data(), writtenPPSBytesCount);
+   } else {
+      writtenPPSBytesCount = 0;
+      debug_printf("Skipping PPS (same as active PPS) for fenceValue: %" PRIu64 "\n", pD3D12Enc->m_fenceValue);
+   }
+
    // Shrink buffer to fit the headers
    if (pD3D12Enc->m_BitstreamHeadersBuffer.size() > (writtenPPSBytesCount + writtenSPSBytesCount)) {
       pD3D12Enc->m_BitstreamHeadersBuffer.resize(writtenPPSBytesCount + writtenSPSBytesCount);
index 5865a46..004d39a 100644 (file)
@@ -792,15 +792,26 @@ d3d12_video_encoder_build_codec_headers_hevc(struct d3d12_video_encoder *pD3D12E
    }
 
    size_t writtenPPSBytesCount = 0;
-   
+
    pHEVCBitstreamBuilder->build_pps(pHEVCBitstreamBuilder->get_latest_sps(),
                                     currentPicParams.pHEVCPicData->slice_pic_parameter_set_id,
                                     *codecConfigDesc.pHEVCConfig,
                                     *currentPicParams.pHEVCPicData,
-                                    pD3D12Enc->m_BitstreamHeadersBuffer,
-                                    pD3D12Enc->m_BitstreamHeadersBuffer.begin() + writtenSPSBytesCount + writtenVPSBytesCount,
+                                    pD3D12Enc->m_StagingHeadersBuffer,
+                                    pD3D12Enc->m_StagingHeadersBuffer.begin(),
                                     writtenPPSBytesCount);
 
+   std::vector<uint8_t>& active_pps = pHEVCBitstreamBuilder->get_active_pps();
+   if ( (writtenPPSBytesCount != active_pps.size()) ||
+         memcmp(pD3D12Enc->m_StagingHeadersBuffer.data(), active_pps.data(), writtenPPSBytesCount)) {
+      active_pps = pD3D12Enc->m_StagingHeadersBuffer;
+      pD3D12Enc->m_BitstreamHeadersBuffer.resize(writtenSPSBytesCount + writtenVPSBytesCount + writtenPPSBytesCount);
+      memcpy(&pD3D12Enc->m_BitstreamHeadersBuffer.data()[(writtenSPSBytesCount + writtenVPSBytesCount)], pD3D12Enc->m_StagingHeadersBuffer.data(), writtenPPSBytesCount);
+   } else {
+      writtenPPSBytesCount = 0;
+      debug_printf("Skipping PPS (same as active PPS) for fenceValue: %" PRIu64 "\n", pD3D12Enc->m_fenceValue);
+   }
+
    // Shrink buffer to fit the headers
    if (pD3D12Enc->m_BitstreamHeadersBuffer.size() > (writtenPPSBytesCount + writtenSPSBytesCount + writtenVPSBytesCount)) {
       pD3D12Enc->m_BitstreamHeadersBuffer.resize(writtenPPSBytesCount + writtenSPSBytesCount + writtenVPSBytesCount);
index ca569a2..c44eb18 100644 (file)
@@ -66,9 +66,6 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
    void print_pps(const H264_PPS &pps);
    void print_sps(const H264_SPS &sps);
 
-   uint32_t m_activeSPSIndex = 0;
-   uint32_t m_activePPSIndex = 0;
-
    uint32_t get_active_sps_id()
    {
       return m_activeSPSIndex;
@@ -78,6 +75,11 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
       return m_activePPSIndex;
    };
 
+   std::vector<uint8_t>& get_active_pps()
+   {
+      return m_activePPS;
+   };
+
    void set_active_sps_id(uint32_t active_sps_id)
    {
       m_activeSPSIndex = active_sps_id;
@@ -91,6 +93,9 @@ class d3d12_video_bitstream_builder_h264 : public d3d12_video_bitstream_builder_
 
  private:
    d3d12_video_nalu_writer_h264 m_h264Encoder;
+   std::vector<uint8_t> m_activePPS;
+   uint32_t m_activeSPSIndex = 0;
+   uint32_t m_activePPSIndex = 0;
 };
 
 #endif
index 6eb80c1..e2487c1 100644 (file)
@@ -79,12 +79,10 @@ class d3d12_video_bitstream_builder_hevc : public d3d12_video_bitstream_builder_
    void print_pps(const HevcPicParameterSet& pps);
    void print_rps(const HevcSeqParameterSet* sps, UINT stRpsIdx);
 
-   uint32_t m_activeVPSIndex = 0;
-   uint32_t m_activeSPSIndex = 0;
-   uint32_t m_activePPSIndex = 0;
-   HevcVideoParameterSet m_latest_vps = {};
-   HevcSeqParameterSet m_latest_sps = {};
-   HevcPicParameterSet m_latest_pps = {};
+   std::vector<uint8_t>& get_active_pps()
+   {
+      return m_activePPS;
+   };
 
    HevcVideoParameterSet get_latest_vps()
    {
@@ -133,6 +131,13 @@ class d3d12_video_bitstream_builder_hevc : public d3d12_video_bitstream_builder_
 
  private:
    d3d12_video_nalu_writer_hevc m_hevcEncoder;
+   uint32_t m_activeVPSIndex = 0;
+   uint32_t m_activeSPSIndex = 0;
+   uint32_t m_activePPSIndex = 0;
+   HevcVideoParameterSet m_latest_vps = {};
+   HevcSeqParameterSet m_latest_sps = {};
+   HevcPicParameterSet m_latest_pps = {};
+   std::vector<uint8_t> m_activePPS;
 
    void init_profile_tier_level(HEVCProfileTierLevel *ptl, uint8_t HEVCProfileIdc, uint8_t HEVCLevelIdc, bool isHighTier);
 };