|
|
|
Lines 565-581
nsresult nsOggReader::DecodeTheora(nsTArray<VideoData*>& aFrames,
|
Link Here
|
|---|
|
| 565 |
return NS_ERROR_OUT_OF_MEMORY; |
565 |
return NS_ERROR_OUT_OF_MEMORY; |
| 566 |
} |
566 |
} |
| 567 |
aFrames.AppendElement(v); |
567 |
aFrames.AppendElement(v); |
| 568 |
} |
568 |
} |
| 569 |
return NS_OK; |
569 |
return NS_OK; |
| 570 |
} |
570 |
} |
| 571 |
|
571 |
|
| 572 |
PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip, |
572 |
PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip, |
| 573 |
PRInt64 aTimeThreshold) |
573 |
PRInt64 aTimeThreshold, |
|
|
574 |
PRUint32 &aDroppedFrames) |
| 574 |
{ |
575 |
{ |
| 575 |
MonitorAutoEnter mon(mMonitor); |
576 |
MonitorAutoEnter mon(mMonitor); |
| 576 |
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(), |
577 |
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(), |
| 577 |
"Should be on state machine or AV thread."); |
578 |
"Should be on state machine or AV thread."); |
| 578 |
// We chose to keep track of the Theora granulepos ourselves, rather than |
579 |
// We chose to keep track of the Theora granulepos ourselves, rather than |
| 579 |
// rely on th_decode_packetin() to do it for us. This is because |
580 |
// rely on th_decode_packetin() to do it for us. This is because |
| 580 |
// th_decode_packetin() simply works by incrementing a counter every time |
581 |
// th_decode_packetin() simply works by incrementing a counter every time |
| 581 |
// it's called, so if we drop frames and don't call it, subsequent granulepos |
582 |
// it's called, so if we drop frames and don't call it, subsequent granulepos |
|
Lines 723-751
PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
|
Link Here
|
|---|
|
| 723 |
if (!aKeyframeSkip || |
724 |
if (!aKeyframeSkip || |
| 724 |
(th_packet_iskeyframe(&packet) == 1 && time >= aTimeThreshold)) |
725 |
(th_packet_iskeyframe(&packet) == 1 && time >= aTimeThreshold)) |
| 725 |
{ |
726 |
{ |
| 726 |
if (DecodeTheora(frames, &packet) == NS_ERROR_OUT_OF_MEMORY) { |
727 |
if (DecodeTheora(frames, &packet) == NS_ERROR_OUT_OF_MEMORY) { |
| 727 |
NS_WARNING("Theora decode memory allocation failure"); |
728 |
NS_WARNING("Theora decode memory allocation failure"); |
| 728 |
return PR_FALSE; |
729 |
return PR_FALSE; |
| 729 |
} |
730 |
} |
| 730 |
} |
731 |
} |
|
|
732 |
else { |
| 733 |
aDroppedFrames++; |
| 734 |
} |
| 731 |
} |
735 |
} |
| 732 |
|
736 |
|
| 733 |
// Push decoded data into the video frame queue. |
737 |
// Push decoded data into the video frame queue. |
| 734 |
for (PRUint32 i = 0; i < frames.Length(); i++) { |
738 |
for (PRUint32 i = 0; i < frames.Length(); i++) { |
| 735 |
nsAutoPtr<VideoData> data(frames[i]); |
739 |
nsAutoPtr<VideoData> data(frames[i]); |
| 736 |
if (!aKeyframeSkip || (aKeyframeSkip && frames[i]->mKeyframe)) { |
740 |
if (!aKeyframeSkip || (aKeyframeSkip && frames[i]->mKeyframe)) { |
| 737 |
mVideoQueue.Push(data.forget()); |
741 |
mVideoQueue.Push(data.forget()); |
| 738 |
if (aKeyframeSkip && frames[i]->mKeyframe) { |
742 |
if (aKeyframeSkip && frames[i]->mKeyframe) { |
| 739 |
aKeyframeSkip = PR_FALSE; |
743 |
aKeyframeSkip = PR_FALSE; |
| 740 |
} |
744 |
} |
| 741 |
} else { |
745 |
} else { |
| 742 |
frames[i] = nsnull; |
746 |
frames[i] = nsnull; |
| 743 |
data = nsnull; |
747 |
data = nsnull; |
|
|
748 |
aDroppedFrames++; |
| 744 |
} |
749 |
} |
| 745 |
} |
750 |
} |
| 746 |
|
751 |
|
| 747 |
if (endOfStream) { |
752 |
if (endOfStream) { |
| 748 |
// We've encountered an end of bitstream packet. Inform the queue that |
753 |
// We've encountered an end of bitstream packet. Inform the queue that |
| 749 |
// there will be no more frames. |
754 |
// there will be no more frames. |
| 750 |
mVideoQueue.Finish(); |
755 |
mVideoQueue.Finish(); |
| 751 |
} |
756 |
} |
|
Lines 1109-1125
nsresult nsOggReader::SeekInBufferedRange(PRInt64 aTarget,
|
Link Here
|
|---|
|
| 1109 |
return res; |
1114 |
return res; |
| 1110 |
} |
1115 |
} |
| 1111 |
|
1116 |
|
| 1112 |
// We have an active Theora bitstream. Decode the next Theora frame, and |
1117 |
// We have an active Theora bitstream. Decode the next Theora frame, and |
| 1113 |
// extract its keyframe's time. |
1118 |
// extract its keyframe's time. |
| 1114 |
PRBool eof; |
1119 |
PRBool eof; |
| 1115 |
do { |
1120 |
do { |
| 1116 |
PRBool skip = PR_FALSE; |
1121 |
PRBool skip = PR_FALSE; |
| 1117 |
eof = !DecodeVideoFrame(skip, 0); |
1122 |
PRUint32 droppedFrames = 0; |
|
|
1123 |
eof = !DecodeVideoFrame(skip, 0, droppedFrames); |
| 1118 |
{ |
1124 |
{ |
| 1119 |
MonitorAutoExit exitReaderMon(mMonitor); |
1125 |
MonitorAutoExit exitReaderMon(mMonitor); |
| 1120 |
MonitorAutoEnter decoderMon(mDecoder->GetMonitor()); |
1126 |
MonitorAutoEnter decoderMon(mDecoder->GetMonitor()); |
| 1121 |
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) { |
1127 |
if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) { |
| 1122 |
return NS_ERROR_FAILURE; |
1128 |
return NS_ERROR_FAILURE; |
| 1123 |
} |
1129 |
} |
| 1124 |
} |
1130 |
} |
| 1125 |
} while (!eof && |
1131 |
} while (!eof && |