mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 970774 - Add display width/height for track encoder. r=rillian
This commit is contained in:
parent
3b5a19f7a3
commit
ae286efd04
@ -26,11 +26,14 @@ namespace mozilla {
|
|||||||
#define GET_ENCODED_VIDEO_FRAME_TIMEOUT 100000 // microseconds
|
#define GET_ENCODED_VIDEO_FRAME_TIMEOUT 100000 // microseconds
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
OmxVideoTrackEncoder::Init(int aWidth, int aHeight, TrackRate aTrackRate)
|
OmxVideoTrackEncoder::Init(int aWidth, int aHeight, int aDisplayWidth,
|
||||||
|
int aDisplayHeight, TrackRate aTrackRate)
|
||||||
{
|
{
|
||||||
mFrameWidth = aWidth;
|
mFrameWidth = aWidth;
|
||||||
mFrameHeight = aHeight;
|
mFrameHeight = aHeight;
|
||||||
mTrackRate = aTrackRate;
|
mTrackRate = aTrackRate;
|
||||||
|
mDisplayWidth = aDisplayWidth;
|
||||||
|
mDisplayHeight = aDisplayHeight;
|
||||||
|
|
||||||
mEncoder = OMXCodecWrapper::CreateAVCEncoder();
|
mEncoder = OMXCodecWrapper::CreateAVCEncoder();
|
||||||
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
||||||
|
@ -35,7 +35,9 @@ public:
|
|||||||
nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
|
nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
|
||||||
|
|
||||||
protected:
|
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:
|
private:
|
||||||
nsAutoPtr<android::OMXVideoEncoder> mEncoder;
|
nsAutoPtr<android::OMXVideoEncoder> mEncoder;
|
||||||
|
@ -163,7 +163,10 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
|||||||
VideoChunk chunk = *iter;
|
VideoChunk chunk = *iter;
|
||||||
if (!chunk.IsNull()) {
|
if (!chunk.IsNull()) {
|
||||||
gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
|
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)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
|
LOG("[VideoTrackEncoder]: Fail to initialize the encoder!");
|
||||||
NotifyCancel();
|
NotifyCancel();
|
||||||
@ -214,7 +217,8 @@ VideoTrackEncoder::NotifyEndOfStream()
|
|||||||
// If source video track is muted till the end of encoding, initialize the
|
// If source video track is muted till the end of encoding, initialize the
|
||||||
// encoder with default frame width, frame height, and track rate.
|
// encoder with default frame width, frame height, and track rate.
|
||||||
if (!mCanceled && !mInitialized) {
|
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);
|
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||||
|
@ -222,6 +222,8 @@ public:
|
|||||||
: TrackEncoder()
|
: TrackEncoder()
|
||||||
, mFrameWidth(0)
|
, mFrameWidth(0)
|
||||||
, mFrameHeight(0)
|
, mFrameHeight(0)
|
||||||
|
, mDisplayWidth(0)
|
||||||
|
, mDisplayHeight(0)
|
||||||
, mTrackRate(0)
|
, mTrackRate(0)
|
||||||
, mTotalFrameDuration(0)
|
, mTotalFrameDuration(0)
|
||||||
{}
|
{}
|
||||||
@ -244,7 +246,8 @@ protected:
|
|||||||
* mReentrantMonitor will be notified after it has successfully initialized,
|
* mReentrantMonitor will be notified after it has successfully initialized,
|
||||||
* and this method is called on the MediaStramGraph thread.
|
* 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
|
* Appends source video frames to mRawSegment. We only append the source chunk
|
||||||
@ -275,6 +278,16 @@ protected:
|
|||||||
*/
|
*/
|
||||||
int mFrameHeight;
|
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.
|
* The track rate of source video.
|
||||||
*/
|
*/
|
||||||
|
@ -53,9 +53,11 @@ VP8TrackEncoder::~VP8TrackEncoder()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
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;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +68,8 @@ VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, TrackRate aTrackRate)
|
|||||||
mEncodedFrameDuration = mTrackRate / mEncodedFrameRate;
|
mEncodedFrameDuration = mTrackRate / mEncodedFrameRate;
|
||||||
mFrameWidth = aWidth;
|
mFrameWidth = aWidth;
|
||||||
mFrameHeight = aHeight;
|
mFrameHeight = aHeight;
|
||||||
|
mDisplayWidth = aDisplayWidth;
|
||||||
|
mDisplayHeight = aDisplayHeight;
|
||||||
|
|
||||||
// Encoder configuration structure.
|
// Encoder configuration structure.
|
||||||
vpx_codec_enc_cfg_t config;
|
vpx_codec_enc_cfg_t config;
|
||||||
@ -153,6 +157,8 @@ VP8TrackEncoder::GetMetadata()
|
|||||||
nsRefPtr<VP8Metadata> meta = new VP8Metadata();
|
nsRefPtr<VP8Metadata> meta = new VP8Metadata();
|
||||||
meta->mWidth = mFrameWidth;
|
meta->mWidth = mFrameWidth;
|
||||||
meta->mHeight = mFrameHeight;
|
meta->mHeight = mFrameHeight;
|
||||||
|
meta->mDisplayWidth = mDisplayWidth;
|
||||||
|
meta->mDisplayHeight = mDisplayHeight;
|
||||||
meta->mEncodedFrameRate = mEncodedFrameRate;
|
meta->mEncodedFrameRate = mEncodedFrameRate;
|
||||||
|
|
||||||
return meta.forget();
|
return meta.forget();
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult Init(int32_t aWidth, int32_t aHeight,
|
nsresult Init(int32_t aWidth, int32_t aHeight,
|
||||||
|
int32_t aDisplayWidth, int32_t aDisplayHeight,
|
||||||
TrackRate aTrackRate) MOZ_FINAL MOZ_OVERRIDE;
|
TrackRate aTrackRate) MOZ_FINAL MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,7 +41,8 @@ void EbmlComposer::GenerateHeader()
|
|||||||
// Video
|
// Video
|
||||||
if (mWidth > 0 && mHeight > 0) {
|
if (mWidth > 0 && mHeight > 0) {
|
||||||
writeVideoTrack(&ebml, 0x1, 0, "V_VP8",
|
writeVideoTrack(&ebml, 0x1, 0, "V_VP8",
|
||||||
mWidth, mHeight, mFrameRate);
|
mWidth, mHeight,
|
||||||
|
mDisplayWidth, mDisplayHeight, mFrameRate);
|
||||||
}
|
}
|
||||||
// Audio
|
// Audio
|
||||||
if (mCodecPrivateData.Length() > 0) {
|
if (mCodecPrivateData.Length() > 0) {
|
||||||
@ -123,13 +124,18 @@ EbmlComposer::WriteSimpleBlock(EncodedFrame* aFrame)
|
|||||||
|
|
||||||
void
|
void
|
||||||
EbmlComposer::SetVideoConfig(uint32_t aWidth, uint32_t aHeight,
|
EbmlComposer::SetVideoConfig(uint32_t aWidth, uint32_t aHeight,
|
||||||
|
uint32_t aDisplayWidth, uint32_t aDisplayHeight,
|
||||||
float aFrameRate)
|
float aFrameRate)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWidth > 0, "Width should > 0");
|
MOZ_ASSERT(aWidth > 0, "Width should > 0");
|
||||||
MOZ_ASSERT(aHeight > 0, "Height 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");
|
MOZ_ASSERT(aFrameRate > 0, "FrameRate should > 0");
|
||||||
mWidth = aWidth;
|
mWidth = aWidth;
|
||||||
mHeight = aHeight;
|
mHeight = aHeight;
|
||||||
|
mDisplayWidth = aDisplayWidth;
|
||||||
|
mDisplayHeight = aDisplayHeight;
|
||||||
mFrameRate = aFrameRate;
|
mFrameRate = aFrameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,8 @@ public:
|
|||||||
/*
|
/*
|
||||||
* Assign the parameter which header required.
|
* 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,
|
void SetAudioConfig(uint32_t aSampleFreq, uint32_t aChannels,
|
||||||
uint32_t bitDepth);
|
uint32_t bitDepth);
|
||||||
@ -64,6 +65,8 @@ private:
|
|||||||
// Video configuration
|
// Video configuration
|
||||||
int mWidth;
|
int mWidth;
|
||||||
int mHeight;
|
int mHeight;
|
||||||
|
int mDisplayWidth;
|
||||||
|
int mDisplayHeight;
|
||||||
float mFrameRate;
|
float mFrameRate;
|
||||||
// Audio configuration
|
// Audio configuration
|
||||||
float mSampleFreq;
|
float mSampleFreq;
|
||||||
|
@ -43,6 +43,7 @@ WebMWriter::SetMetadata(TrackMetadataBase* aMetadata)
|
|||||||
VP8Metadata* meta = static_cast<VP8Metadata*>(aMetadata);
|
VP8Metadata* meta = static_cast<VP8Metadata*>(aMetadata);
|
||||||
MOZ_ASSERT(meta, "Cannot find vp8 encoder metadata");
|
MOZ_ASSERT(meta, "Cannot find vp8 encoder metadata");
|
||||||
mEbmlComposer->SetVideoConfig(meta->mWidth, meta->mHeight,
|
mEbmlComposer->SetVideoConfig(meta->mWidth, meta->mHeight,
|
||||||
|
meta->mDisplayWidth, meta->mDisplayHeight,
|
||||||
meta->mEncodedFrameRate);
|
meta->mEncodedFrameRate);
|
||||||
mMetadataRequiredFlag = mMetadataRequiredFlag & ~ContainerWriter::CREATE_VIDEO_TRACK;
|
mMetadataRequiredFlag = mMetadataRequiredFlag & ~ContainerWriter::CREATE_VIDEO_TRACK;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ class VP8Metadata : public TrackMetadataBase
|
|||||||
public:
|
public:
|
||||||
int32_t mWidth;
|
int32_t mWidth;
|
||||||
int32_t mHeight;
|
int32_t mHeight;
|
||||||
|
int32_t mDisplayWidth;
|
||||||
|
int32_t mDisplayHeight;
|
||||||
int32_t mEncodedFrameRate;
|
int32_t mEncodedFrameRate;
|
||||||
MetadataKind GetKind() const MOZ_OVERRIDE { return METADATA_VP8; }
|
MetadataKind GetKind() const MOZ_OVERRIDE { return METADATA_VP8; }
|
||||||
};
|
};
|
||||||
|
@ -57,6 +57,7 @@ static UInt64 generateTrackID(unsigned int trackNumber) {
|
|||||||
|
|
||||||
void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
|
void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
|
||||||
const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
|
const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
|
||||||
|
unsigned int displayWidth, unsigned int displayHeight,
|
||||||
double frameRate) {
|
double frameRate) {
|
||||||
EbmlLoc start;
|
EbmlLoc start;
|
||||||
UInt64 trackID;
|
UInt64 trackID;
|
||||||
@ -73,6 +74,12 @@ void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
|
|||||||
Ebml_StartSubElement(glob, &videoStart, Video);
|
Ebml_StartSubElement(glob, &videoStart, Video);
|
||||||
Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
|
Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
|
||||||
Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
|
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_SerializeFloat(glob, FrameRate, frameRate);
|
||||||
Ebml_EndSubElement(glob, &videoStart); // Video
|
Ebml_EndSubElement(glob, &videoStart); // Video
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long
|
|||||||
// this function is a helper only, it assumes a lot of defaults
|
// this function is a helper only, it assumes a lot of defaults
|
||||||
void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
|
void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
|
||||||
const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
|
const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
|
||||||
|
unsigned int displayWidth, unsigned int displayHeight,
|
||||||
double frameRate);
|
double frameRate);
|
||||||
void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
|
void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
|
||||||
const char *codecId, double samplingFrequency, unsigned int channels,
|
const char *codecId, double samplingFrequency, unsigned int channels,
|
||||||
|
64
media/libmkv/bug970774.patch
Normal file
64
media/libmkv/bug970774.patch
Normal file
@ -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);
|
@ -35,3 +35,4 @@ patch -p1 < source_fix.patch
|
|||||||
patch -p1 < gecko_fix.patch
|
patch -p1 < gecko_fix.patch
|
||||||
patch -p1 < const_fix.patch
|
patch -p1 < const_fix.patch
|
||||||
patch -p3 < bock_fix.patch
|
patch -p3 < bock_fix.patch
|
||||||
|
patch -p3 < bug970774.patch
|
||||||
|
Loading…
Reference in New Issue
Block a user