1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158

media / filters / h265_to_annex_b_bitstream_converter.h [blame]

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
#define MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_

#include <stdint.h>

#include <vector>

#include "media/base/media_export.h"

namespace media {

namespace mp4 {
struct HEVCDecoderConfigurationRecord;
}

// H265ToAnnexBBitstreamConverter is a class to convert H.265 bitstream from
// MP4 format (as specified in ISO/IEC 14496-15) into H.265 bytestream
// (as specified in ISO/IEC 14496-10 Annex B).
class MEDIA_EXPORT H265ToAnnexBBitstreamConverter {
 public:
  H265ToAnnexBBitstreamConverter();

  H265ToAnnexBBitstreamConverter(const H265ToAnnexBBitstreamConverter&) =
      delete;
  H265ToAnnexBBitstreamConverter& operator=(
      const H265ToAnnexBBitstreamConverter&) = delete;

  ~H265ToAnnexBBitstreamConverter();

  // Parses the global HEVCDecoderConfigurationRecord from the file format's
  // headers. Converter will remember the field length from the configuration
  // headers after this.
  //
  // Parameters
  //   configuration_record
  //     Pointer to buffer containing HEVCDecoderConfigurationRecord.
  //   configuration_record_size
  //     Size of the buffer in bytes.
  //   hevc_config
  //     Pointer to place the parsed HEVCDecoderConfigurationRecord data into.
  //
  // Returns
  //   Returns true if |configuration_record| was successfully parsed. False
  //   is returned if a parsing error occurred.
  //   |hevc_config| only contains valid data when true is returned.
  bool ParseConfiguration(const uint8_t* configuration_record,
                          int configuration_record_size,
                          mp4::HEVCDecoderConfigurationRecord* hevc_config);

  // Returns the buffer size needed to store the parameter sets in |hevc_config|
  // in Annex B form.
  uint32_t GetConfigSize(
      const mp4::HEVCDecoderConfigurationRecord& hevc_config) const;

  // Calculates needed buffer size for the bitstream converted into bytestream.
  // Lightweight implementation that does not do the actual conversion.
  //
  // Parameters
  //   input
  //     Pointer to buffer containing NAL units in MP4 format.
  //   input_size
  //     Size of the buffer in bytes.
  //   hevc_config
  //     The HEVCDecoderConfigurationRecord that contains the parameter sets
  //     that will be inserted into the output. nullptr if no parameter sets
  //     need to be inserted.
  //
  // Returns
  //   Required buffer size for the output NAL unit buffer when converted
  //   to bytestream format, or 0 if could not determine the size of
  //   the output buffer from the data in |input| and |hevc_config|.
  uint32_t CalculateNeededOutputBufferSize(
      const uint8_t* input,
      uint32_t input_size,
      const mp4::HEVCDecoderConfigurationRecord* hevc_config) const;

  // ConvertHEVCDecoderConfigToByteStream converts the
  // HEVCDecoderConfigurationRecord from the MP4 headers to bytestream format.
  // Client is responsible for making sure the output buffer is large enough
  // to hold the output data. Client can precalculate the needed output buffer
  // size by using GetConfigSize().
  //
  // Parameters
  //   hevc_config
  //     The HEVCDecoderConfigurationRecord that contains the parameter sets
  //     that will be written to |output|.
  //   output
  //     Pointer to buffer where the output should be written to.
  //   output_size (i/o)
  //     Pointer to the size of the output buffer. Will contain the number of
  //     bytes written to output after successful call.
  //
  // Returns
  //    true  if successful conversion|
  //    false if conversion not successful (|output_size| will hold the amount
  //          of converted data)
  bool ConvertHEVCDecoderConfigToByteStream(
      const mp4::HEVCDecoderConfigurationRecord& hevc_config,
      uint8_t* output,
      uint32_t* output_size);

  // ConvertNalUnitStreamToByteStream converts the NAL unit from MP4 format
  // to bytestream format. Client is responsible for making sure the output
  // buffer is large enough to hold the output data. Client can precalculate the
  // needed output buffer size by using CalculateNeededOutputBufferSize.
  //
  // Parameters
  //   input
  //     Pointer to buffer containing NAL units in MP4 format.
  //   input_size
  //     Size of the buffer in bytes.
  //   hevc_config
  //     The HEVCDecoderConfigurationRecord that contains the parameter sets to
  //     insert into the output. NULL if no parameter sets need to be inserted.
  //   output
  //     Pointer to buffer where the output should be written to.
  //   output_size (i/o)
  //     Pointer to the size of the output buffer. Will contain the number of
  //     bytes written to output after successful call.
  //
  // Returns
  //    true  if successful conversion
  //    false if conversion not successful (output_size will hold the amount
  //          of converted data)
  bool ConvertNalUnitStreamToByteStream(
      const uint8_t* input,
      uint32_t input_size,
      const mp4::HEVCDecoderConfigurationRecord* hevc_config,
      uint8_t* output,
      uint32_t* output_size);

 private:
  // Writes Annex B start code and |param_set| to |*out|.
  //  |*out| - Is the memory location to write the parameter set.
  //  |*out_size| - Number of bytes available for the parameter set.
  // Returns true if the start code and param set were successfully
  // written. On a successful write, |*out| is updated to point to the first
  // byte after the data that was written. |*out_size| is updated to reflect
  // the new number of bytes left in |*out|.
  bool WriteParamSet(const std::vector<uint8_t>& param_set,
                     uint8_t** out,
                     uint32_t* out_size) const;

  // Flag for indicating whether global parameter sets have been processed.
  bool configuration_processed_ = false;
  // Flag for indicating whether next NAL unit starts new access unit.
  bool first_nal_unit_in_access_unit_ = false;
  // Size of length headers in bytes.
  uint8_t nal_unit_length_field_width_ = 0;
};

}  // namespace media

#endif  // MEDIA_FILTERS_H265_TO_ANNEX_B_BITSTREAM_CONVERTER_H_