Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/media/platforms/omx/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 12 kB image not shown  

Quelle  PureOmxPlatformLayer.cpp   Sprache: 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 "OmxDataDecoder.h"
#include "OmxPromiseLayer.h"
#include "PureOmxPlatformLayer.h"
#include "OmxCoreLibLinker.h"

#ifdef LOG
#  undef LOG
#endif

#define LOG(arg, ...)                    \
  MOZ_LOG(                               \
      sPDMLog, mozilla::LogLevel::Debug, \
      ("PureOmxPlatformLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define LOG_BUF(arg, ...)                    \
  MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, \
          ("PureOmxBufferData(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))

namespace mozilla {

#define OMX_FUNC(func) extern typeof(func)* func;
#include "OmxFunctionList.h"
#undef OMX_FUNC

PureOmxBufferData::PureOmxBufferData(
    const PureOmxPlatformLayer& aPlatformLayer,
    const OMX_PARAM_PORTDEFINITIONTYPE& aPortDef)
    : BufferData(nullptr), mPlatformLayer(aPlatformLayer), mPortDef(aPortDef) {
  LOG_BUF("");

  if (ShouldUseEGLImage()) {
    // TODO
    LOG_BUF(
        "OMX_UseEGLImage() seems available but using it isn't implemented "
        "yet.");
  }

  OMX_ERRORTYPE err;
  err = OMX_AllocateBuffer(mPlatformLayer.GetComponent(), &mBuffer,
                           mPortDef.nPortIndex, this, mPortDef.nBufferSize);
  if (err != OMX_ErrorNone) {
    LOG_BUF("Failed to allocate the buffer!: 0x%08x", err);
  }
}

PureOmxBufferData::~PureOmxBufferData() {
  LOG_BUF("");
  ReleaseBuffer();
}

void PureOmxBufferData::ReleaseBuffer() {
  LOG_BUF("");

  if (mBuffer) {
    OMX_ERRORTYPE err;
    err = OMX_FreeBuffer(mPlatformLayer.GetComponent(), mPortDef.nPortIndex,
                         mBuffer);
    if (err != OMX_ErrorNone) {
      LOG_BUF("Failed to free the buffer!: 0x%08x", err);
    }
    mBuffer = nullptr;
  }
}

bool PureOmxBufferData::ShouldUseEGLImage() {
  OMX_ERRORTYPE err;
  err = OMX_UseEGLImage(mPlatformLayer.GetComponent(), nullptr,
                        mPortDef.nPortIndex, nullptr, nullptr);
  return (err != OMX_ErrorNotImplemented);
}

/* static */
bool PureOmxPlatformLayer::Init(void) {
  if (!OmxCoreLibLinker::Link()) {
    return false;
  }

  OMX_ERRORTYPE err = OMX_Init();
  if (err != OMX_ErrorNone) {
    MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug,
            ("PureOmxPlatformLayer::%s: Failed to initialize OMXCore: 0x%08x",
             __func__, err));
    return false;
  }

  return true;
}

/* static */
OMX_CALLBACKTYPE PureOmxPlatformLayer::sCallbacks = {
    EventHandler, EmptyBufferDone, FillBufferDone};

PureOmxPlatformLayer::PureOmxPlatformLayer(
    OmxDataDecoder* aDataDecoder, OmxPromiseLayer* aPromiseLayer,
    TaskQueue* aTaskQueue, layers::ImageContainer* aImageContainer)
    : mComponent(nullptr),
      mDataDecoder(aDataDecoder),
      mPromiseLayer(aPromiseLayer),
      mTaskQueue(aTaskQueue),
      mImageContainer(aImageContainer) {
  LOG("");
}

PureOmxPlatformLayer::~PureOmxPlatformLayer() { LOG(""); }

OMX_ERRORTYPE
PureOmxPlatformLayer::InitOmxToStateLoaded(const TrackInfo* aInfo) {
  LOG("");

  if (!aInfo) {
    return OMX_ErrorUndefined;
  }
  mInfo = aInfo;

  return CreateComponent();
}

OMX_ERRORTYPE
PureOmxPlatformLayer::EmptyThisBuffer(BufferData* aData) {
  LOG("");
  return OMX_EmptyThisBuffer(mComponent, aData->mBuffer);
}

OMX_ERRORTYPE
PureOmxPlatformLayer::FillThisBuffer(BufferData* aData) {
  LOG("");
  return OMX_FillThisBuffer(mComponent, aData->mBuffer);
}

OMX_ERRORTYPE
PureOmxPlatformLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1,
                                  OMX_PTR aCmdData) {
  LOG("aCmd: 0x%08x", aCmd);
  if (!mComponent) {
    return OMX_ErrorUndefined;
  }
  return OMX_SendCommand(mComponent, aCmd, aParam1, aCmdData);
}

