summaryrefslogtreecommitdiffstats
path: root/media/filters/h264_to_annex_b_bitstream_converter.h
blob: ce5fe35c45f3c6eedebe8b75885060ec05815cc2 (plain)
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
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_
#define MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_

#include <stdint.h>

#include <vector>

#include "base/macros.h"
#include "media/base/media_export.h"

namespace media {

namespace mp4 {
struct AVCDecoderConfigurationRecord;
}

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

  // Parses the global AVCDecoderConfigurationRecord 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 AVCDecoderConfigurationRecord.
  //   configuration_record_size
  //     Size of the buffer in bytes.
  //   avc_config
  //     Pointer to place the parsed AVCDecoderConfigurationRecord data into.
  //
  // Returns
  //   Returns true if |configuration_record| was successfully parsed. False
  //   is returned if a parsing error occurred.
  //   |avc_config| only contains valid data when true is returned.
  bool ParseConfiguration(const uint8_t* configuration_record,
                          int configuration_record_size,
                          mp4::AVCDecoderConfigurationRecord* avc_config);

  // Returns the buffer size needed to store the parameter sets in |avc_config|
  // in Annex B form.
  uint32_t GetConfigSize(
      const mp4::AVCDecoderConfigurationRecord& avc_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.
  //   avc_config
  //     The AVCDecoderConfigurationRecord that contains the parameter sets that
  //     will be inserted into the output. NULL 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 |avc_config|.
  uint32_t CalculateNeededOutputBufferSize(
      const uint8_t* input,
      uint32_t input_size,
      const mp4::AVCDecoderConfigurationRecord* avc_config) const;

  // ConvertAVCDecoderConfigToByteStream converts the
  // AVCDecoderConfigurationRecord 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
  //   avc_config
  //     The AVCDecoderConfigurationRecord 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 ConvertAVCDecoderConfigToByteStream(
      const mp4::AVCDecoderConfigurationRecord& avc_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.
  //   avc_config
  //     The AVCDecoderConfigurationRecord 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::AVCDecoderConfigurationRecord* avc_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_;
  // Flag for indicating whether next NAL unit starts new access unit.
  bool first_nal_unit_in_access_unit_;
  // Variable to hold interleaving field's length in bytes.
  uint8_t nal_unit_length_field_width_;

  DISALLOW_COPY_AND_ASSIGN(H264ToAnnexBBitstreamConverter);
};

}  // namespace media

#endif  // MEDIA_FILTERS_H264_TO_ANNEX_B_BITSTREAM_CONVERTER_H_