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']:
|
if CONFIG['MOZ_OMX_ENCODER']:
|
||||||
DEFINES['MOZ_OMX_ENCODER'] = True
|
DEFINES['MOZ_OMX_ENCODER'] = True
|
||||||
|
EXPORTS += ['OmxTrackEncoder.h']
|
||||||
|
UNIFIED_SOURCES += ['OmxTrackEncoder.cpp']
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
FINAL_LIBRARY = 'gklayout'
|
FINAL_LIBRARY = 'gklayout'
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
Loading…
Reference in New Issue
Block a user