Add MediaParser::Flush to flush the parser
Change-Id: Ic12a045dda47ccd270c8c3e9e83768e04a53ad58
This commit is contained in:
parent
77e9302aa9
commit
30cb6948e5
|
@ -146,9 +146,11 @@ Status Demuxer::Parse() {
|
|||
|
||||
int64 bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
||||
if (bytes_read <= 0) {
|
||||
return media_file_->Eof()
|
||||
? Status(error::END_OF_STREAM, "End of stream.")
|
||||
: Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
|
||||
if (media_file_->Eof()) {
|
||||
parser_->Flush();
|
||||
return Status(error::END_OF_STREAM, "");
|
||||
}
|
||||
return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
|
||||
}
|
||||
|
||||
return parser_->Parse(buffer_.get(), bytes_read)
|
||||
|
|
|
@ -55,6 +55,10 @@ class MediaParser {
|
|||
const NewSampleCB& new_sample_cb,
|
||||
const NeedKeyCB& need_key_cb) = 0;
|
||||
|
||||
/// Flush data currently in the parser and put the parser in a state where it
|
||||
/// can receive data for a new seek point.
|
||||
virtual void Flush() = 0;
|
||||
|
||||
/// Should be called when there is new data to parse.
|
||||
/// @return true if successful.
|
||||
virtual bool Parse(const uint8* buf, int size) = 0;
|
||||
|
|
|
@ -129,12 +129,12 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
|||
/// @return a human-readable string describing |*this|.
|
||||
std::string ToString() const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<MediaSample>;
|
||||
|
||||
/// Create a MediaSample. Buffer will be padded and aligned as necessary.
|
||||
/// @param data,side_data can be NULL, which indicates an empty sample.
|
||||
/// @param size,side_data_size should not be negative.
|
||||
// Create a MediaSample. Buffer will be padded and aligned as necessary.
|
||||
// |data|,|side_data| can be NULL, which indicates an empty sample.
|
||||
// |size|,|side_data_size| should not be negative.
|
||||
MediaSample(const uint8* data,
|
||||
size_t size,
|
||||
const uint8* side_data,
|
||||
|
@ -142,7 +142,6 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
|||
bool is_key_frame);
|
||||
virtual ~MediaSample();
|
||||
|
||||
private:
|
||||
// Decoding time stamp.
|
||||
int64 dts_;
|
||||
// Presentation time stamp.
|
||||
|
|
|
@ -24,9 +24,6 @@ namespace {
|
|||
// 3 bytes for the start code + 1 byte for the NALU type.
|
||||
const int kMinAUDSize = 4;
|
||||
|
||||
// Size of H.264 NALU length output by this SDK.
|
||||
const uint8 kCommonNaluLengthSize = 4;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
EsParserH264::EsParserH264(
|
||||
|
|
|
@ -55,6 +55,12 @@ void MP4MediaParser::Reset() {
|
|||
mdat_tail_ = 0;
|
||||
}
|
||||
|
||||
void MP4MediaParser::Flush() {
|
||||
DCHECK_NE(state_, kWaitingForInit);
|
||||
Reset();
|
||||
ChangeState(kParsingBoxes);
|
||||
}
|
||||
|
||||
bool MP4MediaParser::Parse(const uint8* buf, int size) {
|
||||
DCHECK_NE(state_, kWaitingForInit);
|
||||
|
||||
|
@ -295,9 +301,11 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) {
|
|||
|
||||
bool MP4MediaParser::ParseMoof(BoxReader* reader) {
|
||||
// Must already have initialization segment.
|
||||
RCHECK(moov_.get() && runs_.get());
|
||||
RCHECK(moov_.get());
|
||||
MovieFragment moof;
|
||||
RCHECK(moof.Parse(reader));
|
||||
if (!runs_)
|
||||
runs_.reset(new TrackRunIterator(moov_.get()));
|
||||
RCHECK(runs_->Init(moof));
|
||||
EmitNeedKeyIfNecessary(moof.pssh);
|
||||
ChangeState(kEmittingSamples);
|
||||
|
|
|
@ -35,6 +35,7 @@ class MP4MediaParser : public MediaParser {
|
|||
virtual void Init(const InitCB& init_cb,
|
||||
const NewSampleCB& new_sample_cb,
|
||||
const NeedKeyCB& need_key_cb) OVERRIDE;
|
||||
virtual void Flush() OVERRIDE;
|
||||
virtual bool Parse(const uint8* buf, int size) OVERRIDE;
|
||||
/// @}
|
||||
|
||||
|
|
|
@ -96,23 +96,41 @@ TEST_F(MP4MediaParserTest, MultiFragmentAppend) {
|
|||
ParseMP4File("bear-1280x720-av_frag.mp4", 768432);
|
||||
}
|
||||
|
||||
TEST_F(MP4MediaParserTest, Flush) {
|
||||
// Flush while reading sample data, then start a new stream.
|
||||
InitializeParser();
|
||||
|
||||
std::vector<uint8> buffer = ReadTestDataFile("bear-1280x720-av_frag.mp4");
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(), 65536, 512));
|
||||
parser_->Flush();
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(), buffer.size(), 512));
|
||||
}
|
||||
|
||||
TEST_F(MP4MediaParserTest, Reinitialization) {
|
||||
InitializeParser();
|
||||
|
||||
std::vector<uint8> buffer =
|
||||
ReadTestDataFile("bear-1280x720-av_frag.mp4");
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(),
|
||||
buffer.size(),
|
||||
512));
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(),
|
||||
buffer.size(),
|
||||
512));
|
||||
std::vector<uint8> buffer = ReadTestDataFile("bear-1280x720-av_frag.mp4");
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(), buffer.size(), 512));
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(), buffer.size(), 512));
|
||||
}
|
||||
|
||||
TEST_F(MP4MediaParserTest, MPEG2_AAC_LC) {
|
||||
ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512);
|
||||
}
|
||||
|
||||
// Test that a moov box is not always required after Flush() is called.
|
||||
TEST_F(MP4MediaParserTest, NoMoovAfterFlush) {
|
||||
InitializeParser();
|
||||
|
||||
std::vector<uint8> buffer = ReadTestDataFile("bear-1280x720-av_frag.mp4");
|
||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(), buffer.size(), 512));
|
||||
parser_->Flush();
|
||||
|
||||
const int kFirstMoofOffset = 1307;
|
||||
EXPECT_TRUE(AppendDataInPieces(
|
||||
buffer.data() + kFirstMoofOffset, buffer.size() - kFirstMoofOffset, 512));
|
||||
}
|
||||
|
||||
TEST_F(MP4MediaParserTest, NON_FRAGMENTED_MP4) {
|
||||
ParseMP4File("bear-1280x720.mp4", 512);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue