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