mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
179 lines
4.2 KiB
C++
179 lines
4.2 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* 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 "mp4_demuxer/mp4_demuxer.h"
|
|
#include "GonkMediaDataDecoder.h"
|
|
#include "VideoUtils.h"
|
|
#include "nsTArray.h"
|
|
#include "MediaCodecProxy.h"
|
|
|
|
#include "prlog.h"
|
|
#include <android/log.h>
|
|
#define GMDD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkMediaDataDecoder(blake)", __VA_ARGS__)
|
|
|
|
#ifdef PR_LOGGING
|
|
PRLogModuleInfo* GetDemuxerLog();
|
|
#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
|
|
#else
|
|
#define LOG(...)
|
|
#endif
|
|
|
|
using namespace android;
|
|
|
|
namespace mozilla {
|
|
|
|
GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
|
|
MediaTaskQueue* aTaskQueue,
|
|
MediaDataDecoderCallback* aCallback)
|
|
: mTaskQueue(aTaskQueue)
|
|
, mCallback(aCallback)
|
|
, mManager(aManager)
|
|
, mSignaledEOS(false)
|
|
, mDrainComplete(false)
|
|
{
|
|
MOZ_COUNT_CTOR(GonkMediaDataDecoder);
|
|
}
|
|
|
|
GonkMediaDataDecoder::~GonkMediaDataDecoder()
|
|
{
|
|
MOZ_COUNT_DTOR(GonkMediaDataDecoder);
|
|
}
|
|
|
|
nsresult
|
|
GonkMediaDataDecoder::Init()
|
|
{
|
|
mDecoder = mManager->Init(mCallback);
|
|
mDrainComplete = false;
|
|
return mDecoder.get() ? NS_OK : NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
nsresult
|
|
GonkMediaDataDecoder::Shutdown()
|
|
{
|
|
mDecoder->stop();
|
|
mDecoder = nullptr;
|
|
return NS_OK;
|
|
}
|
|
|
|
// Inserts data into the decoder's pipeline.
|
|
nsresult
|
|
GonkMediaDataDecoder::Input(mp4_demuxer::MP4Sample* aSample)
|
|
{
|
|
mTaskQueue->Dispatch(
|
|
NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>(
|
|
this,
|
|
&GonkMediaDataDecoder::ProcessDecode,
|
|
nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
GonkMediaDataDecoder::ProcessDecode(mp4_demuxer::MP4Sample* aSample)
|
|
{
|
|
nsresult rv = mManager->Input(aSample);
|
|
if (rv != NS_OK) {
|
|
NS_WARNING("GonkAudioDecoder failed to input data");
|
|
GMDD_LOG("Failed to input data err: %d",rv);
|
|
mCallback->Error();
|
|
return;
|
|
}
|
|
if (aSample) {
|
|
mLastStreamOffset = aSample->byte_offset;
|
|
}
|
|
ProcessOutput();
|
|
}
|
|
|
|
void
|
|
GonkMediaDataDecoder::ProcessOutput()
|
|
{
|
|
nsRefPtr<MediaData> output;
|
|
nsresult rv;
|
|
while (true && !mDrainComplete) {
|
|
rv = mManager->Output(mLastStreamOffset, output);
|
|
if (rv == NS_OK) {
|
|
mCallback->Output(output);
|
|
continue;
|
|
} else if (rv == NS_ERROR_NOT_AVAILABLE && mSignaledEOS) {
|
|
// Try to get more frames before getting EOS frame
|
|
continue;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
|
mCallback->InputExhausted();
|
|
return;
|
|
}
|
|
if (rv != NS_OK) {
|
|
NS_WARNING("GonkMediaDataDecoder failed to output data");
|
|
GMDD_LOG("Failed to output data");
|
|
// GonkDecoderManangers report NS_ERROR_ABORT when EOS is reached.
|
|
if (rv == NS_ERROR_ABORT) {
|
|
if (output) {
|
|
mCallback->Output(output);
|
|
}
|
|
mCallback->DrainComplete();
|
|
mSignaledEOS = false;
|
|
mDrainComplete = true;
|
|
return;
|
|
}
|
|
mCallback->Error();
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
GonkMediaDataDecoder::Flush()
|
|
{
|
|
// Flush the input task queue. This cancels all pending Decode() calls.
|
|
// Note this blocks until the task queue finishes its current job, if
|
|
// it's executing at all. Note the MP4Reader ignores all output while
|
|
// flushing.
|
|
mTaskQueue->Flush();
|
|
|
|
return mManager->Flush();
|
|
}
|
|
|
|
void
|
|
GonkMediaDataDecoder::ProcessDrain()
|
|
{
|
|
// Notify decoder input EOS by sending a null data.
|
|
ProcessDecode(nullptr);
|
|
mSignaledEOS = true;
|
|
ProcessOutput();
|
|
}
|
|
|
|
nsresult
|
|
GonkMediaDataDecoder::Drain()
|
|
{
|
|
mTaskQueue->Dispatch(NS_NewRunnableMethod(this, &GonkMediaDataDecoder::ProcessDrain));
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
GonkMediaDataDecoder::IsWaitingMediaResources() {
|
|
return mDecoder->IsWaitingResources();
|
|
}
|
|
|
|
bool
|
|
GonkMediaDataDecoder::IsDormantNeeded() {
|
|
|
|
return mDecoder.get() ? true : false;
|
|
}
|
|
|
|
void
|
|
GonkMediaDataDecoder::AllocateMediaResources()
|
|
{
|
|
mManager->AllocateMediaResources();
|
|
}
|
|
|
|
void
|
|
GonkMediaDataDecoder::ReleaseMediaResources() {
|
|
mManager->ReleaseMediaResources();
|
|
}
|
|
|
|
} // namespace mozilla
|