summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-08-31 10:27:46 -0700
committerAndreas Huber <andih@google.com>2012-08-31 10:27:46 -0700
commitcfaeeec0900014d97e15829e0fa52f865ee4c786 (patch)
treed97027786e1326f54d3d687b5e724eb5b7c04a3b
parentdc91c885f267005e06f439a3bd592b3d8706bb50 (diff)
downloadframeworks_av-cfaeeec0900014d97e15829e0fa52f865ee4c786.zip
frameworks_av-cfaeeec0900014d97e15829e0fa52f865ee4c786.tar.gz
frameworks_av-cfaeeec0900014d97e15829e0fa52f865ee4c786.tar.bz2
Add support for mpeg2 transport streams to the RTSP implementation.
Change-Id: I409d7133a53a71e62523b1acc2b03302fcf824a5
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.cpp76
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.h4
-rw-r--r--media/libstagefright/rtsp/AMPEG2TSAssembler.cpp119
-rw-r--r--media/libstagefright/rtsp/AMPEG2TSAssembler.h54
-rw-r--r--media/libstagefright/rtsp/APacketSource.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPSource.cpp3
-rw-r--r--media/libstagefright/rtsp/Android.mk1
7 files changed, 254 insertions, 5 deletions
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 4a704e3..5a7a785 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -23,6 +23,7 @@
#include "AnotherPacketSource.h"
#include "MyHandler.h"
+#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
namespace android {
@@ -159,6 +160,13 @@ status_t NuPlayer::RTSPSource::dequeueAccessUnit(
}
sp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
+ if (mTSParser != NULL) {
+ sp<MediaSource> source = mTSParser->getSource(
+ audio ? ATSParser::AUDIO : ATSParser::VIDEO);
+
+ return static_cast<AnotherPacketSource *>(source.get());
+ }
+
return audio ? mAudioTrack : mVideoTrack;
}
@@ -255,7 +263,12 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
{
size_t trackIndex;
CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
+
+ if (mTSParser == NULL) {
+ CHECK_LT(trackIndex, mTracks.size());
+ } else {
+ CHECK_EQ(trackIndex, 0u);
+ }
sp<ABuffer> accessUnit;
CHECK(msg->findBuffer("accessUnit", &accessUnit));
@@ -267,6 +280,37 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ if (mTSParser != NULL) {
+ size_t offset = 0;
+ status_t err = OK;
+ while (offset + 188 <= accessUnit->size()) {
+ err = mTSParser->feedTSPacket(
+ accessUnit->data() + offset, 188);
+ if (err != OK) {
+ break;
+ }
+
+ offset += 188;
+ }
+
+ if (offset < accessUnit->size()) {
+ err = ERROR_MALFORMED;
+ }
+
+ if (err != OK) {
+ sp<AnotherPacketSource> source = getSource(false /* audio */);
+ if (source != NULL) {
+ source->signalEOS(err);
+ }
+
+ source = getSource(true /* audio */);
+ if (source != NULL) {
+ source->signalEOS(err);
+ }
+ }
+ break;
+ }
+
TrackInfo *info = &mTracks.editItemAt(trackIndex);
sp<AnotherPacketSource> source = info->mSource;
@@ -296,14 +340,28 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
case MyHandler::kWhatEOS:
{
- size_t trackIndex;
- CHECK(msg->findSize("trackIndex", &trackIndex));
- CHECK_LT(trackIndex, mTracks.size());
-
int32_t finalResult;
CHECK(msg->findInt32("finalResult", &finalResult));
CHECK_NE(finalResult, (status_t)OK);
+ if (mTSParser != NULL) {
+ sp<AnotherPacketSource> source = getSource(false /* audio */);
+ if (source != NULL) {
+ source->signalEOS(finalResult);
+ }
+
+ source = getSource(true /* audio */);
+ if (source != NULL) {
+ source->signalEOS(finalResult);
+ }
+
+ return;
+ }
+
+ size_t trackIndex;
+ CHECK(msg->findSize("trackIndex", &trackIndex));
+ CHECK_LT(trackIndex, mTracks.size());
+
TrackInfo *info = &mTracks.editItemAt(trackIndex);
sp<AnotherPacketSource> source = info->mSource;
if (source != NULL) {
@@ -364,6 +422,14 @@ void NuPlayer::RTSPSource::onConnected() {
const char *mime;
CHECK(format->findCString(kKeyMIMEType, &mime));
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
+ // Very special case for MPEG2 Transport Streams.
+ CHECK_EQ(numTracks, 1u);
+
+ mTSParser = new ATSParser;
+ return;
+ }
+
bool isAudio = !strncasecmp(mime, "audio/", 6);
bool isVideo = !strncasecmp(mime, "video/", 6);
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index c8409e5..f07c724 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -20,6 +20,8 @@
#include "NuPlayerSource.h"
+#include "ATSParser.h"
+
#include <media/stagefright/foundation/AHandlerReflector.h>
namespace android {
@@ -99,6 +101,8 @@ private:
sp<AnotherPacketSource> mAudioTrack;
sp<AnotherPacketSource> mVideoTrack;
+ sp<ATSParser> mTSParser;
+
int32_t mSeekGeneration;
sp<AnotherPacketSource> getSource(bool audio);
diff --git a/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
new file mode 100644
index 0000000..4c9bf5b
--- /dev/null
+++ b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AMPEG2TSAssembler"
+#include <utils/Log.h>
+
+#include "AMPEG2TSAssembler.h"
+
+#include "ARTPSource.h"
+#include "ASessionDescription.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+AMPEG2TSAssembler::AMPEG2TSAssembler(
+ const sp<AMessage> &notify, const char *desc, const AString &params)
+ : mNotifyMsg(notify),
+ mNextExpectedSeqNoValid(false),
+ mNextExpectedSeqNo(0) {
+}
+
+AMPEG2TSAssembler::~AMPEG2TSAssembler() {
+}
+
+ARTPAssembler::AssemblyStatus AMPEG2TSAssembler::assembleMore(
+ const sp<ARTPSource> &source) {
+ return addPacket(source);
+}
+
+ARTPAssembler::AssemblyStatus AMPEG2TSAssembler::addPacket(
+ const sp<ARTPSource> &source) {
+ List<sp<ABuffer> > *queue = source->queue();
+
+ if (queue->empty()) {
+ return NOT_ENOUGH_DATA;
+ }
+
+ if (mNextExpectedSeqNoValid) {
+ List<sp<ABuffer> >::iterator it = queue->begin();
+ while (it != queue->end()) {
+ if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
+ break;
+ }
+
+ it = queue->erase(it);
+ }
+
+ if (queue->empty()) {
+ return NOT_ENOUGH_DATA;
+ }
+ }
+
+ sp<ABuffer> buffer = *queue->begin();
+
+ if (!mNextExpectedSeqNoValid) {
+ mNextExpectedSeqNoValid = true;
+ mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
+ } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
+ ALOGV("Not the sequence number I expected");
+
+ return WRONG_SEQUENCE_NUMBER;
+ }
+
+ // hexdump(buffer->data(), buffer->size());
+
+ if ((buffer->size() % 188) > 0) {
+ queue->erase(queue->begin());
+ ++mNextExpectedSeqNo;
+
+ ALOGV("Not a multiple of transport packet size.");
+
+ return MALFORMED_PACKET;
+ }
+
+ sp<AMessage> msg = mNotifyMsg->dup();
+ msg->setBuffer("access-unit", buffer);
+ msg->post();
+
+ queue->erase(queue->begin());
+ ++mNextExpectedSeqNo;
+
+ return OK;
+}
+
+void AMPEG2TSAssembler::packetLost() {
+ CHECK(mNextExpectedSeqNoValid);
+ ++mNextExpectedSeqNo;
+}
+
+void AMPEG2TSAssembler::onByeReceived() {
+ sp<AMessage> msg = mNotifyMsg->dup();
+ msg->setInt32("eos", true);
+ msg->post();
+}
+
+} // namespace android
+
+
diff --git a/media/libstagefright/rtsp/AMPEG2TSAssembler.h b/media/libstagefright/rtsp/AMPEG2TSAssembler.h
new file mode 100644
index 0000000..712e18e
--- /dev/null
+++ b/media/libstagefright/rtsp/AMPEG2TSAssembler.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef A_MPEG2_TS_ASSEMBLER_H_
+
+#define A_MPEG2_TS_ASSEMBLER_H_
+
+#include "ARTPAssembler.h"
+
+namespace android {
+
+struct AMessage;
+struct AString;
+struct MetaData;
+
+struct AMPEG2TSAssembler : public ARTPAssembler {
+ AMPEG2TSAssembler(
+ const sp<AMessage> &notify,
+ const char *desc, const AString &params);
+
+protected:
+ virtual ~AMPEG2TSAssembler();
+
+ virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
+ virtual void onByeReceived();
+ virtual void packetLost();
+
+private:
+ sp<AMessage> mNotifyMsg;
+ bool mNextExpectedSeqNoValid;
+ uint32_t mNextExpectedSeqNo;
+
+ AssemblyStatus addPacket(const sp<ARTPSource> &source);
+
+ DISALLOW_EVIL_CONSTRUCTORS(AMPEG2TSAssembler);
+};
+
+} // namespace android
+
+#endif // A_MPEG2_TS_ASSEMBLER_H_
+
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index ddd2f06..462c384 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -566,6 +566,8 @@ APacketSource::APacketSource(
codecSpecificData->data(), codecSpecificData->size());
} else if (ARawAudioAssembler::Supports(desc.c_str())) {
ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat);
+ } else if (!strncasecmp("MP2T/", desc.c_str(), 5)) {
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
} else {
mInitCheck = ERROR_UNSUPPORTED;
}
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index ed68790..d7c3bd6 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -23,6 +23,7 @@
#include "AAMRAssembler.h"
#include "AAVCAssembler.h"
#include "AH263Assembler.h"
+#include "AMPEG2TSAssembler.h"
#include "AMPEG4AudioAssembler.h"
#include "AMPEG4ElementaryAssembler.h"
#include "ARawAudioAssembler.h"
@@ -73,6 +74,8 @@ ARTPSource::ARTPSource(
mIssueFIRRequests = true;
} else if (ARawAudioAssembler::Supports(desc.c_str())) {
mAssembler = new ARawAudioAssembler(notify, desc.c_str(), params);
+ } else if (!strncasecmp(desc.c_str(), "MP2T/", 5)) {
+ mAssembler = new AMPEG2TSAssembler(notify, desc.c_str(), params);
} else {
TRESPASS();
}
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index d0f5259..49e2daf 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -6,6 +6,7 @@ LOCAL_SRC_FILES:= \
AAMRAssembler.cpp \
AAVCAssembler.cpp \
AH263Assembler.cpp \
+ AMPEG2TSAssembler.cpp \
AMPEG4AudioAssembler.cpp \
AMPEG4ElementaryAssembler.cpp \
APacketSource.cpp \