зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
f99a3c942c
|
@ -1,5 +1,7 @@
|
|||
conformance/limits/gl-max-texture-dimensions.html
|
||||
conformance/misc/type-conversion-test.html
|
||||
conformance/more/conformance/quickCheckAPI-B2.html
|
||||
conformance/more/conformance/quickCheckAPI-B3.html
|
||||
conformance/more/conformance/quickCheckAPI-B4.html
|
||||
conformance/reading/read-pixels-test.html
|
||||
conformance/textures/texture-mips.html
|
||||
|
|
|
@ -79,8 +79,9 @@ bool AudioStream::sCubebLatencyPrefSet;
|
|||
/*static*/ void AudioStream::InitPreferredSampleRate()
|
||||
{
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (sPreferredSampleRate != 0 ||
|
||||
cubeb_get_preferred_sample_rate(GetCubebContextUnlocked(), &sPreferredSampleRate) != CUBEB_OK) {
|
||||
if (sPreferredSampleRate == 0 &&
|
||||
cubeb_get_preferred_sample_rate(GetCubebContextUnlocked(),
|
||||
&sPreferredSampleRate) != CUBEB_OK) {
|
||||
sPreferredSampleRate = 44100;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -711,7 +711,7 @@ MediaStreamGraphImpl::RecomputeBlockingAt(const nsTArray<MediaStream*>& aStreams
|
|||
STREAM_LOG(PR_LOG_DEBUG+1, ("MediaStream %p is blocked due to being finished", stream));
|
||||
// We'll block indefinitely
|
||||
MarkStreamBlocking(stream);
|
||||
*aEnd = aEndBlockingDecisions;
|
||||
*aEnd = std::min(*aEnd, aEndBlockingDecisions);
|
||||
continue;
|
||||
} else {
|
||||
STREAM_LOG(PR_LOG_DEBUG+1, ("MediaStream %p is finished, but not blocked yet (end at %f, with blocking at %f)",
|
||||
|
@ -734,7 +734,7 @@ MediaStreamGraphImpl::RecomputeBlockingAt(const nsTArray<MediaStream*>& aStreams
|
|||
if (underrun) {
|
||||
// We'll block indefinitely
|
||||
MarkStreamBlocking(stream);
|
||||
*aEnd = aEndBlockingDecisions;
|
||||
*aEnd = std::min(*aEnd, aEndBlockingDecisions);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ FragmentBuffer::FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration,
|
|||
, mFragDuration(aFragDuration)
|
||||
, mMediaStartTime(0)
|
||||
, mFragmentNumber(0)
|
||||
, mLastFrameTimeOfLastFragment(0)
|
||||
, mEOS(false)
|
||||
{
|
||||
mFragArray.AppendElement();
|
||||
|
|
|
@ -72,6 +72,14 @@ public:
|
|||
|
||||
uint32_t GetType() { return mTrackType; }
|
||||
|
||||
void SetLastFragmentLastFrameTime(uint32_t aTime) {
|
||||
mLastFrameTimeOfLastFragment = aTime;
|
||||
}
|
||||
|
||||
uint32_t GetLastFragmentLastFrameTime() {
|
||||
return mLastFrameTimeOfLastFragment;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mTrackType;
|
||||
|
||||
|
@ -92,6 +100,12 @@ private:
|
|||
// the current 'creating' fragment mFragNum in ISOControl.
|
||||
uint32_t mFragmentNumber;
|
||||
|
||||
// The last frame time stamp of last fragment. It is for calculating the
|
||||
// play duration of first frame in current fragment. The frame duration is
|
||||
// defined as "current frame timestamp - last frame timestamp" here. So it
|
||||
// needs to keep the last timestamp of last fragment.
|
||||
uint32_t mLastFrameTimeOfLastFragment;
|
||||
|
||||
// Array of fragments, each element has enough samples to form a
|
||||
// complete fragment.
|
||||
nsTArray<nsTArray<nsRefPtr<EncodedFrame>>> mFragArray;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "ISOTrackMetadata.h"
|
||||
#include "MP4ESDS.h"
|
||||
#include "AVCBox.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -126,19 +127,48 @@ TrackRunBox::fillSampleTable()
|
|||
}
|
||||
uint32_t len = frames.Length();
|
||||
sample_info_table = new tbl[len];
|
||||
// Create sample table according to 14496-12 8.8.8.2.
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
sample_info_table[i].sample_duration = 0;
|
||||
sample_info_table[i].sample_size = frames.ElementAt(i)->GetFrameData().Length();
|
||||
mAllSampleSize += sample_info_table[i].sample_size;
|
||||
table_size += sizeof(uint32_t);
|
||||
// Sample size.
|
||||
sample_info_table[i].sample_size = 0;
|
||||
if (flags.to_ulong() & flags_sample_size_present) {
|
||||
sample_info_table[i].sample_size = frames.ElementAt(i)->GetFrameData().Length();
|
||||
mAllSampleSize += sample_info_table[i].sample_size;
|
||||
table_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
// Sample flags.
|
||||
sample_info_table[i].sample_flags = 0;
|
||||
if (flags.to_ulong() & flags_sample_flags_present) {
|
||||
sample_info_table[i].sample_flags =
|
||||
set_sample_flags(
|
||||
(frames.ElementAt(i)->GetFrameType() == EncodedFrame::I_FRAME));
|
||||
table_size += sizeof(uint32_t);
|
||||
} else {
|
||||
sample_info_table[i].sample_flags = 0;
|
||||
}
|
||||
|
||||
// Sample duration.
|
||||
sample_info_table[i].sample_duration = 0;
|
||||
if (flags.to_ulong() & flags_sample_duration_present) {
|
||||
// Calculate each frame's duration, it is decided by "current frame
|
||||
// timestamp - last frame timestamp".
|
||||
uint64_t frame_time = 0;
|
||||
if (i == 0) {
|
||||
frame_time = frames.ElementAt(i)->GetTimeStamp() -
|
||||
frag->GetLastFragmentLastFrameTime();
|
||||
} else {
|
||||
frame_time = frames.ElementAt(i)->GetTimeStamp() -
|
||||
frames.ElementAt(i - 1)->GetTimeStamp();
|
||||
// Keep the last frame time of current fagment, it will be used to calculate
|
||||
// the first frame duration of next fragment.
|
||||
if ((len - 1) == i) {
|
||||
frag->SetLastFragmentLastFrameTime(frames.ElementAt(i)->GetTimeStamp());
|
||||
}
|
||||
}
|
||||
sample_info_table[i].sample_duration =
|
||||
frame_time * mMeta.mVidMeta->VideoFrequency / USECS_PER_S;
|
||||
table_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
sample_info_table[i].sample_composition_time_offset = 0;
|
||||
}
|
||||
return table_size;
|
||||
|
@ -180,7 +210,12 @@ TrackRunBox::Write()
|
|||
mControl->Write(data_offset);
|
||||
}
|
||||
for (uint32_t i = 0; i < sample_count; i++) {
|
||||
mControl->Write(sample_info_table[i].sample_size);
|
||||
if (flags.to_ulong() & flags_sample_duration_present) {
|
||||
mControl->Write(sample_info_table[i].sample_duration);
|
||||
}
|
||||
if (flags.to_ulong() & flags_sample_size_present) {
|
||||
mControl->Write(sample_info_table[i].sample_size);
|
||||
}
|
||||
if (flags.to_ulong() & flags_sample_flags_present) {
|
||||
mControl->Write(sample_info_table[i].sample_flags);
|
||||
}
|
||||
|
@ -197,6 +232,7 @@ TrackRunBox::TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl)
|
|||
, mAllSampleSize(0)
|
||||
, mTrackType(aType)
|
||||
{
|
||||
mMeta.Init(aControl);
|
||||
MOZ_COUNT_CTOR(TrackRunBox);
|
||||
}
|
||||
|
||||
|
@ -218,15 +254,22 @@ TrackFragmentHeaderBox::Generate(uint32_t* aBoxSize)
|
|||
track_ID = mControl->GetTrackID(mTrackType);
|
||||
size += sizeof(track_ID);
|
||||
|
||||
if (flags.to_ulong() | base_data_offset_present) {
|
||||
if (flags.to_ulong() & base_data_offset_present) {
|
||||
// base_data_offset needs to add size of 'trun', 'tfhd' and
|
||||
// header of 'mdat 'later.
|
||||
// header of 'mdat' later.
|
||||
base_data_offset = 0;
|
||||
size += sizeof(base_data_offset);
|
||||
}
|
||||
if (flags.to_ulong() | default_sample_duration_present) {
|
||||
if (flags.to_ulong() & default_sample_duration_present) {
|
||||
if (mTrackType == Video_Track) {
|
||||
default_sample_duration = mMeta.mVidMeta->VideoFrequency / mMeta.mVidMeta->FrameRate;
|
||||
if (!mMeta.mVidMeta->FrameRate) {
|
||||
// 0 means frame rate is variant, so it is wrong to write
|
||||
// default_sample_duration.
|
||||
MOZ_ASSERT(0);
|
||||
default_sample_duration = 0;
|
||||
} else {
|
||||
default_sample_duration = mMeta.mVidMeta->VideoFrequency / mMeta.mVidMeta->FrameRate;
|
||||
}
|
||||
} else if (mTrackType == Audio_Track) {
|
||||
default_sample_duration = mMeta.mAudMeta->FrameDuration;
|
||||
} else {
|
||||
|
@ -244,22 +287,19 @@ TrackFragmentHeaderBox::Write()
|
|||
{
|
||||
WRITE_FULLBOX(mControl, size)
|
||||
mControl->Write(track_ID);
|
||||
if (flags.to_ulong() | base_data_offset_present) {
|
||||
if (flags.to_ulong() & base_data_offset_present) {
|
||||
mControl->Write(base_data_offset);
|
||||
}
|
||||
if (flags.to_ulong() | default_sample_duration_present) {
|
||||
if (flags.to_ulong() & default_sample_duration_present) {
|
||||
mControl->Write(default_sample_duration);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TrackFragmentHeaderBox::TrackFragmentHeaderBox(uint32_t aType,
|
||||
uint32_t aFlags,
|
||||
ISOControl* aControl)
|
||||
// TODO: tf_flags, we may need to customize it from caller
|
||||
: FullBox(NS_LITERAL_CSTRING("tfhd"),
|
||||
0,
|
||||
base_data_offset_present | default_sample_duration_present,
|
||||
aControl)
|
||||
: FullBox(NS_LITERAL_CSTRING("tfhd"), 0, aFlags, aControl)
|
||||
, track_ID(0)
|
||||
, base_data_offset(0)
|
||||
, default_sample_duration(0)
|
||||
|
@ -274,16 +314,33 @@ TrackFragmentHeaderBox::~TrackFragmentHeaderBox()
|
|||
MOZ_COUNT_DTOR(TrackFragmentHeaderBox);
|
||||
}
|
||||
|
||||
TrackFragmentBox::TrackFragmentBox(uint32_t aType, uint32_t aFlags,
|
||||
ISOControl* aControl)
|
||||
TrackFragmentBox::TrackFragmentBox(uint32_t aType, ISOControl* aControl)
|
||||
: DefaultContainerImpl(NS_LITERAL_CSTRING("traf"), aControl)
|
||||
, mTrackType(aType)
|
||||
{
|
||||
boxes.AppendElement(new TrackFragmentHeaderBox(aType, aControl));
|
||||
// Flags in TrackFragmentHeaderBox.
|
||||
uint32_t tf_flags = base_data_offset_present;
|
||||
|
||||
// Audio frame rate should be fixed; otherwise it will cause noise when playback.
|
||||
// So it doesn't need to keep duration of each audio frame in TrackRunBox. It
|
||||
// keeps the default sample duration in TrackFragmentHeaderBox.
|
||||
tf_flags |= (mTrackType & Audio_Track ? default_sample_duration_present : 0);
|
||||
|
||||
boxes.AppendElement(new TrackFragmentHeaderBox(aType, tf_flags, aControl));
|
||||
|
||||
// Always adds flags_data_offset_present in each TrackRunBox, Android
|
||||
// parser requires this flag to calculate the correct bitstream offset.
|
||||
uint32_t tr_flags = flags_sample_size_present | flags_data_offset_present;
|
||||
|
||||
// Flags in TrackRunBox.
|
||||
// If there is no default sample duration exists, each frame duration needs to
|
||||
// be recored in the TrackRunBox.
|
||||
tr_flags |= (tf_flags & default_sample_duration_present ? 0 : flags_sample_duration_present);
|
||||
|
||||
// For video, add sample_flags to record I frame.
|
||||
aFlags |= (mTrackType & Video_Track ? flags_sample_flags_present : 0);
|
||||
boxes.AppendElement(new TrackRunBox(mTrackType, aFlags, aControl));
|
||||
tr_flags |= (mTrackType & Video_Track ? flags_sample_flags_present : 0);
|
||||
|
||||
boxes.AppendElement(new TrackRunBox(mTrackType, tr_flags, aControl));
|
||||
MOZ_COUNT_CTOR(TrackFragmentBox);
|
||||
}
|
||||
|
||||
|
@ -329,19 +386,13 @@ MovieFragmentBox::MovieFragmentBox(uint32_t aType, ISOControl* aControl)
|
|||
{
|
||||
boxes.AppendElement(new MovieFragmentHeaderBox(mTrackType, aControl));
|
||||
|
||||
// Always adds flags_data_offset_present in each TrackFragmentBox, Android
|
||||
// parser requires this flag to calculate the correct bitstream offset.
|
||||
if (mTrackType & Audio_Track) {
|
||||
boxes.AppendElement(
|
||||
new TrackFragmentBox(Audio_Track,
|
||||
flags_sample_size_present | flags_data_offset_present,
|
||||
aControl));
|
||||
new TrackFragmentBox(Audio_Track, aControl));
|
||||
}
|
||||
if (mTrackType & Video_Track) {
|
||||
boxes.AppendElement(
|
||||
new TrackFragmentBox(Video_Track,
|
||||
flags_sample_size_present | flags_data_offset_present,
|
||||
aControl));
|
||||
new TrackFragmentBox(Video_Track, aControl));
|
||||
}
|
||||
MOZ_COUNT_CTOR(MovieFragmentBox);
|
||||
}
|
||||
|
@ -388,8 +439,12 @@ TrackExtendsBox::Generate(uint32_t* aBoxSize)
|
|||
default_sample_flags = set_sample_flags(1);
|
||||
} else if (mTrackType == Video_Track) {
|
||||
default_sample_description_index = 1;
|
||||
default_sample_duration =
|
||||
mMeta.mVidMeta->VideoFrequency / mMeta.mVidMeta->FrameRate;
|
||||
// Video meta data has assigned framerate, it implies that this video's
|
||||
// frame rate should be fixed.
|
||||
if (mMeta.mVidMeta->FrameRate) {
|
||||
default_sample_duration =
|
||||
mMeta.mVidMeta->VideoFrequency / mMeta.mVidMeta->FrameRate;
|
||||
}
|
||||
default_sample_size = 0;
|
||||
default_sample_flags = set_sample_flags(0);
|
||||
} else {
|
||||
|
|
|
@ -299,6 +299,7 @@ protected:
|
|||
|
||||
uint32_t mAllSampleSize;
|
||||
uint32_t mTrackType;
|
||||
MetaHelper mMeta;
|
||||
};
|
||||
|
||||
// tf_flags in TrackFragmentHeaderBox, 14496-12 8.8.7.1.
|
||||
|
@ -327,7 +328,7 @@ public:
|
|||
nsresult UpdateBaseDataOffset(uint64_t aOffset); // The offset of the first
|
||||
// sample in file.
|
||||
|
||||
TrackFragmentHeaderBox(uint32_t aType, ISOControl* aControl);
|
||||
TrackFragmentHeaderBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
|
||||
~TrackFragmentHeaderBox();
|
||||
|
||||
protected:
|
||||
|
@ -340,7 +341,7 @@ protected:
|
|||
// TrackFragmentBox cotains TrackFragmentHeaderBox and TrackRunBox.
|
||||
class TrackFragmentBox : public DefaultContainerImpl {
|
||||
public:
|
||||
TrackFragmentBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
|
||||
TrackFragmentBox(uint32_t aType, ISOControl* aControl);
|
||||
~TrackFragmentBox();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "ISOTrackMetadata.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "MediaEncoder.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
#undef LOG
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -20,7 +21,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
const static uint32_t FRAG_DURATION = 2000000; // microsecond per unit
|
||||
const static uint32_t FRAG_DURATION = 2 * USECS_PER_S; // microsecond per unit
|
||||
|
||||
ISOMediaWriter::ISOMediaWriter(uint32_t aType)
|
||||
: ContainerWriter()
|
||||
|
|
|
@ -66,7 +66,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
|||
|
||||
static uint8_t gWebAudioOutputKey;
|
||||
|
||||
float GetSampleRateForAudioContext(bool aIsOffline, float aSampleRate)
|
||||
static float GetSampleRateForAudioContext(bool aIsOffline, float aSampleRate)
|
||||
{
|
||||
if (aIsOffline) {
|
||||
return aSampleRate;
|
||||
|
|
|
@ -3694,11 +3694,13 @@ nsDocumentViewer::PrintPreview(nsIPrintSettings* aPrintSettings,
|
|||
if (mPrintEngine->HasPrintCallbackCanvas()) {
|
||||
mBeforeAndAfterPrint = beforeAndAfterPrint;
|
||||
}
|
||||
dom::Element* root = mDocument->GetRootElement();
|
||||
dom::Element* root = doc->GetRootElement();
|
||||
if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::mozdisallowselectionprint)) {
|
||||
PR_PL(("PrintPreview: found mozdisallowselectionprint"));
|
||||
mPrintEngine->SetDisallowSelectionPrint(true);
|
||||
}
|
||||
if (root && root->HasAttr(kNameSpaceID_None, nsGkAtoms::moznomarginboxes)) {
|
||||
PR_PL(("PrintPreview: found moznomarginboxes"));
|
||||
mPrintEngine->SetNoMarginBoxes(true);
|
||||
}
|
||||
rv = mPrintEngine->PrintPreview(aPrintSettings, aChildDOMWin, aWebProgressListener);
|
||||
|
|
|
@ -1315,6 +1315,11 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsIFrame* aFrame,
|
|||
break;
|
||||
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(f))
|
||||
break;
|
||||
if (!f->GetParent() && ViewportHasDisplayPort(f->PresContext())) {
|
||||
// Viewport frames in a display port need to be animated geometry roots
|
||||
// for background-attachment:fixed elements.
|
||||
break;
|
||||
}
|
||||
nsIFrame* parent = GetCrossDocParentFrame(f);
|
||||
if (!parent)
|
||||
break;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"content/media/webspeech/synth/test/test_speech_queue.html": "Test timed out",
|
||||
"content/media/webspeech/synth/test/test_speech_simple.html": "Test timed out",
|
||||
|
||||
"content/media/webaudio/test/test_audioBufferSourceNodeOffset.html": "bug 906752",
|
||||
"content/media/webaudio/test/test_mozaudiochannel.html": "",
|
||||
|
||||
"dom/imptests/editing/selecttest/test_addRange.html": "oom?, bug 775227",
|
||||
|
|
|
@ -796,7 +796,11 @@ class XPCShellTests(object):
|
|||
|
||||
self.buildTestPath()
|
||||
|
||||
self.alltests = mp.active_tests(**mozinfo.info)
|
||||
try:
|
||||
self.alltests = mp.active_tests(**mozinfo.info)
|
||||
except TypeError:
|
||||
sys.stderr.write("*** offending mozinfo.info: %s\n" % repr(mozinfo.info))
|
||||
raise
|
||||
|
||||
if self.singleFile is None and self.totalChunks > 1:
|
||||
self.chunkTests()
|
||||
|
|
Загрузка…
Ссылка в новой задаче