• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     rtpSort_[pt]->InputRtp(TRACK_VIDEO, (unsigned char *)data, len);
63 }
64 
SetOnRtpUnpack(const OnRtpUnpack & cb)65 void RtpUnpackImpl::SetOnRtpUnpack(const OnRtpUnpack &cb)
66 {
67     onRtpUnpack_ = std::move(cb);
68 }
69 
SetOnRtpNotify(const OnRtpNotify & cb)70 void RtpUnpackImpl::SetOnRtpNotify(const OnRtpNotify &cb)
71 {
72     onRtpNotify_ = std::move(cb);
73 }
74 
OnRtpSorted(uint16_t seq,const RtpPacket::Ptr & rtp)75 void RtpUnpackImpl::OnRtpSorted(uint16_t seq, const RtpPacket::Ptr &rtp)
76 {
77     RETURN_IF_NULL(rtp);
78     if (rtpDecoder_[rtp->GetHeader()->pt_]) {
79         MEDIA_LOGD("rtpUnpackImpl::OnRtpSorted seq: %{public}d, pt: %{public}d.", rtp->GetSeq(), rtp->GetHeader()->pt_);
80 
81         if (nextOutSeq_ == 0xffff) {
82             nextOutSeq_ = 1;
83         } else {
84             nextOutSeq_ = rtp->GetSeq() + 1;
85         }
86 
87         rtpDecoder_[rtp->GetHeader()->pt_]->InputRtp(rtp);
88     }
89 }
90 
OnRtpDecode(int32_t pt,const Frame::Ptr & frame)91 void RtpUnpackImpl::OnRtpDecode(int32_t pt, const Frame::Ptr &frame)
92 {
93     if (onRtpUnpack_) {
94         onRtpUnpack_(rtpSort_[pt]->GetSSRC(), frame);
95     }
96 }
97 
Release()98 void RtpUnpackImpl::Release()
99 {
100     rtpDecoder_.clear();
101     rtpSort_.clear();
102 }
103 
CreateRtpDecoder(const RtpPlaylodParam & rpp)104 void RtpUnpackImpl::CreateRtpDecoder(const RtpPlaylodParam &rpp)
105 {
106     switch (rpp.ps_) {
107         case RtpPayloadStream::H264:
108             rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderH264>();
109             break;
110         case RtpPayloadStream::MPEG4_GENERIC:
111             rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderAAC>(rpp);
112             break;
113         case RtpPayloadStream::PCMA: // fall-through
114         case RtpPayloadStream::PCMU:
115             rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderG711>();
116             break;
117         case RtpPayloadStream::MPEG2_TS:
118             rtpDecoder_[rpp.pt_] = std::make_shared<RtpDecoderTs>();
119             break;
120         case RtpPayloadStream::MPEG2_PS:
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