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 WEBRTC_MODULES_VIDEO_CODING_CODECS_H264_H264_VIDEO_TOOLBOX_NALU_H_
13 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_H264_H264_VIDEO_TOOLBOX_NALU_H_
14 
15 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
16 
17 #if defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED)
18 
19 #include <CoreMedia/CoreMedia.h>
20 
21 #include "webrtc/base/buffer.h"
22 #include "webrtc/modules/include/module_common_types.h"
23 
24 namespace webrtc {
25 
26 // Converts a sample buffer emitted from the VideoToolbox encoder into a buffer
27 // suitable for RTP. The sample buffer is in avcc format whereas the rtp buffer
28 // needs to be in Annex B format. Data is written directly to |annexb_buffer|
29 // and a new RTPFragmentationHeader is returned in |out_header|.
30 bool H264CMSampleBufferToAnnexBBuffer(
31     CMSampleBufferRef avcc_sample_buffer,
32     bool is_keyframe,
33     rtc::Buffer* annexb_buffer,
34     webrtc::RTPFragmentationHeader** out_header);
35 
36 // Converts a buffer received from RTP into a sample buffer suitable for the
37 // VideoToolbox decoder. The RTP buffer is in annex b format whereas the sample
38 // buffer is in avcc format.
39 // If |is_keyframe| is true then |video_format| is ignored since the format will
40 // be read from the buffer. Otherwise |video_format| must be provided.
41 // Caller is responsible for releasing the created sample buffer.
42 bool H264AnnexBBufferToCMSampleBuffer(const uint8_t* annexb_buffer,
43                                       size_t annexb_buffer_size,
44                                       CMVideoFormatDescriptionRef video_format,
45                                       CMSampleBufferRef* out_sample_buffer);
46 
47 // Helper class for reading NALUs from an RTP Annex B buffer.
48 class AnnexBBufferReader final {
49  public:
50   AnnexBBufferReader(const uint8_t* annexb_buffer, size_t length);
~AnnexBBufferReader()51   ~AnnexBBufferReader() {}
52   AnnexBBufferReader(const AnnexBBufferReader& other) = delete;
53   void operator=(const AnnexBBufferReader& other) = delete;
54 
55   // Returns a pointer to the beginning of the next NALU slice without the
56   // header bytes and its length. Returns false if no more slices remain.
57   bool ReadNalu(const uint8_t** out_nalu, size_t* out_length);
58 
59   // Returns the number of unread NALU bytes, including the size of the header.
60   // If the buffer has no remaining NALUs this will return zero.
61   size_t BytesRemaining() const;
62 
63  private:
64   // Returns the the next offset that contains NALU data.
65   size_t FindNextNaluHeader(const uint8_t* start,
66                             size_t length,
67                             size_t offset) const;
68 
69   const uint8_t* const start_;
70   size_t offset_;
71   size_t next_offset_;
72   const size_t length_;
73 };
74 
75 // Helper class for writing NALUs using avcc format into a buffer.
76 class AvccBufferWriter final {
77  public:
78   AvccBufferWriter(uint8_t* const avcc_buffer, size_t length);
~AvccBufferWriter()79   ~AvccBufferWriter() {}
80   AvccBufferWriter(const AvccBufferWriter& other) = delete;
81   void operator=(const AvccBufferWriter& other) = delete;
82 
83   // Writes the data slice into the buffer. Returns false if there isn't
84   // enough space left.
85   bool WriteNalu(const uint8_t* data, size_t data_size);
86 
87   // Returns the unused bytes in the buffer.
88   size_t BytesRemaining() const;
89 
90  private:
91   uint8_t* const start_;
92   size_t offset_;
93   const size_t length_;
94 };
95 
96 }  // namespace webrtc
97 
98 #endif  // defined(WEBRTC_VIDEO_TOOLBOX_SUPPORTED)
99 #endif  // WEBRTC_MODULES_VIDEO_CODING_CODECS_H264_H264_VIDEO_TOOLBOX_NALU_H_
100