1 /*
2  *  Copyright (c) 2014 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 #ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H264_H_
12 #define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H264_H_
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 #include <deque>
18 #include <memory>
19 #include <queue>
20 
21 #include "api/array_view.h"
22 #include "modules/rtp_rtcp/source/rtp_format.h"
23 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
24 #include "modules/video_coding/codecs/h264/include/h264_globals.h"
25 #include "rtc_base/buffer.h"
26 #include "rtc_base/constructor_magic.h"
27 
28 namespace webrtc {
29 
30 class RtpPacketizerH264 : public RtpPacketizer {
31  public:
32   // Initialize with payload from encoder.
33   // The payload_data must be exactly one encoded H264 frame.
34   RtpPacketizerH264(rtc::ArrayView<const uint8_t> payload,
35                     PayloadSizeLimits limits,
36                     H264PacketizationMode packetization_mode);
37 
38   ~RtpPacketizerH264() override;
39 
40   size_t NumPackets() const override;
41 
42   // Get the next payload with H264 payload header.
43   // Write payload and set marker bit of the |packet|.
44   // Returns true on success, false otherwise.
45   bool NextPacket(RtpPacketToSend* rtp_packet) override;
46 
47  private:
48   // A packet unit (H264 packet), to be put into an RTP packet:
49   // If a NAL unit is too large for an RTP packet, this packet unit will
50   // represent a FU-A packet of a single fragment of the NAL unit.
51   // If a NAL unit is small enough to fit within a single RTP packet, this
52   // packet unit may represent a single NAL unit or a STAP-A packet, of which
53   // there may be multiple in a single RTP packet (if so, aggregated = true).
54   struct PacketUnit {
PacketUnitPacketUnit55     PacketUnit(rtc::ArrayView<const uint8_t> source_fragment,
56                bool first_fragment,
57                bool last_fragment,
58                bool aggregated,
59                uint8_t header)
60         : source_fragment(source_fragment),
61           first_fragment(first_fragment),
62           last_fragment(last_fragment),
63           aggregated(aggregated),
64           header(header) {}
65 
66     rtc::ArrayView<const uint8_t> source_fragment;
67     bool first_fragment;
68     bool last_fragment;
69     bool aggregated;
70     uint8_t header;
71   };
72 
73   bool GeneratePackets(H264PacketizationMode packetization_mode);
74   bool PacketizeFuA(size_t fragment_index);
75   size_t PacketizeStapA(size_t fragment_index);
76   bool PacketizeSingleNalu(size_t fragment_index);
77 
78   void NextAggregatePacket(RtpPacketToSend* rtp_packet);
79   void NextFragmentPacket(RtpPacketToSend* rtp_packet);
80 
81   const PayloadSizeLimits limits_;
82   size_t num_packets_left_;
83   std::deque<rtc::ArrayView<const uint8_t>> input_fragments_;
84   std::queue<PacketUnit> packets_;
85 
86   RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerH264);
87 };
88 }  // namespace webrtc
89 #endif  // MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H264_H_
90