Merge "Support for RFC3640 - mpeg4-generic RTP packet type, AAC-lbr and AAC-hbr." into gingerbread
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 5a87f4c..c424281 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -32,9 +32,15 @@
using namespace android;
+static const int32_t kFramerate = 24; // fps
+static const int32_t kIFramesIntervalSec = 1;
+static const int32_t kVideoBitRate = 512 * 1024;
+static const int32_t kAudioBitRate = 12200;
+static const int32_t kColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+static const int64_t kDurationUs = 10000000LL; // 10 seconds
+
#if 1
class DummySource : public MediaSource {
- static const int32_t kFramerate = 24; // fps
public:
DummySource(int width, int height)
@@ -176,6 +182,12 @@
enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
+ enc_meta->setInt32(kKeySampleRate, kFramerate);
+ enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
+ enc_meta->setInt32(kKeyStride, width);
+ enc_meta->setInt32(kKeySliceHeight, height);
+ enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
+ enc_meta->setInt32(kKeyColorFormat, kColorFormat);
sp<MediaSource> encoder =
OMXCodec::Create(
@@ -184,8 +196,10 @@
#if 1
sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
writer->addSource(encoder);
+ writer->setMaxFileDuration(kDurationUs);
writer->start();
while (!writer->reachedEOS()) {
+ fprintf(stderr, ".");
usleep(100000);
}
writer->stop();
@@ -194,6 +208,8 @@
MediaBuffer *buffer;
while (encoder->read(&buffer) == OK) {
+ printf(".");
+ fflush(stdout);
int32_t isSync;
if (!buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)) {
isSync = false;
@@ -209,6 +225,7 @@
encoder->stop();
#endif
+ printf("$\n");
client.disconnect();
#endif
@@ -267,6 +284,7 @@
encMeta->setInt32(kKeySampleRate, kSampleRate);
encMeta->setInt32(kKeyChannelCount, kNumChannels);
encMeta->setInt32(kKeyMaxInputSize, 8192);
+ encMeta->setInt32(kKeyBitRate, kAudioBitRate);
sp<MediaSource> encoder =
OMXCodec::Create(client.interface(), encMeta, true, audioSource);
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 12f8f32..10c9e02 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -362,7 +362,6 @@
if (receiveRTP) {
err = parseRTP(s, buffer);
} else {
- ++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer);
}
@@ -456,6 +455,12 @@
}
status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
+ if (s->mNumRTCPPacketsReceived++ == 0) {
+ sp<AMessage> notify = s->mNotifyMsg->dup();
+ notify->setInt32("first-rtcp", true);
+ notify->post();
+ }
+
const uint8_t *data = buffer->data();
size_t size = buffer->size();
@@ -626,7 +631,6 @@
if (it->mRTPSocket == index) {
err = parseRTP(s, buffer);
} else {
- ++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer);
}
}
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index ee6f65a..b849117 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -82,7 +82,8 @@
mFirstAccessUnitNTP(0),
mNumAccessUnitsReceived(0),
mCheckPending(false),
- mTryTCPInterleaving(false) {
+ mTryTCPInterleaving(false),
+ mReceivedFirstRTCPPacket(false) {
mNetLooper->setName("rtsp net");
mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */,
@@ -199,31 +200,35 @@
break;
}
- CHECK_EQ(response->mStatusCode, 200u);
-
- mSessionDesc = new ASessionDescription;
-
- mSessionDesc->setTo(
- response->mContent->data(),
- response->mContent->size());
-
- CHECK(mSessionDesc->isValid());
-
- ssize_t i = response->mHeaders.indexOfKey("content-base");
- if (i >= 0) {
- mBaseURL = response->mHeaders.valueAt(i);
+ if (response->mStatusCode != 200) {
+ result = UNKNOWN_ERROR;
} else {
- i = response->mHeaders.indexOfKey("content-location");
+ mSessionDesc = new ASessionDescription;
+
+ mSessionDesc->setTo(
+ response->mContent->data(),
+ response->mContent->size());
+
+ CHECK(mSessionDesc->isValid());
+
+ ssize_t i = response->mHeaders.indexOfKey("content-base");
if (i >= 0) {
mBaseURL = response->mHeaders.valueAt(i);
} else {
- mBaseURL = mSessionURL;
+ i = response->mHeaders.indexOfKey("content-location");
+ if (i >= 0) {
+ mBaseURL = response->mHeaders.valueAt(i);
+ } else {
+ mBaseURL = mSessionURL;
+ }
}
- }
- CHECK_GT(mSessionDesc->countTracks(), 1u);
- setupTrack(1);
- } else {
+ CHECK_GT(mSessionDesc->countTracks(), 1u);
+ setupTrack(1);
+ }
+ }
+
+ if (result != OK) {
sp<AMessage> reply = new AMessage('disc', id());
mConn->disconnect(reply);
}
@@ -247,6 +252,39 @@
LOG(INFO) << "SETUP(" << index << ") completed with result "
<< result << " (" << strerror(-result) << ")";
+ if (result == OK) {
+ CHECK(track != NULL);
+
+ sp<RefBase> obj;
+ CHECK(msg->findObject("response", &obj));
+ sp<ARTSPResponse> response =
+ static_cast<ARTSPResponse *>(obj.get());
+
+ if (response->mStatusCode != 200) {
+ result = UNKNOWN_ERROR;
+ } else {
+ ssize_t i = response->mHeaders.indexOfKey("session");
+ CHECK_GE(i, 0);
+
+ mSessionID = response->mHeaders.valueAt(i);
+ i = mSessionID.find(";");
+ if (i >= 0) {
+ // Remove options, i.e. ";timeout=90"
+ mSessionID.erase(i, mSessionID.size() - i);
+ }
+
+ sp<AMessage> notify = new AMessage('accu', id());
+ notify->setSize("track-index", trackIndex);
+
+ mRTPConn->addStream(
+ track->mRTPSocket, track->mRTCPSocket,
+ mSessionDesc, index,
+ notify, track->mUsingInterleavedTCP);
+
+ mSetupTracksSuccessful = true;
+ }
+ }
+
if (result != OK) {
if (track) {
if (!track->mUsingInterleavedTCP) {
@@ -256,37 +294,6 @@
mTracks.removeItemsAt(trackIndex);
}
- } else {
- CHECK(track != NULL);
-
- sp<RefBase> obj;
- CHECK(msg->findObject("response", &obj));
- sp<ARTSPResponse> response =
- static_cast<ARTSPResponse *>(obj.get());
-
- CHECK_EQ(response->mStatusCode, 200u);
-
- ssize_t i = response->mHeaders.indexOfKey("session");
- CHECK_GE(i, 0);
-
- if (index == 1) {
- mSessionID = response->mHeaders.valueAt(i);
- i = mSessionID.find(";");
- if (i >= 0) {
- // Remove options, i.e. ";timeout=90"
- mSessionID.erase(i, mSessionID.size() - i);
- }
- }
-
- sp<AMessage> notify = new AMessage('accu', id());
- notify->setSize("track-index", trackIndex);
-
- mRTPConn->addStream(
- track->mRTPSocket, track->mRTCPSocket,
- mSessionDesc, index,
- notify, track->mUsingInterleavedTCP);
-
- mSetupTracksSuccessful = true;
}
++index;
@@ -355,6 +362,12 @@
}
}
mTracks.clear();
+ mSetupTracksSuccessful = false;
+ mSeekPending = false;
+ mFirstAccessUnit = true;
+ mFirstAccessUnitNTP = 0;
+ mNumAccessUnitsReceived = 0;
+ mReceivedFirstRTCPPacket = false;
sp<AMessage> reply = new AMessage('tear', id());
@@ -424,6 +437,12 @@
case 'accu':
{
+ int32_t firstRTCP;
+ if (msg->findInt32("first-rtcp", &firstRTCP)) {
+ mReceivedFirstRTCPPacket = true;
+ break;
+ }
+
++mNumAccessUnitsReceived;
if (!mCheckPending) {
@@ -612,7 +631,7 @@
case 'tiou':
{
- if (mFirstAccessUnit) {
+ if (!mReceivedFirstRTCPPacket) {
if (mTryTCPInterleaving) {
LOG(WARNING) << "Never received any data, disconnecting.";
(new AMessage('abor', id()))->post();
@@ -747,6 +766,7 @@
int64_t mNumAccessUnitsReceived;
bool mCheckPending;
bool mTryTCPInterleaving;
+ bool mReceivedFirstRTCPPacket;
struct TrackInfo {
AString mURL;