• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  *
10  */
11 
12 #ifndef SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_NALU_REWRITER_H_
13 #define SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_NALU_REWRITER_H_
14 
15 #include "modules/video_coding/codecs/h264/include/h264.h"
16 
17 #include <CoreMedia/CoreMedia.h>
18 #include <vector>
19 
20 #include "common_video/h264/h264_common.h"
21 #include "rtc_base/buffer.h"
22 
23 using webrtc::H264::NaluIndex;
24 
25 namespace webrtc {
26 
27 // Converts a sample buffer emitted from the VideoToolbox encoder into a buffer
28 // suitable for RTP. The sample buffer is in avcc format whereas the rtp buffer
29 // needs to be in Annex B format. Data is written directly to `annexb_buffer`.
30 bool H264CMSampleBufferToAnnexBBuffer(CMSampleBufferRef avcc_sample_buffer,
31                                       bool is_keyframe,
32                                       rtc::Buffer* annexb_buffer);
33 
34 // Converts a buffer received from RTP into a sample buffer suitable for the
35 // VideoToolbox decoder. The RTP buffer is in annex b format whereas the sample
36 // buffer is in avcc format.
37 // If `is_keyframe` is true then `video_format` is ignored since the format will
38 // be read from the buffer. Otherwise `video_format` must be provided.
39 // Caller is responsible for releasing the created sample buffer.
40 bool H264AnnexBBufferToCMSampleBuffer(const uint8_t* annexb_buffer,
41                                       size_t annexb_buffer_size,
42                                       CMVideoFormatDescriptionRef video_format,
43                                       CMSampleBufferRef* out_sample_buffer,
44                                       CMMemoryPoolRef memory_pool);
45 
46 // Returns a video format description created from the sps/pps information in
47 // the Annex B buffer. If there is no such information, nullptr is returned.
48 // The caller is responsible for releasing the description.
49 CMVideoFormatDescriptionRef CreateVideoFormatDescription(
50     const uint8_t* annexb_buffer,
51     size_t annexb_buffer_size);
52 
53 // Helper class for reading NALUs from an RTP Annex B buffer.
54 class AnnexBBufferReader final {
55  public:
56   AnnexBBufferReader(const uint8_t* annexb_buffer, size_t length);
57   ~AnnexBBufferReader();
58   AnnexBBufferReader(const AnnexBBufferReader& other) = delete;
59   void operator=(const AnnexBBufferReader& other) = delete;
60 
61   // Returns a pointer to the beginning of the next NALU slice without the
62   // header bytes and its length. Returns false if no more slices remain.
63   bool ReadNalu(const uint8_t** out_nalu, size_t* out_length);
64 
65   // Returns the number of unread NALU bytes, including the size of the header.
66   // If the buffer has no remaining NALUs this will return zero.
67   size_t BytesRemaining() const;
68 
69   // Reset the reader to start reading from the first NALU
70   void SeekToStart();
71 
72   // Seek to the next position that holds a NALU of the desired type,
73   // or the end if no such NALU is found.
74   // Return true if a NALU of the desired type is found, false if we
75   // reached the end instead
76   bool SeekToNextNaluOfType(H264::NaluType type);
77 
78  private:
79   // Returns the the next offset that contains NALU data.
80   size_t FindNextNaluHeader(const uint8_t* start,
81                             size_t length,
82                             size_t offset) const;
83 
84   const uint8_t* const start_;
85   std::vector<NaluIndex> offsets_;
86   std::vector<NaluIndex>::iterator offset_;
87   const size_t length_;
88 };
89 
90 // Helper class for writing NALUs using avcc format into a buffer.
91 class AvccBufferWriter final {
92  public:
93   AvccBufferWriter(uint8_t* const avcc_buffer, size_t length);
~AvccBufferWriter()94   ~AvccBufferWriter() {}
95   AvccBufferWriter(const AvccBufferWriter& other) = delete;
96   void operator=(const AvccBufferWriter& other) = delete;
97 
98   // Writes the data slice into the buffer. Returns false if there isn't
99   // enough space left.
100   bool WriteNalu(const uint8_t* data, size_t data_size);
101 
102   // Returns the unused bytes in the buffer.
103   size_t BytesRemaining() const;
104 
105  private:
106   uint8_t* const start_;
107   size_t offset_;
108   const size_t length_;
109 };
110 
111 }  // namespace webrtc
112 
113 #endif  // SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_NALU_REWRITER_H_
114