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 protected:
48     virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source) = 0;
49     virtual void packetLost() = 0;
50 
51     static void CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from);
52 
53     static sp<ABuffer> MakeADTSCompoundFromAACFrames(
54             unsigned profile,
55             unsigned samplingFreqIndex,
56             unsigned channelConfig,
57             const List<sp<ABuffer> > &frames);
58 
59     static sp<ABuffer> MakeCompoundFromPackets(
60             const List<sp<ABuffer> > &frames);
61 
62     void showCurrentQueue(List<sp<ABuffer> > *queue);
63 
64     bool mShowQueue;
65     int32_t mShowQueueCnt;
66 
67     // Utility functions
68     inline int64_t findRTPTime(const uint32_t& firstRTPTime, const sp<ABuffer>& buffer);
69     inline int64_t MsToRtp(int64_t ms, int64_t clockRate);
70     inline int64_t RtpToMs(int64_t rtp, int64_t clockRate);
71     inline void printNowTimeMs(int64_t start, int64_t now, int64_t play);
72     inline void printRTPTime(int64_t rtp, int64_t play, int64_t exp, bool isExp);
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 }  // namespace android
109 
110 #endif  // A_RTP_ASSEMBLER_H_
111