1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "rtp_unpack_impl.h"
17 #include <arpa/inet.h>
18 #include <chrono>
19 #include "common/common_macro.h"
20 #include "common/media_log.h"
21 #include "rtp_codec_aac.h"
22 #include "rtp_codec_g711.h"
23 #include "rtp_codec_h264.h"
24 #include "rtp_codec_ts.h"
25
26 namespace OHOS {
27 namespace Sharing {
RtpUnpackImpl(const RtpPlaylodParam & rpp)28 RtpUnpackImpl::RtpUnpackImpl(const RtpPlaylodParam &rpp)
29 {
30 CreateRtpDecoder(rpp);
31 }
32
~RtpUnpackImpl()33 RtpUnpackImpl::~RtpUnpackImpl()
34 {
35 SHARING_LOGI("~RtpUnpackImpl.");
36 Release();
37 }
38
ParseRtp(const char * data,size_t len)39 void RtpUnpackImpl::ParseRtp(const char *data, size_t len)
40 {
41 RETURN_IF_NULL(data);
42 RtpHeader *header = (RtpHeader *)data;
43 auto pt = header->pt_;
44 auto decoder = rtpDecoder_[pt];
45
46 if (!decoder) {
47 if (rtpDecoder_.size() > 2) { // 2:fixed size
48 return;
49 }
50 switch (pt) {
51 case 33: { // 33:mpeg-2 ts code
52 // todo judge ps/ts
53 CreateRtpDecoder(RtpPlaylodParam{pt, 90000, RtpPayloadStream::MPEG2_TS}); // 90000:audio clock cycle
54 break;
55 }
56 default:
57 // todo not support this pt
58 return;
59 }
60 }
61
62 if (rtpSort_[pt]) {
63 rtpSort_[pt]->InputRtp(TRACK_VIDEO, (unsigned char *)data, len);
64 }
65 }
66
SetOnRtpUnpack(const OnRtpUnpack & cb)67 void RtpUnpackImpl::SetOnRtpUnpack(const OnRtpUnpack &cb)
68 {
69 onRtpUnpack_ = std::move(cb);
70 }
71
SetOnRtpNotify(const OnRtpNotify & cb)72 void RtpUnpackImpl::SetOnRtpNotify(const OnRtpNotify &cb)
73 {
74 onRtpNotify_ = std::move(cb);
75 }
76
OnRtpSorted(uint16_t seq,const RtpPacket::Ptr & rtp)77 void RtpUnpackImpl::OnRtpSorted(uint16_t seq, const RtpPacket::Ptr &rtp)
78 {
79 RETURN_IF_NULL(rtp);
80 if (rtpDecoder_[rtp->GetHeader()->pt_]) {
81 MEDIA_LOGD("rtpUnpackImpl::OnRtpSorted seq: %{public}d, pt: %{public}d.", rtp->GetSeq(), rtp->GetHeader()->pt_);
82
83 if (nextOutSeq_ == 0xffff) {
84 nextOutSeq_ = 1;
85 } else {
86 nextOutSeq_ = rtp->GetSeq() + 1;
87 }
88
89 rtpDecoder_[rtp->GetHeader()->pt_]->InputRtp(rtp);
90 }
91 }
92
OnRtpDecode(int32_t pt,const Frame::Ptr & frame)93 void RtpUnpackImpl::OnRtpDecode(int32_t pt, const Frame::Ptr &frame)
94 {
95 if (onRtpUnpack_) {
96 onRtpUnpack_(rtpSort_[pt]->GetSSRC(), frame);
97 }
98 }
99
Release()100 void RtpUnpackImpl::Release()
101 {
102 rtpDecoder_.clear();
103 rtpSort_.clear();
104 }
105
CreateRtpDecoder(const RtpPlaylodParam & rpp)106 void RtpUnpackImpl::CreateRtpDecoder(const RtpPlaylodParam &rpp)
107 {
108 switch (rpp.ps_) {
109 case RtpPayloadStream::H264:
110 rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderH264>();
111 break;
112 case RtpPayloadStream::MPEG4_GENERIC:
113 rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderAAC>(rpp);
114 break;
115 case RtpPayloadStream::PCMA: // fall-through
116 case RtpPayloadStream::PCMU:
117 rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderG711>();
118 break;
119 case RtpPayloadStream::MPEG2_TS:
120 rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderTs>();
121 break;
122 default:
123 // todo log
124 break;
125 }
126 if (rtpDecoder_[rpp.pt_]) {
127 auto &ref = rtpSort_[rpp.pt_];
128 ref = std::make_shared<RtpPacketSortor>(rpp.sampleRate_);
129 ref->SetOnSort(std::bind(&RtpUnpackImpl::OnRtpSorted, this, std::placeholders::_1, std::placeholders::_2));
130 rtpDecoder_[rpp.pt_]->SetOnFrame(std::bind(&RtpUnpackImpl::OnRtpDecode, this, rpp.pt_, std::placeholders::_1));
131 }
132 }
133 } // namespace Sharing
134 } // namespace OHOS