mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 879668 - Part 4: Add OmxVideoTrackEncoder to file OmxTrackEncoder. r=roc
This commit is contained in:
parent
131af2cba3
commit
fa29418b0a
13
content/media/encoder/Makefile.in
Normal file
13
content/media/encoder/Makefile.in
Normal file
@ -0,0 +1,13 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# These includes are from Android JB, for use of MediaCodec.
|
||||
INCLUDES += \
|
||||
-I$(topsrcdir)/ipc/chromium/src \
|
||||
-I$(ANDROID_SOURCE)/frameworks/native/opengl/include/ \
|
||||
-I$(ANDROID_SOURCE)/frameworks/native/include/ \
|
||||
-I$(ANDROID_SOURCE)/frameworks/av/include/media/ \
|
||||
$(NULL)
|
150
content/media/encoder/OmxTrackEncoder.cpp
Normal file
150
content/media/encoder/OmxTrackEncoder.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "OmxTrackEncoder.h"
|
||||
#include "OMXCodecWrapper.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "ISOTrackMetadata.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <android/log.h>
|
||||
#define OMX_LOG(args...) \
|
||||
do { \
|
||||
__android_log_print(ANDROID_LOG_INFO, "OmxTrackEncoder", ##args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define OMX_LOG(args, ...)
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
mFrameWidth = aWidth;
|
||||
mFrameHeight = aHeight;
|
||||
mTrackRate = aTrackRate;
|
||||
|
||||
mEncoder = OMXCodecWrapper::CreateAVCEncoder();
|
||||
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = mEncoder->Configure(mFrameWidth, mFrameHeight,
|
||||
ENCODER_CONFIG_FRAME_RATE);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
mInitialized = (rv == NS_OK);
|
||||
|
||||
mReentrantMonitor.NotifyAll();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
already_AddRefed<TrackMetadataBase>
|
||||
OmxVideoTrackEncoder::GetMetadata()
|
||||
{
|
||||
{
|
||||
// Wait if mEncoder is not initialized nor is being canceled.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
while (!mCanceled && !mInitialized) {
|
||||
mReentrantMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (mCanceled || mEncodingComplete) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<AVCTrackMetadata> meta = new AVCTrackMetadata();
|
||||
meta->Width = mFrameWidth;
|
||||
meta->Height = mFrameHeight;
|
||||
meta->FrameRate = ENCODER_CONFIG_FRAME_RATE;
|
||||
meta->VideoFrequency = 90000; // Hz
|
||||
return meta.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
OmxVideoTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
||||
{
|
||||
VideoSegment segment;
|
||||
{
|
||||
// Move all the samples from mRawSegment to segment. We only hold the
|
||||
// monitor in this block.
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
|
||||
// Wait if mEncoder is not initialized nor is being canceled.
|
||||
while (!mCanceled && (!mInitialized ||
|
||||
(mRawSegment.GetDuration() == 0 && !mEndOfStream))) {
|
||||
mReentrantMonitor.Wait();
|
||||
}
|
||||
|
||||
if (mCanceled || mEncodingComplete) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
segment.AppendFrom(&mRawSegment);
|
||||
}
|
||||
|
||||
// Start queuing raw frames to the input buffers of OMXCodecWrapper.
|
||||
VideoSegment::ChunkIterator iter(segment);
|
||||
while (!iter.IsEnded()) {
|
||||
VideoChunk chunk = *iter;
|
||||
|
||||
// Send only the unique video frames to OMXCodecWrapper.
|
||||
if (mLastFrame != chunk.mFrame) {
|
||||
uint64_t totalDurationUs = mTotalFrameDuration * USECS_PER_S / mTrackRate;
|
||||
layers::Image* img = (chunk.IsNull() || chunk.mFrame.GetForceBlack()) ?
|
||||
nullptr : chunk.mFrame.GetImage();
|
||||
mEncoder->Encode(img, mFrameWidth, mFrameHeight, totalDurationUs);
|
||||
}
|
||||
|
||||
mLastFrame.TakeFrom(&chunk.mFrame);
|
||||
mTotalFrameDuration += chunk.GetDuration();
|
||||
|
||||
iter.Next();
|
||||
}
|
||||
|
||||
// Send the EOS signal to OMXCodecWrapper.
|
||||
if (mEndOfStream && iter.IsEnded() && !mEosSetInEncoder) {
|
||||
mEosSetInEncoder = true;
|
||||
uint64_t totalDurationUs = mTotalFrameDuration * USECS_PER_S / mTrackRate;
|
||||
layers::Image* img = (!mLastFrame.GetImage() || mLastFrame.GetForceBlack())
|
||||
? nullptr : mLastFrame.GetImage();
|
||||
mEncoder->Encode(img, mFrameWidth, mFrameHeight, totalDurationUs,
|
||||
OMXCodecWrapper::BUFFER_EOS);
|
||||
}
|
||||
|
||||
// Dequeue an encoded frame from the output buffers of OMXCodecWrapper.
|
||||
nsTArray<uint8_t> buffer;
|
||||
int outFlags = 0;
|
||||
int64_t outTimeStampUs = 0;
|
||||
mEncoder->GetNextEncodedFrame(&buffer, &outTimeStampUs, &outFlags,
|
||||
GET_ENCODED_VIDEO_FRAME_TIMEOUT);
|
||||
if (!buffer.IsEmpty()) {
|
||||
nsRefPtr<EncodedFrame> videoData = new EncodedFrame();
|
||||
if (outFlags & OMXCodecWrapper::BUFFER_CODEC_CONFIG) {
|
||||
videoData->SetFrameType(EncodedFrame::AVC_CSD);
|
||||
} else {
|
||||
videoData->SetFrameType((outFlags & OMXCodecWrapper::BUFFER_SYNC_FRAME) ?
|
||||
EncodedFrame::I_FRAME : EncodedFrame::P_FRAME);
|
||||
}
|
||||
videoData->SetFrameData(&buffer);
|
||||
videoData->SetTimeStamp(outTimeStampUs);
|
||||
aData.AppendEncodedFrame(videoData);
|
||||
}
|
||||
|
||||
if (outFlags & OMXCodecWrapper::BUFFER_EOS) {
|
||||
mEncodingComplete = true;
|
||||
OMX_LOG("Done encoding video.");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
44
content/media/encoder/OmxTrackEncoder.h
Normal file
44
content/media/encoder/OmxTrackEncoder.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef OmxTrackEncoder_h_
|
||||
#define OmxTrackEncoder_h_
|
||||
|
||||
#include "TrackEncoder.h"
|
||||
|
||||
namespace android {
|
||||
class OMXVideoEncoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* There are two major classes defined in file OmxTrackEncoder;
|
||||
* OmxVideoTrackEncoder and OmxAudioTrackEncoder, the video and audio track
|
||||
* encoder for media type AVC/h.264 and AAC. OMXCodecWrapper wraps and controls
|
||||
* an instance of MediaCodec, defined in libstagefright, runs on Android Jelly
|
||||
* Bean platform.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OmxVideoTrackEncoder: public VideoTrackEncoder
|
||||
{
|
||||
public:
|
||||
OmxVideoTrackEncoder()
|
||||
: VideoTrackEncoder()
|
||||
{}
|
||||
|
||||
already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
|
||||
|
||||
nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsresult Init(int aWidth, int aHeight, TrackRate aTrackRate) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsAutoPtr<android::OMXVideoEncoder> mEncoder;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -26,7 +26,11 @@ if CONFIG['MOZ_OPUS']:
|
||||
|
||||
if CONFIG['MOZ_OMX_ENCODER']:
|
||||
DEFINES['MOZ_OMX_ENCODER'] = True
|
||||
EXPORTS += ['OmxTrackEncoder.h']
|
||||
UNIFIED_SOURCES += ['OmxTrackEncoder.cpp']
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'gklayout'
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
Loading…
Reference in New Issue
Block a user