Loading media/libmediaplayerservice/nuplayer/RTSPSource.cpp +71 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "AnotherPacketSource.h" #include "MyHandler.h" #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MetaData.h> namespace android { Loading Loading @@ -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; } Loading Loading @@ -255,7 +263,12 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); if (mTSParser == NULL) { CHECK_LT(trackIndex, mTracks.size()); } else { CHECK_EQ(trackIndex, 0u); } sp<ABuffer> accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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); Loading media/libmediaplayerservice/nuplayer/RTSPSource.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include "NuPlayerSource.h" #include "ATSParser.h" #include <media/stagefright/foundation/AHandlerReflector.h> namespace android { Loading Loading @@ -99,6 +101,8 @@ private: sp<AnotherPacketSource> mAudioTrack; sp<AnotherPacketSource> mVideoTrack; sp<ATSParser> mTSParser; int32_t mSeekGeneration; sp<AnotherPacketSource> getSource(bool audio); Loading media/libstagefright/rtsp/AMPEG2TSAssembler.cpp 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * 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> ¬ify, const char *desc, const AString ¶ms) : 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 media/libstagefright/rtsp/AMPEG2TSAssembler.h 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * 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> ¬ify, const char *desc, const AString ¶ms); 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_ media/libstagefright/rtsp/APacketSource.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading
media/libmediaplayerservice/nuplayer/RTSPSource.cpp +71 −5 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "AnotherPacketSource.h" #include "MyHandler.h" #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MetaData.h> namespace android { Loading Loading @@ -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; } Loading Loading @@ -255,7 +263,12 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { { size_t trackIndex; CHECK(msg->findSize("trackIndex", &trackIndex)); if (mTSParser == NULL) { CHECK_LT(trackIndex, mTracks.size()); } else { CHECK_EQ(trackIndex, 0u); } sp<ABuffer> accessUnit; CHECK(msg->findBuffer("accessUnit", &accessUnit)); Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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); Loading
media/libmediaplayerservice/nuplayer/RTSPSource.h +4 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include "NuPlayerSource.h" #include "ATSParser.h" #include <media/stagefright/foundation/AHandlerReflector.h> namespace android { Loading Loading @@ -99,6 +101,8 @@ private: sp<AnotherPacketSource> mAudioTrack; sp<AnotherPacketSource> mVideoTrack; sp<ATSParser> mTSParser; int32_t mSeekGeneration; sp<AnotherPacketSource> getSource(bool audio); Loading
media/libstagefright/rtsp/AMPEG2TSAssembler.cpp 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * 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> ¬ify, const char *desc, const AString ¶ms) : 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
media/libstagefright/rtsp/AMPEG2TSAssembler.h 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * 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> ¬ify, const char *desc, const AString ¶ms); 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_
media/libstagefright/rtsp/APacketSource.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading