зеркало из https://github.com/mozilla/gecko-dev.git
Bug 846769 - Mark Ogg frames with MediaResource offset, instead of (incorrectly) trying to infer and then use the offset of pages. r=rillian
This commit is contained in:
Родитель
1fa65593c1
Коммит
3a531b30f9
|
@ -92,7 +92,6 @@ OggReader::OggReader(AbstractMediaDecoder* aDecoder)
|
|||
mOpusSerial(0),
|
||||
mTheoraSerial(0),
|
||||
mOpusPreSkip(0),
|
||||
mPageOffset(0),
|
||||
mIsChained(false),
|
||||
mDecodedAudioFrames(0)
|
||||
{
|
||||
|
@ -184,8 +183,7 @@ nsresult OggReader::ReadMetadata(VideoInfo* aInfo,
|
|||
nsAutoTArray<OggCodecState*,4> bitstreams;
|
||||
bool readAllBOS = false;
|
||||
while (!readAllBOS) {
|
||||
int64_t pageOffset = ReadOggPage(&page);
|
||||
if (pageOffset == -1) {
|
||||
if (!ReadOggPage(&page)) {
|
||||
// Some kind of error...
|
||||
break;
|
||||
}
|
||||
|
@ -415,7 +413,7 @@ nsresult OggReader::DecodeVorbis(ogg_packet* aPacket) {
|
|||
|
||||
int64_t duration = mVorbisState->Time((int64_t)frames);
|
||||
int64_t startTime = mVorbisState->Time(endFrame - frames);
|
||||
mAudioQueue.Push(new AudioData(mPageOffset,
|
||||
mAudioQueue.Push(new AudioData(mDecoder->GetResource()->Tell(),
|
||||
startTime,
|
||||
duration,
|
||||
frames,
|
||||
|
@ -535,7 +533,7 @@ nsresult OggReader::DecodeOpus(ogg_packet* aPacket) {
|
|||
LOG(PR_LOG_DEBUG, ("Opus decoder pushing %d frames", frames));
|
||||
int64_t startTime = mOpusState->Time(startFrame);
|
||||
int64_t endTime = mOpusState->Time(endFrame);
|
||||
mAudioQueue.Push(new AudioData(mPageOffset,
|
||||
mAudioQueue.Push(new AudioData(mDecoder->GetResource()->Tell(),
|
||||
startTime,
|
||||
endTime - startTime,
|
||||
frames,
|
||||
|
@ -675,8 +673,7 @@ bool OggReader::ReadOggChain()
|
|||
}
|
||||
|
||||
ogg_page page;
|
||||
int64_t pageOffset = ReadOggPage(&page);
|
||||
if ((pageOffset == -1) || (!ogg_page_bos(&page))) {
|
||||
if (!ReadOggPage(&page) || !ogg_page_bos(&page)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -784,7 +781,7 @@ nsresult OggReader::DecodeTheora(ogg_packet* aPacket, int64_t aTimeThreshold)
|
|||
}
|
||||
|
||||
if (ret == TH_DUPFRAME) {
|
||||
VideoData* v = VideoData::CreateDuplicate(mPageOffset,
|
||||
VideoData* v = VideoData::CreateDuplicate(mDecoder->GetResource()->Tell(),
|
||||
time,
|
||||
endTime,
|
||||
aPacket->granulepos);
|
||||
|
@ -805,7 +802,7 @@ nsresult OggReader::DecodeTheora(ogg_packet* aPacket, int64_t aTimeThreshold)
|
|||
|
||||
VideoData *v = VideoData::Create(mInfo,
|
||||
mDecoder->GetImageContainer(),
|
||||
mPageOffset,
|
||||
mDecoder->GetResource()->Tell(),
|
||||
time,
|
||||
endTime,
|
||||
b,
|
||||
|
@ -873,7 +870,7 @@ bool OggReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||
return true;
|
||||
}
|
||||
|
||||
int64_t OggReader::ReadOggPage(ogg_page* aPage)
|
||||
bool OggReader::ReadOggPage(ogg_page* aPage)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
|
@ -881,7 +878,6 @@ int64_t OggReader::ReadOggPage(ogg_page* aPage)
|
|||
while((ret = ogg_sync_pageseek(&mOggState, aPage)) <= 0) {
|
||||
if (ret < 0) {
|
||||
// Lost page sync, have to skip up to next page.
|
||||
mPageOffset += -ret;
|
||||
continue;
|
||||
}
|
||||
// Returns a buffer that can be written too
|
||||
|
@ -896,19 +892,17 @@ int64_t OggReader::ReadOggPage(ogg_page* aPage)
|
|||
nsresult rv = mDecoder->GetResource()->Read(buffer, 4096, &bytesRead);
|
||||
if (NS_FAILED(rv) || (bytesRead == 0 && ret == 0)) {
|
||||
// End of file.
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
mDecoder->NotifyBytesConsumed(bytesRead);
|
||||
// Update the synchronisation layer with the number
|
||||
// of bytes written to the buffer
|
||||
ret = ogg_sync_wrote(&mOggState, bytesRead);
|
||||
NS_ENSURE_TRUE(ret == 0, -1);
|
||||
NS_ENSURE_TRUE(ret == 0, false);
|
||||
}
|
||||
int64_t offset = mPageOffset;
|
||||
mPageOffset += aPage->header_len + aPage->body_len;
|
||||
|
||||
return offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
ogg_packet* OggReader::NextOggPacket(OggCodecState* aCodecState)
|
||||
|
@ -924,7 +918,7 @@ ogg_packet* OggReader::NextOggPacket(OggCodecState* aCodecState)
|
|||
// The codec state does not have any buffered pages, so try to read another
|
||||
// page from the channel.
|
||||
ogg_page page;
|
||||
if (ReadOggPage(&page) == -1) {
|
||||
if (!ReadOggPage(&page)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1231,7 +1225,6 @@ OggReader::IndexedSeekResult OggReader::SeekToKeyframeUsingIndex(int64_t aTarget
|
|||
nsresult res = resource->Seek(nsISeekableStream::NS_SEEK_SET,
|
||||
keyframe.mKeyPoint.mOffset);
|
||||
NS_ENSURE_SUCCESS(res, SEEK_FATAL_ERROR);
|
||||
mPageOffset = keyframe.mKeyPoint.mOffset;
|
||||
|
||||
// We've moved the read set, so reset decode.
|
||||
res = ResetDecode();
|
||||
|
@ -1244,7 +1237,7 @@ OggReader::IndexedSeekResult OggReader::SeekToKeyframeUsingIndex(int64_t aTarget
|
|||
PageSyncResult syncres = PageSync(resource,
|
||||
&mOggState,
|
||||
false,
|
||||
mPageOffset,
|
||||
keyframe.mKeyPoint.mOffset,
|
||||
resource->GetLength(),
|
||||
&page,
|
||||
skippedBytes);
|
||||
|
@ -1269,7 +1262,6 @@ OggReader::IndexedSeekResult OggReader::SeekToKeyframeUsingIndex(int64_t aTarget
|
|||
// is no longer active.
|
||||
return RollbackIndexedSeek(tell);
|
||||
}
|
||||
mPageOffset = keyframe.mKeyPoint.mOffset + page.header_len + page.body_len;
|
||||
return SEEK_OK;
|
||||
}
|
||||
|
||||
|
@ -1386,7 +1378,6 @@ nsresult OggReader::Seek(int64_t aTarget,
|
|||
res = resource->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
NS_ENSURE_SUCCESS(res,res);
|
||||
|
||||
mPageOffset = 0;
|
||||
res = ResetDecode(true);
|
||||
NS_ENSURE_SUCCESS(res,res);
|
||||
|
||||
|
@ -1513,7 +1504,6 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
}
|
||||
res = resource->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
NS_ENSURE_SUCCESS(res,res);
|
||||
mPageOffset = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1627,12 +1617,6 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
skippedBytes);
|
||||
NS_ENSURE_TRUE(res != PAGE_SYNC_ERROR, NS_ERROR_FAILURE);
|
||||
|
||||
// We've located a page of length |ret| at |guess + skippedBytes|.
|
||||
// Remember where the page is located.
|
||||
pageOffset = guess + skippedBytes;
|
||||
pageLength = page.header_len + page.body_len;
|
||||
mPageOffset = pageOffset + pageLength;
|
||||
|
||||
if (res == PAGE_SYNC_END_OF_RANGE) {
|
||||
// Our guess was too close to the end, we've ended up reading the end
|
||||
// page. Backoff exponentially from the end point, in case the last
|
||||
|
@ -1642,6 +1626,11 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
continue;
|
||||
}
|
||||
|
||||
// We've located a page of length |ret| at |guess + skippedBytes|.
|
||||
// Remember where the page is located.
|
||||
pageOffset = guess + skippedBytes;
|
||||
pageLength = page.header_len + page.body_len;
|
||||
|
||||
// Read pages until we can determine the granule time of the audio and
|
||||
// video bitstream.
|
||||
ogg_int64_t audioTime = -1;
|
||||
|
@ -1674,25 +1663,25 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
videoTime = mTheoraState->StartTime(granulepos);
|
||||
}
|
||||
|
||||
if (mPageOffset == endOffset) {
|
||||
if (pageOffset + pageLength >= endOffset) {
|
||||
// Hit end of readable data.
|
||||
break;
|
||||
}
|
||||
|
||||
if (ReadOggPage(&page) == -1) {
|
||||
if (!ReadOggPage(&page)) {
|
||||
break;
|
||||
}
|
||||
|
||||
} while ((HasAudio() && audioTime == -1) ||
|
||||
(HasVideo() && videoTime == -1));
|
||||
|
||||
NS_ASSERTION(mPageOffset <= endOffset, "Page read cursor should be inside range");
|
||||
|
||||
if ((HasAudio() && audioTime == -1) ||
|
||||
(HasVideo() && videoTime == -1))
|
||||
{
|
||||
// We don't have timestamps for all active tracks...
|
||||
if (pageOffset == startOffset + startLength && mPageOffset == endOffset) {
|
||||
if (pageOffset == startOffset + startLength &&
|
||||
pageOffset + pageLength >= endOffset) {
|
||||
// We read the entire interval without finding timestamps for all
|
||||
// active tracks. We know the interval start offset is before the seek
|
||||
// target, and the interval end is after the seek target, and we can't
|
||||
|
@ -1722,7 +1711,6 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
NS_ASSERTION(startTime < aTarget, "Start time must always be less than target");
|
||||
res = resource->Seek(nsISeekableStream::NS_SEEK_SET, startOffset);
|
||||
NS_ENSURE_SUCCESS(res,res);
|
||||
mPageOffset = startOffset;
|
||||
if (NS_FAILED(ResetDecode())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1734,11 +1722,10 @@ nsresult OggReader::SeekBisection(int64_t aTarget,
|
|||
// We're within the fuzzy region in which we want to terminate the search.
|
||||
res = resource->Seek(nsISeekableStream::NS_SEEK_SET, pageOffset);
|
||||
NS_ENSURE_SUCCESS(res,res);
|
||||
mPageOffset = pageOffset;
|
||||
if (NS_FAILED(ResetDecode())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
SEEK_LOG(PR_LOG_DEBUG, ("Terminating seek at offset=%lld", mPageOffset));
|
||||
SEEK_LOG(PR_LOG_DEBUG, ("Terminating seek at offset=%lld", pageOffset));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -234,9 +234,9 @@ private:
|
|||
// not be enqueued.
|
||||
nsresult DecodeTheora(ogg_packet* aPacket, int64_t aTimeThreshold);
|
||||
|
||||
// Read a page of data from the Ogg file. Returns the offset of the start
|
||||
// of the page, or -1 if the page read failed.
|
||||
int64_t ReadOggPage(ogg_page* aPage);
|
||||
// Read a page of data from the Ogg file. Returns true if a page has been
|
||||
// read, false if the page read failed or end of file reached.
|
||||
bool ReadOggPage(ogg_page* aPage);
|
||||
|
||||
// Reads and decodes header packets for aState, until either header decode
|
||||
// fails, or is complete. Initializes the codec state before returning.
|
||||
|
@ -295,10 +295,6 @@ private:
|
|||
int mOpusPreSkip;
|
||||
th_info mTheoraInfo;
|
||||
|
||||
// The offset of the end of the last page we've read, or the start of
|
||||
// the page we're about to read.
|
||||
int64_t mPageOffset;
|
||||
|
||||
// The picture region inside Theora frame to be displayed, if we have
|
||||
// a Theora video track.
|
||||
nsIntRect mPicture;
|
||||
|
|
Загрузка…
Ссылка в новой задаче