diff options
Diffstat (limited to 'media')
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp | 9 | ||||
| -rw-r--r-- | media/libmediaplayerservice/nuplayer/StreamingSource.cpp | 10 | ||||
| -rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 98 | ||||
| -rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.h | 6 | ||||
| -rw-r--r-- | media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp | 5 | 
5 files changed, 101 insertions, 27 deletions
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index 0251baf..605d056 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -124,7 +124,14 @@ bool NuPlayer::HTTPLiveSource::feedMoreTSData() {                              : ATSParser::DISCONTINUITY_FORMATCHANGE,                          extra);              } else { -                mTSParser->feedTSPacket(buffer, sizeof(buffer)); +                status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); + +                if (err != OK) { +                    LOGE("TS Parser returned error %d", err); +                    mTSParser->signalEOS(err); +                    mEOS = true; +                    break; +                }              }              mOffset += n; diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp index f41e9d2..a741987 100644 --- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp +++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp @@ -86,7 +86,15 @@ bool NuPlayer::StreamingSource::feedMoreTSData() {                              : ATSParser::DISCONTINUITY_FORMATCHANGE,                          extra);              } else { -                mTSParser->feedTSPacket(buffer, sizeof(buffer)); +                status_t err = mTSParser->feedTSPacket(buffer, sizeof(buffer)); + +                if (err != OK) { +                    LOGE("TS Parser returned error %d", err); + +                    mTSParser->signalEOS(err); +                    mEOS = true; +                    break; +                }              }          }      } diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 0b7dc3d..017d01c 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -48,7 +48,7 @@ struct ATSParser::Program : public RefBase {      bool parsePID(              unsigned pid, unsigned payload_unit_start_indicator, -            ABitReader *br); +            ABitReader *br, status_t *err);      void signalDiscontinuity(              DiscontinuityType type, const sp<AMessage> &extra); @@ -77,7 +77,7 @@ private:      bool mFirstPTSValid;      uint64_t mFirstPTS; -    void parseProgramMap(ABitReader *br); +    status_t parseProgramMap(ABitReader *br);      DISALLOW_EVIL_CONSTRUCTORS(Program);  }; @@ -140,14 +140,17 @@ ATSParser::Program::Program(  bool ATSParser::Program::parsePID(          unsigned pid, unsigned payload_unit_start_indicator, -        ABitReader *br) { +        ABitReader *br, status_t *err) { +    *err = OK; +      if (pid == mProgramMapPID) {          if (payload_unit_start_indicator) {              unsigned skip = br->getBits(8);              br->skipBits(skip * 8);          } -        parseProgramMap(br); +        *err = parseProgramMap(br); +          return true;      } @@ -180,7 +183,7 @@ struct StreamInfo {      unsigned mPID;  }; -void ATSParser::Program::parseProgramMap(ABitReader *br) { +status_t ATSParser::Program::parseProgramMap(ABitReader *br) {      unsigned table_id = br->getBits(8);      LOGV("  table_id = %u", table_id);      CHECK_EQ(table_id, 0x02u); @@ -283,7 +286,60 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {      }      if (PIDsChanged) { -        mStreams.clear(); +#if 0 +        LOGI("before:"); +        for (size_t i = 0; i < mStreams.size(); ++i) { +            sp<Stream> stream = mStreams.editValueAt(i); + +            LOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type()); +        } + +        LOGI("after:"); +        for (size_t i = 0; i < infos.size(); ++i) { +            StreamInfo &info = infos.editItemAt(i); + +            LOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType); +        } +#endif + +        // The only case we can recover from is if we have two streams +        // and they switched PIDs. + +        bool success = false; + +        if (mStreams.size() == 2 && infos.size() == 2) { +            const StreamInfo &info1 = infos.itemAt(0); +            const StreamInfo &info2 = infos.itemAt(1); + +            sp<Stream> s1 = mStreams.editValueAt(0); +            sp<Stream> s2 = mStreams.editValueAt(1); + +            bool caseA = +                info1.mPID == s1->pid() && info1.mType == s2->type() +                    && info2.mPID == s2->pid() && info2.mType == s1->type(); + +            bool caseB = +                info1.mPID == s2->pid() && info1.mType == s1->type() +                    && info2.mPID == s1->pid() && info2.mType == s2->type(); + +            if (caseA || caseB) { +                unsigned pid1 = s1->pid(); +                unsigned pid2 = s2->pid(); +                s1->setPID(pid2); +                s2->setPID(pid1); + +                mStreams.clear(); +                mStreams.add(s1->pid(), s1); +                mStreams.add(s2->pid(), s2); + +                success = true; +            } +        } + +        if (!success) { +            LOGI("Stream PIDs changed and we cannot recover."); +            return ERROR_MALFORMED; +        }      }      for (size_t i = 0; i < infos.size(); ++i) { @@ -294,13 +350,10 @@ void ATSParser::Program::parseProgramMap(ABitReader *br) {          if (index < 0) {              sp<Stream> stream = new Stream(this, info.mPID, info.mType);              mStreams.add(info.mPID, stream); - -            if (PIDsChanged) { -                sp<AMessage> extra; -                stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE, extra); -            }          }      } + +    return OK;  }  sp<MediaSource> ATSParser::Program::getSource(SourceType type) { @@ -724,11 +777,11 @@ ATSParser::ATSParser(uint32_t flags)  ATSParser::~ATSParser() {  } -void ATSParser::feedTSPacket(const void *data, size_t size) { +status_t ATSParser::feedTSPacket(const void *data, size_t size) {      CHECK_EQ(size, kTSPacketSize);      ABitReader br((const uint8_t *)data, kTSPacketSize); -    parseTS(&br); +    return parseTS(&br);  }  void ATSParser::signalDiscontinuity( @@ -806,7 +859,7 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) {      MY_LOGV("  CRC = 0x%08x", br->getBits(32));  } -void ATSParser::parsePID( +status_t ATSParser::parsePID(          ABitReader *br, unsigned PID,          unsigned payload_unit_start_indicator) {      if (PID == 0) { @@ -815,13 +868,18 @@ void ATSParser::parsePID(              br->skipBits(skip * 8);          }          parseProgramAssociationTable(br); -        return; +        return OK;      }      bool handled = false;      for (size_t i = 0; i < mPrograms.size(); ++i) { +        status_t err;          if (mPrograms.editItemAt(i)->parsePID( -                    PID, payload_unit_start_indicator, br)) { +                    PID, payload_unit_start_indicator, br, &err)) { +            if (err != OK) { +                return err; +            } +              handled = true;              break;          } @@ -830,6 +888,8 @@ void ATSParser::parsePID(      if (!handled) {          LOGV("PID 0x%04x not handled.", PID);      } + +    return OK;  }  void ATSParser::parseAdaptationField(ABitReader *br) { @@ -839,7 +899,7 @@ void ATSParser::parseAdaptationField(ABitReader *br) {      }  } -void ATSParser::parseTS(ABitReader *br) { +status_t ATSParser::parseTS(ABitReader *br) {      LOGV("---");      unsigned sync_byte = br->getBits(8); @@ -870,8 +930,10 @@ void ATSParser::parseTS(ABitReader *br) {      }      if (adaptation_field_control == 1 || adaptation_field_control == 3) { -        parsePID(br, PID, payload_unit_start_indicator); +        return parsePID(br, PID, payload_unit_start_indicator);      } + +    return OK;  }  sp<MediaSource> ATSParser::getSource(SourceType type) { diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h index d12d998..388cb54 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.h +++ b/media/libstagefright/mpeg2ts/ATSParser.h @@ -49,7 +49,7 @@ struct ATSParser : public RefBase {      ATSParser(uint32_t flags = 0); -    void feedTSPacket(const void *data, size_t size); +    status_t feedTSPacket(const void *data, size_t size);      void signalDiscontinuity(              DiscontinuityType type, const sp<AMessage> &extra); @@ -89,12 +89,12 @@ private:      void parseProgramMap(ABitReader *br);      void parsePES(ABitReader *br); -    void parsePID( +    status_t parsePID(          ABitReader *br, unsigned PID,          unsigned payload_unit_start_indicator);      void parseAdaptationField(ABitReader *br); -    void parseTS(ABitReader *br); +    status_t parseTS(ABitReader *br);      DISALLOW_EVIL_CONSTRUCTORS(ATSParser);  }; diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp index 8250ad1..17cf45a 100644 --- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp +++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp @@ -210,13 +210,10 @@ status_t MPEG2TSExtractor::feedMore() {      if (n < (ssize_t)kTSPacketSize) {          return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM; -    } else { -        mParser->feedTSPacket(packet, kTSPacketSize);      }      mOffset += n; - -    return OK; +    return mParser->feedTSPacket(packet, kTSPacketSize);  }  void MPEG2TSExtractor::setLiveSession(const sp<LiveSession> &liveSession) {  | 
