author | Benjamin Chen <bechen@mozilla.com> |
Fri, 21 Feb 2014 14:27:41 +0800 | |
changeset 170663 | 838a38c416bd1817c71b39e28fbf561fbbeb5770 |
parent 170662 | 2cb3948fb588ecb1a06aff98e8319d5f213797ae |
child 170664 | 896d64c59638f5f172fabe70dc33b645dc8e2b6d |
push id | 40273 |
push user | ryanvm@gmail.com |
push date | Wed, 26 Feb 2014 14:05:16 +0000 |
treeherder | mozilla-inbound@f6b60344ed5f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | rillian |
bugs | 970774 |
milestone | 30.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/media/encoder/OmxTrackEncoder.cpp +++ b/content/media/encoder/OmxTrackEncoder.cpp @@ -21,21 +21,24 @@ using namespace android; namespace mozilla { #define ENCODER_CONFIG_FRAME_RATE 30 // fps #define GET_ENCODED_VIDEO_FRAME_TIMEOUT 100000 // microseconds nsresult -OmxVideoTrackEncoder::Init(int aWidth, int aHeight, TrackRate aTrackRate) +OmxVideoTrackEncoder::Init(int aWidth, int aHeight, int aDisplayWidth, + int aDisplayHeight, TrackRate aTrackRate) { mFrameWidth = aWidth; mFrameHeight = aHeight; mTrackRate = aTrackRate; + mDisplayWidth = aDisplayWidth; + mDisplayHeight = aDisplayHeight; mEncoder = OMXCodecWrapper::CreateAVCEncoder(); NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE); nsresult rv = mEncoder->Configure(mFrameWidth, mFrameHeight, ENCODER_CONFIG_FRAME_RATE); ReentrantMonitorAutoEnter mon(mReentrantMonitor);
--- a/content/media/encoder/OmxTrackEncoder.h +++ b/content/media/encoder/OmxTrackEncoder.h @@ -30,17 +30,19 @@ public: : VideoTrackEncoder() {} already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE; nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE; protected: - nsresult Init(int aWidth, int aHeight, TrackRate aTrackRate) MOZ_OVERRIDE; + nsresult Init(int aWidth, int aHeight, + int aDisplayWidth, int aDisplayHeight, + TrackRate aTrackRate) MOZ_OVERRIDE; private: nsAutoPtr<android::OMXVideoEncoder> mEncoder; }; class OmxAudioTrackEncoder MOZ_FINAL : public AudioTrackEncoder { public:
--- a/content/media/encoder/TrackEncoder.cpp +++ b/content/media/encoder/TrackEncoder.cpp @@ -158,17 +158,20 @@ VideoTrackEncoder::NotifyQueuedTrackChan // Check and initialize parameters for codec encoder. if (!mInitialized) { VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video)); while (!iter.IsEnded()) { VideoChunk chunk = *iter; if (!chunk.IsNull()) { gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize(); - nsresult rv = Init(imgsize.width, imgsize.height, aTrackRate); + gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); + nsresult rv = Init(imgsize.width, imgsize.height, + intrinsicSize.width, intrinsicSize.height, + aTrackRate); if (NS_FAILED(rv)) { LOG("[VideoTrackEncoder]: Fail to initialize the encoder!"); NotifyCancel(); } break; } iter.Next(); @@ -209,17 +212,18 @@ VideoTrackEncoder::AppendVideoSegment(co } void VideoTrackEncoder::NotifyEndOfStream() { // If source video track is muted till the end of encoding, initialize the // encoder with default frame width, frame height, and track rate. if (!mCanceled && !mInitialized) { - Init(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, DEFAULT_TRACK_RATE); + Init(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, + DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT, DEFAULT_TRACK_RATE); } ReentrantMonitorAutoEnter mon(mReentrantMonitor); mEndOfStream = true; mReentrantMonitor.NotifyAll(); } void
--- a/content/media/encoder/TrackEncoder.h +++ b/content/media/encoder/TrackEncoder.h @@ -217,16 +217,18 @@ protected: class VideoTrackEncoder : public TrackEncoder { public: VideoTrackEncoder() : TrackEncoder() , mFrameWidth(0) , mFrameHeight(0) + , mDisplayWidth(0) + , mDisplayHeight(0) , mTrackRate(0) , mTotalFrameDuration(0) {} /** * Notified by the same callbcak of MediaEncoder when it has received a track * change from MediaStreamGraph. Called on the MediaStreamGraph thread. */ @@ -239,17 +241,18 @@ public: protected: /** * Initialized the video encoder. In order to collect the value of width and * height of source frames, this initialization is delayed until we have * received the first valid video frame from MediaStreamGraph; * mReentrantMonitor will be notified after it has successfully initialized, * and this method is called on the MediaStramGraph thread. */ - virtual nsresult Init(int aWidth, int aHeight, TrackRate aTrackRate) = 0; + virtual nsresult Init(int aWidth, int aHeight, int aDisplayWidth, + int aDisplayHeight, TrackRate aTrackRate) = 0; /** * Appends source video frames to mRawSegment. We only append the source chunk * if it is unique to mLastChunk. Called on the MediaStreamGraph thread. */ nsresult AppendVideoSegment(const VideoSegment& aSegment); /** @@ -271,16 +274,26 @@ protected: int mFrameWidth; /** * The height of source video frame, ceiled if the source height is odd. */ int mFrameHeight; /** + * The display width of source video frame. + */ + int mDisplayWidth; + + /** + * The display height of source video frame. + */ + int mDisplayHeight; + + /** * The track rate of source video. */ TrackRate mTrackRate; /** * The total duration of frames in encoded video in TrackTicks, kept track of * in subclasses. */
--- a/content/media/encoder/VP8TrackEncoder.cpp +++ b/content/media/encoder/VP8TrackEncoder.cpp @@ -48,29 +48,33 @@ VP8TrackEncoder::~VP8TrackEncoder() if (mVPXImageWrapper) { vpx_img_free(mVPXImageWrapper); } MOZ_COUNT_DTOR(VP8TrackEncoder); } nsresult -VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, TrackRate aTrackRate) +VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth, + int32_t aDisplayHeight,TrackRate aTrackRate) { - if (aWidth < 1 || aHeight < 1 || aTrackRate <= 0) { + if (aWidth < 1 || aHeight < 1 || aDisplayWidth < 1 || aDisplayHeight < 1 + || aTrackRate <= 0) { return NS_ERROR_FAILURE; } ReentrantMonitorAutoEnter mon(mReentrantMonitor); mTrackRate = aTrackRate; mEncodedFrameRate = DEFAULT_ENCODE_FRAMERATE; mEncodedFrameDuration = mTrackRate / mEncodedFrameRate; mFrameWidth = aWidth; mFrameHeight = aHeight; + mDisplayWidth = aDisplayWidth; + mDisplayHeight = aDisplayHeight; // Encoder configuration structure. vpx_codec_enc_cfg_t config; memset(&config, 0, sizeof(vpx_codec_enc_cfg_t)); if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config, 0)) { return NS_ERROR_FAILURE; } @@ -148,16 +152,18 @@ VP8TrackEncoder::GetMetadata() if (mCanceled || mEncodingComplete) { return nullptr; } nsRefPtr<VP8Metadata> meta = new VP8Metadata(); meta->mWidth = mFrameWidth; meta->mHeight = mFrameHeight; + meta->mDisplayWidth = mDisplayWidth; + meta->mDisplayHeight = mDisplayHeight; meta->mEncodedFrameRate = mEncodedFrameRate; return meta.forget(); } nsresult VP8TrackEncoder::GetEncodedPartitions(EncodedFrameContainer& aData) {
--- a/content/media/encoder/VP8TrackEncoder.h +++ b/content/media/encoder/VP8TrackEncoder.h @@ -33,16 +33,17 @@ public: virtual ~VP8TrackEncoder(); already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_FINAL MOZ_OVERRIDE; nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_FINAL MOZ_OVERRIDE; protected: nsresult Init(int32_t aWidth, int32_t aHeight, + int32_t aDisplayWidth, int32_t aDisplayHeight, TrackRate aTrackRate) MOZ_FINAL MOZ_OVERRIDE; private: // Calculate the target frame's encoded duration. TrackTicks CalculateEncodedDuration(TrackTicks aDurationCopied); // Calculate the mRemainingTicks for next target frame. TrackTicks CalculateRemainingTicks(TrackTicks aDurationCopied,
--- a/content/media/webm/EbmlComposer.cpp +++ b/content/media/webm/EbmlComposer.cpp @@ -36,17 +36,18 @@ void EbmlComposer::GenerateHeader() writeSegmentInformation(&ebml, &ebmlLoc, TIME_CODE_SCALE, 0); { EbmlLoc trackLoc; Ebml_StartSubElement(&ebml, &trackLoc, Tracks); { // Video if (mWidth > 0 && mHeight > 0) { writeVideoTrack(&ebml, 0x1, 0, "V_VP8", - mWidth, mHeight, mFrameRate); + mWidth, mHeight, + mDisplayWidth, mDisplayHeight, mFrameRate); } // Audio if (mCodecPrivateData.Length() > 0) { writeAudioTrack(&ebml, 0x2, 0x0, "A_VORBIS", mSampleFreq, mChannels, mCodecPrivateData.Elements(), mCodecPrivateData.Length()); } } @@ -118,23 +119,28 @@ EbmlComposer::WriteSimpleBlock(EncodedFr } MOZ_ASSERT_IF(ebml.offset > DEFAULT_HEADER_SIZE + aFrame->GetFrameData().Length(), "write more data > EBML_BUFFER_SIZE"); mClusterBuffs.LastElement().SetLength(ebml.offset); } void EbmlComposer::SetVideoConfig(uint32_t aWidth, uint32_t aHeight, + uint32_t aDisplayWidth, uint32_t aDisplayHeight, float aFrameRate) { MOZ_ASSERT(aWidth > 0, "Width should > 0"); MOZ_ASSERT(aHeight > 0, "Height should > 0"); + MOZ_ASSERT(aDisplayWidth > 0, "DisplayWidth should > 0"); + MOZ_ASSERT(aDisplayHeight > 0, "DisplayHeight should > 0"); MOZ_ASSERT(aFrameRate > 0, "FrameRate should > 0"); mWidth = aWidth; mHeight = aHeight; + mDisplayWidth = aDisplayWidth; + mDisplayHeight = aDisplayHeight; mFrameRate = aFrameRate; } void EbmlComposer::SetAudioConfig(uint32_t aSampleFreq, uint32_t aChannels, uint32_t aBitDepth) { MOZ_ASSERT(aSampleFreq > 0, "SampleFreq should > 0");
--- a/content/media/webm/EbmlComposer.h +++ b/content/media/webm/EbmlComposer.h @@ -14,17 +14,18 @@ namespace mozilla { * A WebM muxer helper for package the valid WebM format. */ class EbmlComposer { public: EbmlComposer(); /* * Assign the parameter which header required. */ - void SetVideoConfig(uint32_t aWidth, uint32_t aHeight, float aFrameRate); + void SetVideoConfig(uint32_t aWidth, uint32_t aHeight, uint32_t aDisplayWidth, + uint32_t aDisplayHeight, float aFrameRate); void SetAudioConfig(uint32_t aSampleFreq, uint32_t aChannels, uint32_t bitDepth); /* * Set the CodecPrivateData for writing in header. */ void SetAudioCodecPrivateData(nsTArray<uint8_t>& aBufs) { @@ -59,16 +60,18 @@ private: nsTArray<uint8_t> mCodecPrivateData; // The timecode of the cluster. uint64_t mClusterTimecode; // Video configuration int mWidth; int mHeight; + int mDisplayWidth; + int mDisplayHeight; float mFrameRate; // Audio configuration float mSampleFreq; int mBitDepth; int mChannels; }; }
--- a/content/media/webm/WebMWriter.cpp +++ b/content/media/webm/WebMWriter.cpp @@ -38,16 +38,17 @@ WebMWriter::GetContainerData(nsTArray<ns nsresult WebMWriter::SetMetadata(TrackMetadataBase* aMetadata) { MOZ_ASSERT(aMetadata); if (aMetadata->GetKind() == TrackMetadataBase::METADATA_VP8) { VP8Metadata* meta = static_cast<VP8Metadata*>(aMetadata); MOZ_ASSERT(meta, "Cannot find vp8 encoder metadata"); mEbmlComposer->SetVideoConfig(meta->mWidth, meta->mHeight, + meta->mDisplayWidth, meta->mDisplayHeight, meta->mEncodedFrameRate); mMetadataRequiredFlag = mMetadataRequiredFlag & ~ContainerWriter::CREATE_VIDEO_TRACK; } if (aMetadata->GetKind() == TrackMetadataBase::METADATA_VORBIS) { VorbisMetadata* meta = static_cast<VorbisMetadata*>(aMetadata); MOZ_ASSERT(meta, "Cannot find vorbis encoder metadata"); mEbmlComposer->SetAudioConfig(meta->mSamplingFrequency, meta->mChannels, meta->mBitDepth);
--- a/content/media/webm/WebMWriter.h +++ b/content/media/webm/WebMWriter.h @@ -24,16 +24,18 @@ public: }; // VP8 meta data structure class VP8Metadata : public TrackMetadataBase { public: int32_t mWidth; int32_t mHeight; + int32_t mDisplayWidth; + int32_t mDisplayHeight; int32_t mEncodedFrameRate; MetadataKind GetKind() const MOZ_OVERRIDE { return METADATA_VP8; } }; /** * WebM writer helper * This class accepts encoder to set audio or video meta data or * encoded data to ebml Composer, and get muxing data through GetContainerData.
--- a/media/libmkv/WebMElement.c +++ b/media/libmkv/WebMElement.c @@ -52,32 +52,39 @@ static UInt64 generateTrackID(unsigned i r = r << 32; r += rand(); // UInt64 rval = t ^ r; return t ^ r; } void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight, + unsigned int displayWidth, unsigned int displayHeight, double frameRate) { EbmlLoc start; UInt64 trackID; Ebml_StartSubElement(glob, &start, TrackEntry); Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber); trackID = generateTrackID(trackNumber); Ebml_SerializeUnsigned(glob, TrackUID, trackID); Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed Ebml_SerializeUnsigned(glob, TrackType, 1); // video is always 1 Ebml_SerializeString(glob, CodecID, codecId); { EbmlLoc videoStart; Ebml_StartSubElement(glob, &videoStart, Video); Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth); Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight); + if (pixelWidth != displayWidth) { + Ebml_SerializeUnsigned(glob, DisplayWidth, displayWidth); + } + if (pixelHeight != displayHeight) { + Ebml_SerializeUnsigned(glob, DisplayHeight, displayHeight); + } Ebml_SerializeFloat(glob, FrameRate, frameRate); Ebml_EndSubElement(glob, &videoStart); // Video } Ebml_EndSubElement(glob, &start); // Track Entry } void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, const char *codecId, double samplingFrequency, unsigned int channels, unsigned char *private, unsigned long privateSize) {
--- a/media/libmkv/WebMElement.h +++ b/media/libmkv/WebMElement.h @@ -16,16 +16,17 @@ extern "C" { #include "EbmlWriter.h" // these are helper functions void writeHeader(EbmlGlobal *ebml); void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration); // this function is a helper only, it assumes a lot of defaults void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing, const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight, + unsigned int displayWidth, unsigned int displayHeight, double frameRate); void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, const char *codecId, double samplingFrequency, unsigned int channels, unsigned char *private_, unsigned long privateSize); void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode, int isKeyframe, unsigned char lacingFlag, int discardable, unsigned char *data, unsigned long dataLength);
new file mode 100644 --- /dev/null +++ b/media/libmkv/bug970774.patch @@ -0,0 +1,64 @@ +diff --git a/media/libmkv/WebMElement.c b/media/libmkv/WebMElement.c +--- a/media/libmkv/WebMElement.c ++++ b/media/libmkv/WebMElement.c +@@ -52,32 +52,39 @@ static UInt64 generateTrackID(unsigned i + r = r << 32; + r += rand(); + // UInt64 rval = t ^ r; + return t ^ r; + } + + void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, + const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight, ++ unsigned int displayWidth, unsigned int displayHeight, + double frameRate) { + EbmlLoc start; + UInt64 trackID; + Ebml_StartSubElement(glob, &start, TrackEntry); + Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber); + trackID = generateTrackID(trackNumber); + Ebml_SerializeUnsigned(glob, TrackUID, trackID); + Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed + + Ebml_SerializeUnsigned(glob, TrackType, 1); // video is always 1 + Ebml_SerializeString(glob, CodecID, codecId); + { + EbmlLoc videoStart; + Ebml_StartSubElement(glob, &videoStart, Video); + Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth); + Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight); ++ if (pixelWidth != displayWidth) { ++ Ebml_SerializeUnsigned(glob, DisplayWidth, displayWidth); ++ } ++ if (pixelHeight != displayHeight) { ++ Ebml_SerializeUnsigned(glob, DisplayHeight, displayHeight); ++ } + Ebml_SerializeFloat(glob, FrameRate, frameRate); + Ebml_EndSubElement(glob, &videoStart); // Video + } + Ebml_EndSubElement(glob, &start); // Track Entry + } + void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, + const char *codecId, double samplingFrequency, unsigned int channels, + unsigned char *private, unsigned long privateSize) { +diff --git a/media/libmkv/WebMElement.h b/media/libmkv/WebMElement.h +--- a/media/libmkv/WebMElement.h ++++ b/media/libmkv/WebMElement.h +@@ -16,16 +16,17 @@ extern "C" { + #include "EbmlWriter.h" + + // these are helper functions + void writeHeader(EbmlGlobal *ebml); + void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration); + // this function is a helper only, it assumes a lot of defaults + void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing, + const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight, ++ unsigned int displayWidth, unsigned int displayHeight, + double frameRate); + void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, + const char *codecId, double samplingFrequency, unsigned int channels, + unsigned char *private_, unsigned long privateSize); + + void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode, + int isKeyframe, unsigned char lacingFlag, int discardable, + unsigned char *data, unsigned long dataLength);
--- a/media/libmkv/update.sh +++ b/media/libmkv/update.sh @@ -30,8 +30,9 @@ else echo "Remember to update README_MOZILLA with the version details." fi # Apply any patches against upstream here. patch -p1 < source_fix.patch patch -p1 < gecko_fix.patch patch -p1 < const_fix.patch patch -p3 < bock_fix.patch +patch -p3 < bug970774.patch