1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef A_RTP_ASSEMBLER_H_
18 
19 #define A_RTP_ASSEMBLER_H_
20 
21 #include <media/stagefright/foundation/ABase.h>
22 #include <media/stagefright/foundation/ABuffer.h>
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/foundation/AMessage.h>
25 #include <utils/List.h>
26 #include <utils/RefBase.h>
27 
28 namespace android {
29 
30 struct ABuffer;
31 struct ARTPSource;
32 
33 struct ARTPAssembler : public RefBase {
34     enum AssemblyStatus {
35         MALFORMED_PACKET,
36         WRONG_SEQUENCE_NUMBER,
37         NOT_ENOUGH_DATA,
38         OK
39     };
40 
41     ARTPAssembler();
42 
43     void onPacketReceived(const sp<ARTPSource> &source);
44     virtual void onByeReceived() = 0;
initCheckARTPAssembler45     virtual bool initCheck() { return true; }
46 
47     // Utility functions
48     inline int64_t findRTPTime(const uint32_t& firstRTPTime, const sp<ABuffer>& buffer);
49     inline int64_t MsToRtp(int64_t ms, int64_t clockRate);
50     inline int64_t RtpToMs(int64_t rtp, int64_t clockRate);
51     inline void printNowTimeMs(int64_t start, int64_t now, int64_t play);
52     inline void printRTPTime(int64_t rtp, int64_t play, int64_t exp, bool isExp);
53 
54 protected:
55     virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source) = 0;
56     virtual void packetLost() = 0;
57 
58     static void CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from);
59 
60     static sp<ABuffer> MakeADTSCompoundFromAACFrames(
61             unsigned profile,
62             unsigned samplingFreqIndex,
63             unsigned channelConfig,
64             const List<sp<ABuffer> > &frames);
65 
66     static sp<ABuffer> MakeCompoundFromPackets(
67             const List<sp<ABuffer> > &frames);
68 
69     void showCurrentQueue(List<sp<ABuffer> > *queue);
70 
71     bool mShowQueue;
72     int32_t mShowQueueCnt;
73 
74 private:
75     int64_t mFirstFailureTimeUs;
76 
77     DISALLOW_EVIL_CONSTRUCTORS(ARTPAssembler);
78 };
79 
findRTPTime(const uint32_t & firstRTPTime,const sp<ABuffer> & buffer)80 inline int64_t ARTPAssembler::findRTPTime(const uint32_t& firstRTPTime, const sp<ABuffer>& buffer) {
81     /* If you want to +,-,* rtpTime, recommend to declare rtpTime as int64_t.
82        Because rtpTime can be near UINT32_MAX. Beware the overflow. */
83     int64_t rtpTime = 0;
84     CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
85     // If the first overs 2^31 and rtp unders 2^31, the rtp value is overflowed one.
86     int64_t overflowMask = (firstRTPTime & 0x80000000 & ~rtpTime) << 1;
87     return rtpTime | overflowMask;
88 }
89 
MsToRtp(int64_t ms,int64_t clockRate)90 inline int64_t ARTPAssembler::MsToRtp(int64_t ms, int64_t clockRate) {
91     return ms * clockRate / 1000;
92 }
93 
RtpToMs(int64_t rtp,int64_t clockRate)94 inline int64_t ARTPAssembler::RtpToMs(int64_t rtp, int64_t clockRate) {
95     return rtp * 1000 / clockRate;
96 }
97 
printNowTimeMs(int64_t start,int64_t now,int64_t play)98 inline void ARTPAssembler::printNowTimeMs(int64_t start, int64_t now, int64_t play) {
99     ALOGD("start=%lld, now=%lld, played=%lld",
100             (long long)start, (long long)now, (long long)play);
101 }
102 
printRTPTime(int64_t rtp,int64_t play,int64_t exp,bool isExp)103 inline void ARTPAssembler::printRTPTime(int64_t rtp, int64_t play, int64_t exp, bool isExp) {
104     ALOGD("rtp-time(JB)=%lld, played-rtp-time(JB)=%lld, expired-rtp-time(JB)=%lld expired=%d",
105             (long long)rtp, (long long)play, (long long)exp, isExp);
106 }
107 
108 struct ReceptionReportBlock : public RefBase {
109     uint32_t ssrc;       // ssrc of data source being reported
110     uint32_t fraction;   // fraction lost since last SR/RR
111     int32_t lost;        // cumul. no. pkts lost (signed!)
112     uint32_t lastSeq;    // extended last seq. no. received
113     uint32_t jitter;     // interarrival jitter
114     uint32_t lsr;        // last SR packet from this source
115     uint32_t dlsr;       // delay since last SR packet
116 
ReceptionReportBlockReceptionReportBlock117     ReceptionReportBlock(uint32_t ssrc, uint32_t fraction, int32_t lost, uint32_t lastSeq,
118             uint32_t jitter, uint32_t lsr, uint32_t dlsr) {
119         this->ssrc = ssrc;
120         this->fraction = fraction;
121         this->lost = lost;
122         this->lastSeq = lastSeq;
123         this->jitter = jitter;
124         this->lsr = lsr;
125         this->dlsr = dlsr;
126     }
127 };
128 
129 }  // namespace android
130 
131 #endif  // A_RTP_ASSEMBLER_H_
132