16e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber/* 26e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * Copyright (C) 2010 The Android Open Source Project 36e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * 46e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 56e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * you may not use this file except in compliance with the License. 66e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * You may obtain a copy of the License at 76e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * 86e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 96e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * 106e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * Unless required by applicable law or agreed to in writing, software 116e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 126e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * See the License for the specific language governing permissions and 146e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber * limitations under the License. 156e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber */ 166e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber 176e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber//#define LOG_NDEBUG 0 186e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber#define LOG_TAG "ARTPWriter" 196e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber#include <utils/Log.h> 206e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber 2157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include "ARTPWriter.h" 2257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 2357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <fcntl.h> 2457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 2557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 2657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/foundation/AMessage.h> 2857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/foundation/hexdump.h> 2957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/MediaBuffer.h> 3057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/MediaDefs.h> 3157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/MediaSource.h> 3257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <media/stagefright/MetaData.h> 3357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#include <utils/ByteOrder.h> 3457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 3557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#define PT 97 3657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#define PT_STR "97" 3757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 3857648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubernamespace android { 3957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 4057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber// static const size_t kMaxPacketSize = 65507; // maximum payload in UDP over IP 4157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic const size_t kMaxPacketSize = 1500; 4257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 4357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic int UniformRand(int limit) { 4457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return ((double)rand() * limit) / RAND_MAX; 4557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 4657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 4757648e4eec7dd2593af467877bc7cce4aa654759Andreas HuberARTPWriter::ARTPWriter(int fd) 4857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber : mFlags(0), 492747e0e07ff7ec2ba808298e8d96536d72d211cbJames Dong mFd(dup(fd)), 5057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLooper(new ALooper), 5157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mReflector(new AHandlerReflector<ARTPWriter>(this)) { 5257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(fd, 0); 5357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 54c4e0b70a21fadb47d70955c71fc31ce1473da925Andreas Huber mLooper->setName("rtp writer"); 5557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLooper->registerHandler(mReflector); 5657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLooper->start(); 5757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 5857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSocket = socket(AF_INET, SOCK_DGRAM, 0); 5957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(mSocket, 0); 6057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 6157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memset(mRTPAddr.sin_zero, 0, sizeof(mRTPAddr.sin_zero)); 6257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPAddr.sin_family = AF_INET; 6357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 6457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 1 6557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPAddr.sin_addr.s_addr = INADDR_ANY; 6657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#else 6700237b79a031e95073f7f9ee8f7c022e149a4f3bAndreas Huber mRTPAddr.sin_addr.s_addr = inet_addr("172.19.18.246"); 6857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif 6957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 7057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPAddr.sin_port = htons(5634); 7157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(0, ntohs(mRTPAddr.sin_port) & 1); 7257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 7357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTCPAddr = mRTPAddr; 7457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTCPAddr.sin_port = htons(ntohs(mRTPAddr.sin_port) | 1); 7557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 7657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if LOG_TO_FILES 7757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPFd = open( 7857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "/data/misc/rtpout.bin", 7957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber O_WRONLY | O_CREAT | O_TRUNC, 8057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 0644); 8157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(mRTPFd, 0); 8257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 8357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTCPFd = open( 8457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "/data/misc/rtcpout.bin", 8557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber O_WRONLY | O_CREAT | O_TRUNC, 8657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 0644); 8757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(mRTCPFd, 0); 8857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif 8957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 9057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 9157648e4eec7dd2593af467877bc7cce4aa654759Andreas HuberARTPWriter::~ARTPWriter() { 9257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if LOG_TO_FILES 9357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber close(mRTCPFd); 9457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTCPFd = -1; 9557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 9657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber close(mRTPFd); 9757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPFd = -1; 9857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif 9957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 10057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber close(mSocket); 10157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSocket = -1; 10257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 10357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber close(mFd); 10457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mFd = -1; 10557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 10657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 10757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatus_t ARTPWriter::addSource(const sp<MediaSource> &source) { 10857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSource = source; 10957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return OK; 11057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 11157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 11257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberbool ARTPWriter::reachedEOS() { 11357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 11457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return (mFlags & kFlagEOS) != 0; 11557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 11657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 11757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatus_t ARTPWriter::start(MetaData *params) { 11857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 11957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mFlags & kFlagStarted) { 12057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return INVALID_OPERATION; 12157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 12257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 12357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mFlags &= ~kFlagEOS; 12457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSourceID = rand(); 12557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSeqNo = UniformRand(65536); 12657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mRTPTimeBase = rand(); 12757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPSent = 0; 12857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPOctetsSent = 0; 12957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastRTPTime = 0; 13057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastNTPTime = 0; 13157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumSRsSent = 0; 13257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 13357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const char *mime; 13457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 13557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 13657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mMode = INVALID; 13757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 13857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mMode = H264; 13957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_H263)) { 14057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mMode = H263; 14157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) { 14257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mMode = AMR_NB; 14357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) { 14457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mMode = AMR_WB; 14557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else { 14657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber TRESPASS(); 14757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 14857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 14957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (new AMessage(kWhatStart, mReflector->id()))->post(); 15057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 15157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (!(mFlags & kFlagStarted)) { 15257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mCondition.wait(mLock); 15357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 15457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 15557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return OK; 15657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 15757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 158d036662470ceb6b20b0591b7d4123f2db911536dJames Dongstatus_t ARTPWriter::stop() { 15957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 16057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!(mFlags & kFlagStarted)) { 161d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 16257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 16357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 16457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (new AMessage(kWhatStop, mReflector->id()))->post(); 16557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 16657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (mFlags & kFlagStarted) { 16757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mCondition.wait(mLock); 16857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 169d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 17057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 17157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 172d036662470ceb6b20b0591b7d4123f2db911536dJames Dongstatus_t ARTPWriter::pause() { 173d036662470ceb6b20b0591b7d4123f2db911536dJames Dong return OK; 17457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 17557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 17657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic void StripStartcode(MediaBuffer *buffer) { 17757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (buffer->range_length() < 4) { 17857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return; 17957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 18057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 18157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const uint8_t *ptr = 18257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 18357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 18457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { 18557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->set_range( 18657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->range_offset() + 4, buffer->range_length() - 4); 18757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 18857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 18957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 19057648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::onMessageReceived(const sp<AMessage> &msg) { 19157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber switch (msg->what()) { 19257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case kWhatStart: 19357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 19457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(mSource->start(), (status_t)OK); 19557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 19657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if 0 19757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264) { 19857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber MediaBuffer *buffer; 19957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(mSource->read(&buffer), (status_t)OK); 20057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 20157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber StripStartcode(buffer); 20257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber makeH264SPropParamSets(buffer); 20357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->release(); 20457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer = NULL; 20557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 20657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 20757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber dumpSessionDesc(); 20857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif 20957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 21057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 21157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 21257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mFlags |= kFlagStarted; 21357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mCondition.signal(); 21457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 21557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 21657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (new AMessage(kWhatRead, mReflector->id()))->post(); 21757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (new AMessage(kWhatSendSR, mReflector->id()))->post(); 21857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 21957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 22057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 22157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case kWhatStop: 22257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 22357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 22457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 22557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sendBye(); 22657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 22757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 22857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 22957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mFlags &= ~kFlagStarted; 23057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mCondition.signal(); 23157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 23257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 23357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 23457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 23557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case kWhatRead: 23657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 23757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 23857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 23957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!(mFlags & kFlagStarted)) { 24057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 24157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 24257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 24357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 24457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber onRead(msg); 24557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 24657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 24757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 24857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case kWhatSendSR: 24957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 25057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber { 25157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 25257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!(mFlags & kFlagStarted)) { 25357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 25457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 25557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 25657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 25757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber onSendSR(msg); 25857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 25957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 26057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 26157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber default: 26257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber TRESPASS(); 26357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber break; 26457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 26557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 26657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 26757648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::onRead(const sp<AMessage> &msg) { 26857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber MediaBuffer *mediaBuf; 26957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber status_t err = mSource->read(&mediaBuf); 27057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 27157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (err != OK) { 2726e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGI("reached EOS."); 27357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 27457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Mutex::Autolock autoLock(mLock); 27557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mFlags |= kFlagEOS; 27657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return; 27757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 27857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 27957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mediaBuf->range_length() > 0) { 2806e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGV("read buffer of size %d", mediaBuf->range_length()); 28157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 28257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264) { 28357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber StripStartcode(mediaBuf); 28457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sendAVCData(mediaBuf); 28557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (mMode == H263) { 28657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sendH263Data(mediaBuf); 28757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 28857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sendAMRData(mediaBuf); 28957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 29057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 29157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 29257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mediaBuf->release(); 29357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mediaBuf = NULL; 29457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 29557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber msg->post(); 29657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 29757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 29857648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::onSendSR(const sp<AMessage> &msg) { 29957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<ABuffer> buffer = new ABuffer(65536); 30057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, 0); 30157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 30257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber addSR(buffer); 30357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber addSDES(buffer); 30457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 30557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, true /* isRTCP */); 30657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 30757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mNumSRsSent; 30857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber msg->post(3000000); 30957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 31057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 31157648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) { 31257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ssize_t n = sendto( 31357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mSocket, buffer->data(), buffer->size(), 0, 31457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const struct sockaddr *)(isRTCP ? &mRTCPAddr : &mRTPAddr), 31557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sizeof(mRTCPAddr)); 31657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 31757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(n, (ssize_t)buffer->size()); 31857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 31957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#if LOG_TO_FILES 32057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int fd = isRTCP ? mRTCPFd : mRTPFd; 32157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 32257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint32_t ms = tolel(ALooper::GetNowUs() / 1000ll); 32357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint32_t length = tolel(buffer->size()); 32457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber write(fd, &ms, sizeof(ms)); 32557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber write(fd, &length, sizeof(length)); 32657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber write(fd, buffer->data(), buffer->size()); 32757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber#endif 32857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 32957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 33057648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::addSR(const sp<ABuffer> &buffer) { 33157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 33257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 33357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80 | 0; 33457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = 200; // SR 33557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = 0; 33657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = 6; 33757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = mSourceID >> 24; 33857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (mSourceID >> 16) & 0xff; 33957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (mSourceID >> 8) & 0xff; 34057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = mSourceID & 0xff; 34157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 34257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[8] = mLastNTPTime >> (64 - 8); 34357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 34457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 34557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[11] = (mLastNTPTime >> 32) & 0xff; 34657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[12] = (mLastNTPTime >> 24) & 0xff; 34757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[13] = (mLastNTPTime >> 16) & 0xff; 34857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[14] = (mLastNTPTime >> 8) & 0xff; 34957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[15] = mLastNTPTime & 0xff; 35057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 35157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[16] = (mLastRTPTime >> 24) & 0xff; 35257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[17] = (mLastRTPTime >> 16) & 0xff; 35357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[18] = (mLastRTPTime >> 8) & 0xff; 35457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[19] = mLastRTPTime & 0xff; 35557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 35657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[20] = mNumRTPSent >> 24; 35757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[21] = (mNumRTPSent >> 16) & 0xff; 35857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[22] = (mNumRTPSent >> 8) & 0xff; 35957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[23] = mNumRTPSent & 0xff; 36057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 36157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[24] = mNumRTPOctetsSent >> 24; 36257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 36357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 36457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[27] = mNumRTPOctetsSent & 0xff; 36557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 36657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + 28); 36757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 36857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 36957648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::addSDES(const sp<ABuffer> &buffer) { 37057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data() + buffer->size(); 37157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80 | 1; 37257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = 202; // SDES 37357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = mSourceID >> 24; 37457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (mSourceID >> 16) & 0xff; 37557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (mSourceID >> 8) & 0xff; 37657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = mSourceID & 0xff; 37757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 37857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t offset = 8; 37957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 38057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 1; // CNAME 38157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 38257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber static const char *kCNAME = "someone@somewhere"; 38357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = strlen(kCNAME); 38457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 38557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[offset], kCNAME, strlen(kCNAME)); 38657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber offset += strlen(kCNAME); 38757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 38857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 7; // NOTE 38957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 39057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber static const char *kNOTE = "Hell's frozen over."; 39157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = strlen(kNOTE); 39257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 39357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[offset], kNOTE, strlen(kNOTE)); 39457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber offset += strlen(kNOTE); 39557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 39657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 0; 39757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 39857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if ((offset % 4) > 0) { 39957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t count = 4 - (offset % 4); 40057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber switch (count) { 40157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case 3: 40257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 0; 40357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case 2: 40457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 0; 40557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber case 1: 40657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[offset++] = 0; 40757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 40857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 40957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 41057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t numWords = (offset / 4) - 1; 41157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = numWords >> 8; 41257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = numWords & 0xff; 41357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 41457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(buffer->offset(), buffer->size() + offset); 41557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 41657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 41757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber// static 41857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberuint64_t ARTPWriter::GetNowNTP() { 41957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint64_t nowUs = ALooper::GetNowUs(); 42057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 42157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 42257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 42357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint64_t hi = nowUs / 1000000ll; 42457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 42557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 42657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return (hi << 32) | lo; 42757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 42857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 42957648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::dumpSessionDesc() { 43057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber AString sdp; 43157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp = "v=0\r\n"; 43257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 43357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("o=- "); 43457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 43557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint64_t ntp = GetNowNTP(); 43657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(ntp); 43757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(" "); 43857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(ntp); 43957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(" IN IP4 127.0.0.0\r\n"); 44057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 44157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append( 44257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "s=Sample\r\n" 44357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "i=Playing around\r\n" 44457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "c=IN IP4 "); 44557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 44657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber struct in_addr addr; 44757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber addr.s_addr = ntohl(INADDR_LOOPBACK); 44857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 44957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(inet_ntoa(addr)); 45057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 45157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append( 45257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "\r\n" 45357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "t=0 0\r\n" 45457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "a=range:npt=now-\r\n"); 45557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 45657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<MetaData> meta = mSource->getFormat(); 45757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 45857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264 || mMode == H263) { 45957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("m=video "); 46057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else { 46157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("m=audio "); 46257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 46357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 46457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(StringPrintf("%d", ntohs(mRTPAddr.sin_port))); 46557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append( 46657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber " RTP/AVP " PT_STR "\r\n" 46757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "b=AS 320000\r\n" 46857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "a=rtpmap:" PT_STR " "); 46957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 47057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264) { 47157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("H264/90000"); 47257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (mMode == H263) { 47357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("H263-1998/90000"); 47457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 47557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int32_t sampleRate, numChannels; 47657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mSource->getFormat()->findInt32(kKeySampleRate, &sampleRate)); 47757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mSource->getFormat()->findInt32(kKeyChannelCount, &numChannels)); 47857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 47957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(numChannels, 1); 48057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(sampleRate, (mMode == AMR_NB) ? 8000 : 16000); 48157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 48257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(mMode == AMR_NB ? "AMR" : "AMR-WB"); 48357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(StringPrintf("/%d/%d", sampleRate, numChannels)); 48457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else { 48557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber TRESPASS(); 48657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 48757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 48857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("\r\n"); 48957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 49057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264 || mMode == H263) { 49157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int32_t width, height; 49257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 49357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 49457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 49557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("a=cliprect 0,0,"); 49657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(height); 49757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(","); 49857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(width); 49957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("\r\n"); 50057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 50157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append( 50257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "a=framesize:" PT_STR " "); 50357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(width); 50457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("-"); 50557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(height); 50657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("\r\n"); 50757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 50857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 50957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mMode == H264) { 51057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append( 51157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber "a=fmtp:" PT_STR " profile-level-id="); 51257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(mProfileLevel); 51357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(";sprop-parameter-sets="); 51457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 51557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(mSeqParamSet); 51657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(","); 51757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(mPicParamSet); 51857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append(";packetization-mode=1\r\n"); 51957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else if (mMode == AMR_NB || mMode == AMR_WB) { 52057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sdp.append("a=fmtp:" PT_STR " octed-align\r\n"); 52157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 52257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 5236e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGI("%s", sdp.c_str()); 52457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 52557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 52657648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::makeH264SPropParamSets(MediaBuffer *buffer) { 52757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber static const char kStartCode[] = "\x00\x00\x00\x01"; 52857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 52957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const uint8_t *data = 53057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 53157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t size = buffer->range_length(); 53257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 53357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(size, 0u); 53457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 53557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t startCodePos = 0; 53657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (startCodePos + 3 < size 53757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber && memcmp(kStartCode, &data[startCodePos], 4)) { 53857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++startCodePos; 53957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 54057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 54157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_LT(startCodePos + 3, size); 54257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 54357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ((unsigned)data[0], 0x67u); 54457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 54557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mProfileLevel = 54657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber StringPrintf("%02X%02X%02X", data[1], data[2], data[3]); 54757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 54857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber encodeBase64(data, startCodePos, &mSeqParamSet); 54957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 55057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber encodeBase64(&data[startCodePos + 4], size - startCodePos - 4, 55157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber &mPicParamSet); 55257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 55357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 55457648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::sendBye() { 55557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<ABuffer> buffer = new ABuffer(8); 55657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data(); 55757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = (2 << 6) | 1; 55857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = 203; 55957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = 0; 56057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = 1; 56157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = mSourceID >> 24; 56257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = (mSourceID >> 16) & 0xff; 56357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = (mSourceID >> 8) & 0xff; 56457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber *data++ = mSourceID & 0xff; 56557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, 8); 56657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 56757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, true /* isRTCP */); 56857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 56957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 57057648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::sendAVCData(MediaBuffer *mediaBuf) { 57157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header. 57257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 2u); 57357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 57457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int64_t timeUs; 57557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 57657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 57757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 57857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 57957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const uint8_t *mediaData = 58057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 58157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 58257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 58357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mediaBuf->range_length() + 12 <= buffer->capacity()) { 58457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // The data fits into a single packet 58557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data(); 58657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80; 58757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = (1 << 7) | PT; // M-bit 58857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 58957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = mSeqNo & 0xff; 59057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = rtpTime >> 24; 59157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 59257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 59357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = rtpTime & 0xff; 59457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[8] = mSourceID >> 24; 59557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 59657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 59757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[11] = mSourceID & 0xff; 59857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 59957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[12], 60057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mediaData, mediaBuf->range_length()); 60157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 60257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, mediaBuf->range_length() + 12); 60357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 60457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, false /* isRTCP */); 60557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 60657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mSeqNo; 60757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mNumRTPSent; 60857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 60957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else { 61057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // FU-A 61157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 61257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber unsigned nalType = mediaData[0]; 61357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t offset = 1; 61457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 61557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber bool firstPacket = true; 61657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (offset < mediaBuf->range_length()) { 61757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t size = mediaBuf->range_length() - offset; 61857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber bool lastPacket = true; 61957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (size + 12 + 2 > buffer->capacity()) { 62057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber lastPacket = false; 62157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size = buffer->capacity() - 12 - 2; 62257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 62357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 62457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data(); 62557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80; 62657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = (lastPacket ? (1 << 7) : 0x00) | PT; // M-bit 62757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 62857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = mSeqNo & 0xff; 62957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = rtpTime >> 24; 63057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 63157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 63257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = rtpTime & 0xff; 63357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[8] = mSourceID >> 24; 63457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 63557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 63657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[11] = mSourceID & 0xff; 63757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 63857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[12] = 28 | (nalType & 0xe0); 63957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 64057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(!firstPacket || !lastPacket); 64157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 64257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[13] = 64357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (firstPacket ? 0x80 : 0x00) 64457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber | (lastPacket ? 0x40 : 0x00) 64557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber | (nalType & 0x1f); 64657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 64757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[14], &mediaData[offset], size); 64857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 64957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, 14 + size); 65057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 65157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, false /* isRTCP */); 65257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 65357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mSeqNo; 65457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mNumRTPSent; 65557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 65657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 65757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber firstPacket = false; 65857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber offset += size; 65957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 66057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 66157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 66257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastRTPTime = rtpTime; 66357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastNTPTime = GetNowNTP(); 66457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 66557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 66657648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::sendH263Data(MediaBuffer *mediaBuf) { 66757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 2u); 66857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 66957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int64_t timeUs; 67057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 67157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 67257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll); 67357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 67457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const uint8_t *mediaData = 67557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 67657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 67757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // hexdump(mediaData, mediaBuf->range_length()); 67857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 67957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ((unsigned)mediaData[0], 0u); 68057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ((unsigned)mediaData[1], 0u); 68157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 68257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t offset = 2; 68357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t size = mediaBuf->range_length(); 68457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 68557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (offset < size) { 68657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 68757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // CHECK_LE(mediaBuf->range_length() -2 + 14, buffer->capacity()); 68857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 68957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t remaining = size - offset; 69057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber bool lastPacket = (remaining + 14 <= buffer->capacity()); 69157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (!lastPacket) { 69257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber remaining = buffer->capacity() - 14; 69357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 69457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 69557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data(); 69657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80; 69757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = (lastPacket ? 0x80 : 0x00) | PT; // M-bit 69857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 69957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = mSeqNo & 0xff; 70057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = rtpTime >> 24; 70157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 70257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 70357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = rtpTime & 0xff; 70457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[8] = mSourceID >> 24; 70557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 70657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 70757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[11] = mSourceID & 0xff; 70857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 70957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[12] = (offset == 2) ? 0x04 : 0x00; // P=?, V=0 71057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[13] = 0x00; // PLEN = PEBIT = 0 71157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 71257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[14], &mediaData[offset], remaining); 71357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber offset += remaining; 71457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 71557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, remaining + 14); 71657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 71757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, false /* isRTCP */); 71857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 71957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mSeqNo; 72057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mNumRTPSent; 72157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 72257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 72357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 72457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastRTPTime = rtpTime; 72557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastNTPTime = GetNowNTP(); 72657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 72757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 72857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huberstatic size_t getFrameSize(bool isWide, unsigned FT) { 72957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber static const size_t kFrameSizeNB[8] = { 73057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 95, 103, 118, 134, 148, 159, 204, 244 73157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber }; 73257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber static const size_t kFrameSizeWB[9] = { 73357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 132, 177, 253, 285, 317, 365, 397, 461, 477 73457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber }; 73557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 73657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT]; 73757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 73857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // Round up bits to bytes and add 1 for the header byte. 73957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber frameSize = (frameSize + 7) / 8 + 1; 74057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 74157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber return frameSize; 74257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 74357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 74457648e4eec7dd2593af467877bc7cce4aa654759Andreas Hubervoid ARTPWriter::sendAMRData(MediaBuffer *mediaBuf) { 74557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const uint8_t *mediaData = 74657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset(); 74757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 74857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t mediaLength = mediaBuf->range_length(); 74957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 75057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength); 75157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 75257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber const bool isWide = (mMode == AMR_WB); 75357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 75457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber int64_t timeUs; 75557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK(mediaBuf->meta_data()->findInt64(kKeyTime, &timeUs)); 75657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125)); 75757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 75857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // hexdump(mediaData, mediaLength); 75957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 76057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber Vector<uint8_t> tableOfContents; 76157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t srcOffset = 0; 76257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber while (srcOffset < mediaLength) { 76357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t toc = mediaData[srcOffset]; 76457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 76557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber unsigned FT = (toc >> 3) & 0x0f; 76657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK((isWide && FT <= 8) || (!isWide && FT <= 7)); 76757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 76857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber tableOfContents.push(toc); 76957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber srcOffset += getFrameSize(isWide, FT); 77057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 77157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_EQ(srcOffset, mediaLength); 77257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 77357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxPacketSize); 77457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber CHECK_LE(mediaLength + 12 + 1, buffer->capacity()); 77557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 77657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // The data fits into a single packet 77757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t *data = buffer->data(); 77857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[0] = 0x80; 77957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] = PT; 78057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (mNumRTPSent == 0) { 78157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber // Signal start of talk-spurt. 78257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[1] |= 0x80; // M-bit 78357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 78457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[2] = (mSeqNo >> 8) & 0xff; 78557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[3] = mSeqNo & 0xff; 78657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[4] = rtpTime >> 24; 78757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[5] = (rtpTime >> 16) & 0xff; 78857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[6] = (rtpTime >> 8) & 0xff; 78957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[7] = rtpTime & 0xff; 79057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[8] = mSourceID >> 24; 79157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[9] = (mSourceID >> 16) & 0xff; 79257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[10] = (mSourceID >> 8) & 0xff; 79357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[11] = mSourceID & 0xff; 79457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 79557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[12] = 0xf0; // CMR=15, RR=0 79657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 79757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t dstOffset = 13; 79857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 79957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber for (size_t i = 0; i < tableOfContents.size(); ++i) { 80057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t toc = tableOfContents[i]; 80157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 80257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber if (i + 1 < tableOfContents.size()) { 80357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber toc |= 0x80; 80457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } else { 80557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber toc &= ~0x80; 80657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 80757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 80857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber data[dstOffset++] = toc; 80957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 81057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 81157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber srcOffset = 0; 81257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber for (size_t i = 0; i < tableOfContents.size(); ++i) { 81357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber uint8_t toc = tableOfContents[i]; 81457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber unsigned FT = (toc >> 3) & 0x0f; 81557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber size_t frameSize = getFrameSize(isWide, FT); 81657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 81757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++srcOffset; // skip toc 81857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1); 81957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber srcOffset += frameSize - 1; 82057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber dstOffset += frameSize - 1; 82157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber } 82257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 82357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber buffer->setRange(0, dstOffset); 82457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 82557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber send(buffer, false /* isRTCP */); 82657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 82757648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mSeqNo; 82857648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber ++mNumRTPSent; 82957648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mNumRTPOctetsSent += buffer->size() - 12; 83057648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 83157648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastRTPTime = rtpTime; 83257648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber mLastNTPTime = GetNowNTP(); 83357648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} 83457648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 83557648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber} // namespace android 83657648e4eec7dd2593af467877bc7cce4aa654759Andreas Huber 837