nsresult PureOmxPlatformLayer::FindPortDefinition(
    OMX_DIRTYPE aType, OMX_PARAM_PORTDEFINITIONTYPE& portDef) {
  nsTArray<uint32_t> portIndex;
  GetPortIndices(portIndex);
  for (auto idx : portIndex) {
    InitOmxParameter(&portDef);
    portDef.nPortIndex = idx;

    OMX_ERRORTYPE err;
    err = GetParameter(OMX_IndexParamPortDefinition, &portDef,
                       sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    if (err != OMX_ErrorNone) {
      return NS_ERROR_FAILURE;
    } else if (portDef.eDir == aType) {
      LOG("Found OMX_IndexParamPortDefinition: port: %d, type: %d",
          portDef.nPortIndex, portDef.eDir);
      return NS_OK;
    }
  }
  return NS_ERROR_FAILURE;
}

nsresult PureOmxPlatformLayer::AllocateOmxBuffer(OMX_DIRTYPE aType,
                                                 BUFFERLIST* aBufferList) {
  LOG("aType: %d", aType);

  OMX_PARAM_PORTDEFINITIONTYPE portDef;
  nsresult result = FindPortDefinition(aType, portDef);
  if (result != NS_OK) {
    return result;
  }

  LOG("nBufferCountActual: %d, nBufferSize: %d", portDef.nBufferCountActual,
      portDef.nBufferSize);

  for (OMX_U32 i = 0; i < portDef.nBufferCountActual; ++i) {
    RefPtr<PureOmxBufferData> buffer = new PureOmxBufferData(*this, portDef);
    aBufferList->AppendElement(buffer);
  }

  return NS_OK;
}

nsresult PureOmxPlatformLayer::ReleaseOmxBuffer(OMX_DIRTYPE aType,
                                                BUFFERLIST* aBufferList) {
  LOG("aType: 0x%08x", aType);

  uint32_t len = aBufferList->Length();
  for (uint32_t i = 0; i < len; i++) {
    PureOmxBufferData* buffer =
        static_cast<PureOmxBufferData*>(aBufferList->ElementAt(i).get());

    // All raw OpenMAX buffers have to be released here to flush
    // OMX_CommandStateSet for switching the state to OMX_StateLoaded.
    // See OmxDataDecoder::DoAsyncShutdown() for more detail.
    buffer->ReleaseBuffer();
  }
  aBufferList->Clear();

  return NS_OK;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::GetState(OMX_STATETYPE* aType) {
  LOG("");

  if (mComponent) {
    return OMX_GetState(mComponent, aType);
  }

  return OMX_ErrorUndefined;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::GetParameter(OMX_INDEXTYPE aParamIndex,
                                   OMX_PTR aComponentParameterStructure,
                                   OMX_U32 aComponentParameterSize) {
  LOG("aParamIndex: 0x%08x", aParamIndex);

  if (!mComponent) {
    return OMX_ErrorUndefined;
  }

  return OMX_GetParameter(mComponent, aParamIndex,
                          aComponentParameterStructure);
}

OMX_ERRORTYPE
PureOmxPlatformLayer::SetParameter(OMX_INDEXTYPE aParamIndex,
                                   OMX_PTR aComponentParameterStructure,
                                   OMX_U32 aComponentParameterSize) {
  LOG("aParamIndex: 0x%08x", aParamIndex);

  if (!mComponent) {
    return OMX_ErrorUndefined;
  }

  return OMX_SetParameter(mComponent, aParamIndex,
                          aComponentParameterStructure);
}

nsresult PureOmxPlatformLayer::Shutdown() {
  LOG("");
  if (mComponent) {
    OMX_FreeHandle(mComponent);
    mComponent = nullptr;
  }
  mPromiseLayer = nullptr;
  mDataDecoder = nullptr;
  return NS_OK;
}

/* static */
OMX_ERRORTYPE PureOmxPlatformLayer::EventHandler(OMX_HANDLETYPE hComponent,
                                                 OMX_PTR pAppData,
                                                 OMX_EVENTTYPE eEventType,
                                                 OMX_U32 nData1, OMX_U32 nData2,
                                                 OMX_PTR pEventData) {
  PureOmxPlatformLayer* self = static_cast<PureOmxPlatformLayer*>(pAppData);
  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
      "mozilla::PureOmxPlatformLayer::EventHandler",
      [self, eEventType, nData1, nData2, pEventData]() {
        self->EventHandler(eEventType, nData1, nData2, pEventData);
      });
  nsresult rv = self->mTaskQueue->Dispatch(r.forget());
  return NS_SUCCEEDED(rv) ? OMX_ErrorNone : OMX_ErrorUndefined;
}

/* static */
OMX_ERRORTYPE PureOmxPlatformLayer::EmptyBufferDone(
    OMX_HANDLETYPE hComponent, OMX_IN OMX_PTR pAppData,
    OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
  PureOmxPlatformLayer* self = static_cast<PureOmxPlatformLayer*>(pAppData);
  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
      "mozilla::PureOmxPlatformLayer::EmptyBufferDone",
      [self, pBuffer]() { self->EmptyBufferDone(pBuffer); });
  nsresult rv = self->mTaskQueue->Dispatch(r.forget());
  return NS_SUCCEEDED(rv) ? OMX_ErrorNone : OMX_ErrorUndefined;
}

/* static */
OMX_ERRORTYPE PureOmxPlatformLayer::FillBufferDone(
    OMX_OUT OMX_HANDLETYPE hComponent, OMX_OUT OMX_PTR pAppData,
    OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
  PureOmxPlatformLayer* self = static_cast<PureOmxPlatformLayer*>(pAppData);
  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
      "mozilla::PureOmxPlatformLayer::FillBufferDone",
      [self, pBuffer]() { self->FillBufferDone(pBuffer); });
  nsresult rv = self->mTaskQueue->Dispatch(r.forget());
  return NS_SUCCEEDED(rv) ? OMX_ErrorNone : OMX_ErrorUndefined;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::EventHandler(OMX_EVENTTYPE eEventType, OMX_U32 nData1,
                                   OMX_U32 nData2, OMX_PTR pEventData) {
  bool handled = mPromiseLayer->Event(eEventType, nData1, nData2);
  LOG("eEventType: 0x%08x, handled: %d", eEventType, handled);
  return OMX_ErrorNone;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::EmptyBufferDone(OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
  PureOmxBufferData* buffer =
      static_cast<PureOmxBufferData*>(pBuffer->pAppPrivate);
  OMX_DIRTYPE portDirection = buffer->GetPortDirection();
  LOG("PortDirection: %d", portDirection);
  mPromiseLayer->EmptyFillBufferDone(portDirection, buffer);
  return OMX_ErrorNone;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::FillBufferDone(OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
  PureOmxBufferData* buffer =
      static_cast<PureOmxBufferData*>(pBuffer->pAppPrivate);
  OMX_DIRTYPE portDirection = buffer->GetPortDirection();
  LOG("PortDirection: %d", portDirection);
  mPromiseLayer->EmptyFillBufferDone(portDirection, buffer);
  return OMX_ErrorNone;
}

bool PureOmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType) {
  return FindStandardComponent(aMimeType, nullptr);
}

static bool GetStandardComponentRole(const nsACString& aMimeType,
                                     nsACString& aRole) {
  if (aMimeType.EqualsLiteral("video/avc") ||
      aMimeType.EqualsLiteral("video/mp4") ||
      aMimeType.EqualsLiteral("video/mp4v-es")) {
    aRole.Assign("video_decoder.avc");
    return true;
  } else if (aMimeType.EqualsLiteral("audio/mp4a-latm") ||
             aMimeType.EqualsLiteral("audio/mp4") ||
             aMimeType.EqualsLiteral("audio/aac")) {
    aRole.Assign("audio_decoder.aac");
    return true;
  }
  return false;
}

/* static */
bool PureOmxPlatformLayer::FindStandardComponent(const nsACString& aMimeType,
                                                 nsACString* aComponentName) {
  nsAutoCString role;
  if (!GetStandardComponentRole(aMimeType, role)) return false;

  OMX_U32 nComponents = 0;
  OMX_ERRORTYPE err;
  err = OMX_GetComponentsOfRole(const_cast<OMX_STRING>(role.Data()),
                                &nComponents, nullptr);
  if (err != OMX_ErrorNone || nComponents <= 0) {
    return false;
  }
  if (!aComponentName) {
    return true;
  }

  // TODO:
  // Only the first component will be used.
  // We should detect the most preferred component.
  OMX_U8* componentNames[1];
  UniquePtr<OMX_U8[]> componentName;
  componentName = MakeUniqueFallible<OMX_U8[]>(OMX_MAX_STRINGNAME_SIZE);
  componentNames[0] = componentName.get();
  nComponents = 1;
  err = OMX_GetComponentsOfRole(const_cast<OMX_STRING>(role.Data()),
                                &nComponents, componentNames);
  if (err == OMX_ErrorNone) {
    MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug,
            ("PureOmxPlatformLayer::%s: A component has been found for %s: %s",
             __func__, aMimeType.Data(), componentNames[0]));
    aComponentName->Assign(reinterpret_cast<char*>(componentNames[0]));
  }

  return err == OMX_ErrorNone;
}

OMX_ERRORTYPE
PureOmxPlatformLayer::CreateComponent(const nsACString* aComponentName) {
  nsAutoCString componentName;
  if (aComponentName) {
    componentName = *aComponentName;
  } else if (!FindStandardComponent(mInfo->mMimeType, &componentName)) {
    return OMX_ErrorComponentNotFound;
  }

  OMX_ERRORTYPE err;
  err = OMX_GetHandle(&mComponent, const_cast<OMX_STRING>(componentName.Data()),
                      this, &sCallbacks);

  const char* mime = mInfo->mMimeType.Data();
  if (err == OMX_ErrorNone) {
    LOG("Succeeded to create the component for %s", mime);
  } else {
    LOG("Failed to create the component for %s: 0x%08x", mime, err);
  }

  return err;
}

}  // namespace mozilla

Messung V0.5
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.