1 /*
2  * Copyright (C) 2011 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "ARawAudioAssembler"
19 #include <utils/Log.h>
20 
21 #include "ARawAudioAssembler.h"
22 
23 #include "ARTPSource.h"
24 #include "ASessionDescription.h"
25 
26 #include <media/stagefright/foundation/ABuffer.h>
27 #include <media/stagefright/foundation/ADebug.h>
28 #include <media/stagefright/foundation/AMessage.h>
29 #include <media/stagefright/foundation/hexdump.h>
30 #include <media/stagefright/MediaDefs.h>
31 #include <media/stagefright/MetaData.h>
32 #include <media/stagefright/Utils.h>
33 
34 namespace android {
35 
ARawAudioAssembler(const sp<AMessage> & notify,const char *,const AString &)36 ARawAudioAssembler::ARawAudioAssembler(
37         const sp<AMessage> &notify,
38         const char * /* desc */,
39         const AString & /* params */)
40     : mNotifyMsg(notify),
41       mNextExpectedSeqNoValid(false),
42       mNextExpectedSeqNo(0) {
43 }
44 
~ARawAudioAssembler()45 ARawAudioAssembler::~ARawAudioAssembler() {
46 }
47 
assembleMore(const sp<ARTPSource> & source)48 ARTPAssembler::AssemblyStatus ARawAudioAssembler::assembleMore(
49         const sp<ARTPSource> &source) {
50     return addPacket(source);
51 }
52 
addPacket(const sp<ARTPSource> & source)53 ARTPAssembler::AssemblyStatus ARawAudioAssembler::addPacket(
54         const sp<ARTPSource> &source) {
55     List<sp<ABuffer> > *queue = source->queue();
56 
57     if (queue->empty()) {
58         return NOT_ENOUGH_DATA;
59     }
60 
61     if (mNextExpectedSeqNoValid) {
62         List<sp<ABuffer> >::iterator it = queue->begin();
63         while (it != queue->end()) {
64             if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
65                 break;
66             }
67 
68             it = queue->erase(it);
69         }
70 
71         if (queue->empty()) {
72             return NOT_ENOUGH_DATA;
73         }
74     }
75 
76     sp<ABuffer> buffer = *queue->begin();
77 
78     if (!mNextExpectedSeqNoValid) {
79         mNextExpectedSeqNoValid = true;
80         mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
81     } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
82         ALOGV("Not the sequence number I expected");
83 
84         return WRONG_SEQUENCE_NUMBER;
85     }
86 
87     // hexdump(buffer->data(), buffer->size());
88 
89     if (buffer->size() < 1) {
90         queue->erase(queue->begin());
91         ++mNextExpectedSeqNo;
92 
93         ALOGV("raw audio packet too short.");
94 
95         return MALFORMED_PACKET;
96     }
97 
98     sp<AMessage> msg = mNotifyMsg->dup();
99     msg->setBuffer("access-unit", buffer);
100     msg->post();
101 
102     queue->erase(queue->begin());
103     ++mNextExpectedSeqNo;
104 
105     return OK;
106 }
107 
packetLost()108 void ARawAudioAssembler::packetLost() {
109     CHECK(mNextExpectedSeqNoValid);
110     ++mNextExpectedSeqNo;
111 }
112 
onByeReceived()113 void ARawAudioAssembler::onByeReceived() {
114     sp<AMessage> msg = mNotifyMsg->dup();
115     msg->setInt32("eos", true);
116     msg->post();
117 }
118 
119 // static
Supports(const char * desc)120 bool ARawAudioAssembler::Supports(const char *desc) {
121     return !strncmp(desc, "PCMU/", 5)
122         || !strncmp(desc, "PCMA/", 5);
123 }
124 
125 // static
MakeFormat(const char * desc,const sp<MetaData> & format)126 void ARawAudioAssembler::MakeFormat(
127         const char *desc, const sp<MetaData> &format) {
128     if (!strncmp(desc, "PCMU/", 5)) {
129         format->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
130     } else if (!strncmp(desc, "PCMA/", 5)) {
131         format->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
132     } else {
133         TRESPASS();
134     }
135 
136     int32_t sampleRate, numChannels;
137     ASessionDescription::ParseFormatDesc(
138             desc, &sampleRate, &numChannels);
139 
140     format->setInt32(kKeySampleRate, sampleRate);
141     format->setInt32(kKeyChannelCount, numChannels);
142 }
143 
144 }  // namespace android
145 
146