LCOV - code coverage report
Current view: top level - dom/media/platforms/omx - OmxPromiseLayer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 186 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "OmxPromiseLayer.h"
       8             : 
       9             : #include "ImageContainer.h"
      10             : 
      11             : #include "OmxDataDecoder.h"
      12             : #include "OmxPlatformLayer.h"
      13             : 
      14             : 
      15             : #ifdef LOG
      16             : #undef LOG
      17             : #endif
      18             : 
      19             : #define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("OmxPromiseLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
      20             : 
      21             : namespace mozilla {
      22             : 
      23           0 : OmxPromiseLayer::OmxPromiseLayer(TaskQueue* aTaskQueue,
      24             :                                  OmxDataDecoder* aDataDecoder,
      25           0 :                                  layers::ImageContainer* aImageContainer)
      26           0 :   : mTaskQueue(aTaskQueue)
      27             : {
      28             :   mPlatformLayer = OmxPlatformLayer::Create(aDataDecoder,
      29             :                                             this,
      30             :                                             aTaskQueue,
      31           0 :                                             aImageContainer);
      32           0 :   MOZ_ASSERT(!!mPlatformLayer);
      33           0 : }
      34             : 
      35             : RefPtr<OmxPromiseLayer::OmxCommandPromise>
      36           0 : OmxPromiseLayer::Init(const TrackInfo* aInfo)
      37             : {
      38           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
      39             : 
      40           0 :   OMX_ERRORTYPE err = mPlatformLayer->InitOmxToStateLoaded(aInfo);
      41           0 :   if (err != OMX_ErrorNone) {
      42           0 :     OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandStateSet);
      43           0 :     return OmxCommandPromise::CreateAndReject(failure, __func__);
      44             :   }
      45             : 
      46           0 :   OMX_STATETYPE state = GetState();
      47           0 :   if (state ==  OMX_StateLoaded) {
      48           0 :     return OmxCommandPromise::CreateAndResolve(OMX_CommandStateSet, __func__);
      49           0 :   } if (state == OMX_StateIdle) {
      50           0 :     return SendCommand(OMX_CommandStateSet, OMX_StateIdle, nullptr);
      51             :   }
      52             : 
      53           0 :   OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandStateSet);
      54           0 :   return OmxCommandPromise::CreateAndReject(failure, __func__);
      55             : }
      56             : 
      57             : OMX_ERRORTYPE
      58           0 : OmxPromiseLayer::Config()
      59             : {
      60           0 :   MOZ_ASSERT(GetState() == OMX_StateLoaded);
      61             : 
      62           0 :   return mPlatformLayer->Config();
      63             : }
      64             : 
      65             : RefPtr<OmxPromiseLayer::OmxBufferPromise>
      66           0 : OmxPromiseLayer::FillBuffer(BufferData* aData)
      67             : {
      68           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
      69           0 :   LOG("buffer %p", aData->mBuffer);
      70             : 
      71           0 :   RefPtr<OmxBufferPromise> p = aData->mPromise.Ensure(__func__);
      72             : 
      73           0 :   OMX_ERRORTYPE err = mPlatformLayer->FillThisBuffer(aData);
      74             : 
      75           0 :   if (err != OMX_ErrorNone) {
      76           0 :     OmxBufferFailureHolder failure(err, aData);
      77           0 :     aData->mPromise.Reject(Move(failure), __func__);
      78             :   } else {
      79           0 :     aData->mStatus = BufferData::BufferStatus::OMX_COMPONENT;
      80           0 :     GetBufferHolders(OMX_DirOutput)->AppendElement(aData);
      81             :   }
      82             : 
      83           0 :   return p;
      84             : }
      85             : 
      86             : RefPtr<OmxPromiseLayer::OmxBufferPromise>
      87           0 : OmxPromiseLayer::EmptyBuffer(BufferData* aData)
      88             : {
      89           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
      90           0 :   LOG("buffer %p, size %lu", aData->mBuffer, aData->mBuffer->nFilledLen);
      91             : 
      92           0 :   RefPtr<OmxBufferPromise> p = aData->mPromise.Ensure(__func__);
      93             : 
      94           0 :   OMX_ERRORTYPE err = mPlatformLayer->EmptyThisBuffer(aData);
      95             : 
      96           0 :   if (err != OMX_ErrorNone) {
      97           0 :     OmxBufferFailureHolder failure(err, aData);
      98           0 :     aData->mPromise.Reject(Move(failure), __func__);
      99             :   } else {
     100           0 :     if (aData->mRawData) {
     101           0 :       mRawDatas.AppendElement(Move(aData->mRawData));
     102             :     }
     103           0 :     aData->mStatus = BufferData::BufferStatus::OMX_COMPONENT;
     104           0 :     GetBufferHolders(OMX_DirInput)->AppendElement(aData);
     105             :   }
     106             : 
     107           0 :   return p;
     108             : }
     109             : 
     110             : OmxPromiseLayer::BUFFERLIST*
     111           0 : OmxPromiseLayer::GetBufferHolders(OMX_DIRTYPE aType)
     112             : {
     113           0 :   MOZ_ASSERT(aType == OMX_DirInput || aType == OMX_DirOutput);
     114             : 
     115           0 :   if (aType == OMX_DirInput) {
     116           0 :     return &mInbufferHolders;
     117             :   }
     118             : 
     119           0 :   return &mOutbufferHolders;
     120             : }
     121             : 
     122             : already_AddRefed<MediaRawData>
     123           0 : OmxPromiseLayer::FindAndRemoveRawData(OMX_TICKS aTimecode)
     124             : {
     125           0 :   for (auto raw : mRawDatas) {
     126           0 :     if (raw->mTime.ToMicroseconds() == aTimecode) {
     127           0 :       mRawDatas.RemoveElement(raw);
     128           0 :       return raw.forget();
     129             :     }
     130             :   }
     131           0 :   return nullptr;
     132             : }
     133             : 
     134             : already_AddRefed<BufferData>
     135           0 : OmxPromiseLayer::FindAndRemoveBufferHolder(OMX_DIRTYPE aType,
     136             :                                            BufferData::BufferID aId)
     137             : {
     138           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     139             : 
     140           0 :   RefPtr<BufferData> holder;
     141           0 :   BUFFERLIST* holders = GetBufferHolders(aType);
     142             : 
     143           0 :   for (uint32_t i = 0; i < holders->Length(); i++) {
     144           0 :     if (holders->ElementAt(i)->ID() == aId) {
     145           0 :       holder = holders->ElementAt(i);
     146           0 :       holders->RemoveElementAt(i);
     147           0 :       return holder.forget();
     148             :     }
     149             :   }
     150             : 
     151           0 :   return nullptr;
     152             : }
     153             : 
     154             : already_AddRefed<BufferData>
     155           0 : OmxPromiseLayer::FindBufferById(OMX_DIRTYPE aType, BufferData::BufferID aId)
     156             : {
     157           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     158             : 
     159           0 :   RefPtr<BufferData> holder;
     160           0 :   BUFFERLIST* holders = GetBufferHolders(aType);
     161             : 
     162           0 :   for (uint32_t i = 0; i < holders->Length(); i++) {
     163           0 :     if (holders->ElementAt(i)->ID() == aId) {
     164           0 :       holder = holders->ElementAt(i);
     165           0 :       return holder.forget();
     166             :     }
     167             :   }
     168             : 
     169           0 :   return nullptr;
     170             : }
     171             : 
     172             : void
     173           0 : OmxPromiseLayer::EmptyFillBufferDone(OMX_DIRTYPE aType, BufferData* aData)
     174             : {
     175           0 :   if (aData) {
     176           0 :     LOG("type %d, buffer %p", aType, aData->mBuffer);
     177           0 :     if (aType == OMX_DirOutput) {
     178           0 :       aData->mRawData = nullptr;
     179           0 :       aData->mRawData = FindAndRemoveRawData(aData->mBuffer->nTimeStamp);
     180             :     }
     181           0 :     aData->mStatus = BufferData::BufferStatus::OMX_CLIENT;
     182           0 :     aData->mPromise.Resolve(aData, __func__);
     183             :   } else {
     184           0 :     LOG("type %d, no buffer", aType);
     185             :   }
     186           0 : }
     187             : 
     188             : void
     189           0 : OmxPromiseLayer::EmptyFillBufferDone(OMX_DIRTYPE aType, BufferData::BufferID aID)
     190             : {
     191           0 :   RefPtr<BufferData> holder = FindAndRemoveBufferHolder(aType, aID);
     192           0 :   EmptyFillBufferDone(aType, holder);
     193           0 : }
     194             : 
     195             : RefPtr<OmxPromiseLayer::OmxCommandPromise>
     196           0 : OmxPromiseLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1, OMX_PTR aCmdData)
     197             : {
     198           0 :   if (aCmd == OMX_CommandFlush) {
     199             :     // It doesn't support another flush commands before previous one is completed.
     200           0 :     MOZ_RELEASE_ASSERT(!mFlushCommands.Length());
     201             : 
     202             :     // Some coomponents don't send event with OMX_ALL, they send flush complete
     203             :     // event with input port and another event for output port.
     204             :     // In prupose of better compatibility, we interpret the OMX_ALL to OMX_DirInput
     205             :     // and OMX_DirOutput flush separately.
     206           0 :     OMX_DIRTYPE types[] = {OMX_DIRTYPE::OMX_DirInput, OMX_DIRTYPE::OMX_DirOutput};
     207           0 :     for(const auto type : types) {
     208           0 :       if ((aParam1 == type) || (aParam1 == OMX_ALL)) {
     209           0 :         mFlushCommands.AppendElement(FlushCommand({type, aCmdData}));
     210             :       }
     211             : 
     212           0 :       if (type == OMX_DirInput) {
     213             :         // Clear all buffered raw data.
     214           0 :         mRawDatas.Clear();
     215             :       }
     216             :     }
     217             : 
     218             :     // Don't overlay more than one flush command, some components can't overlay flush commands.
     219             :     // So here we send another flush after receiving the previous flush completed event.
     220           0 :     if (mFlushCommands.Length()) {
     221             :       OMX_ERRORTYPE err =
     222           0 :         mPlatformLayer->SendCommand(OMX_CommandFlush,
     223           0 :                                     mFlushCommands.ElementAt(0).type,
     224           0 :                                     mFlushCommands.ElementAt(0).cmd);
     225           0 :       if (err != OMX_ErrorNone) {
     226           0 :         OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
     227           0 :         return OmxCommandPromise::CreateAndReject(failure, __func__);
     228             :       }
     229             :     } else {
     230           0 :       LOG("OMX_CommandFlush parameter error");
     231           0 :       OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
     232           0 :       return OmxCommandPromise::CreateAndReject(failure, __func__);
     233             :     }
     234             :   } else {
     235           0 :     OMX_ERRORTYPE err = mPlatformLayer->SendCommand(aCmd, aParam1, aCmdData);
     236           0 :     if (err != OMX_ErrorNone) {
     237           0 :       OmxCommandFailureHolder failure(OMX_ErrorNotReady, aCmd);
     238           0 :       return OmxCommandPromise::CreateAndReject(failure, __func__);
     239             :     }
     240             :   }
     241             : 
     242           0 :   RefPtr<OmxCommandPromise> p;
     243           0 :   if (aCmd == OMX_CommandStateSet) {
     244           0 :     p = mCommandStatePromise.Ensure(__func__);
     245           0 :   } else if (aCmd == OMX_CommandFlush) {
     246           0 :     p = mFlushPromise.Ensure(__func__);
     247           0 :   } else if (aCmd == OMX_CommandPortEnable) {
     248           0 :     p = mPortEnablePromise.Ensure(__func__);
     249           0 :   } else if (aCmd == OMX_CommandPortDisable) {
     250           0 :     p = mPortDisablePromise.Ensure(__func__);
     251             :   } else {
     252           0 :     LOG("error unsupport command");
     253           0 :     MOZ_ASSERT(0);
     254             :   }
     255             : 
     256           0 :   return p;
     257             : }
     258             : 
     259             : bool
     260           0 : OmxPromiseLayer::Event(OMX_EVENTTYPE aEvent, OMX_U32 aData1, OMX_U32 aData2)
     261             : {
     262           0 :   OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) aData1;
     263           0 :   switch (aEvent) {
     264             :     case OMX_EventCmdComplete:
     265             :     {
     266           0 :       if (cmd == OMX_CommandStateSet) {
     267           0 :         mCommandStatePromise.Resolve(OMX_CommandStateSet, __func__);
     268           0 :       } else if (cmd == OMX_CommandFlush) {
     269           0 :         MOZ_RELEASE_ASSERT(mFlushCommands.ElementAt(0).type == aData2);
     270           0 :         LOG("OMX_CommandFlush completed port type %lu", aData2);
     271           0 :         mFlushCommands.RemoveElementAt(0);
     272             : 
     273             :         // Sending next flush command.
     274           0 :         if (mFlushCommands.Length()) {
     275             :           OMX_ERRORTYPE err =
     276           0 :             mPlatformLayer->SendCommand(OMX_CommandFlush,
     277           0 :                                         mFlushCommands.ElementAt(0).type,
     278           0 :                                         mFlushCommands.ElementAt(0).cmd);
     279           0 :           if (err != OMX_ErrorNone) {
     280           0 :             OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
     281           0 :             mFlushPromise.Reject(failure, __func__);
     282             :           }
     283             :         } else {
     284           0 :           mFlushPromise.Resolve(OMX_CommandFlush, __func__);
     285             :         }
     286           0 :       } else if (cmd == OMX_CommandPortDisable) {
     287           0 :         mPortDisablePromise.Resolve(OMX_CommandPortDisable, __func__);
     288           0 :       } else if (cmd == OMX_CommandPortEnable) {
     289           0 :         mPortEnablePromise.Resolve(OMX_CommandPortEnable, __func__);
     290             :       }
     291           0 :       break;
     292             :     }
     293             :     case OMX_EventError:
     294             :     {
     295           0 :       if (cmd == OMX_CommandStateSet) {
     296           0 :         OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandStateSet);
     297           0 :         mCommandStatePromise.Reject(failure, __func__);
     298           0 :       } else if (cmd == OMX_CommandFlush) {
     299           0 :         OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandFlush);
     300           0 :         mFlushPromise.Reject(failure, __func__);
     301           0 :       } else if (cmd == OMX_CommandPortDisable) {
     302           0 :         OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandPortDisable);
     303           0 :         mPortDisablePromise.Reject(failure, __func__);
     304           0 :       } else if (cmd == OMX_CommandPortEnable) {
     305           0 :         OmxCommandFailureHolder failure(OMX_ErrorUndefined, OMX_CommandPortEnable);
     306           0 :         mPortEnablePromise.Reject(failure, __func__);
     307             :       } else {
     308           0 :         return false;
     309             :       }
     310           0 :       break;
     311             :     }
     312             :     default:
     313             :     {
     314           0 :       return false;
     315             :     }
     316             :   }
     317           0 :   return true;
     318             : }
     319             : 
     320             : nsresult
     321           0 : OmxPromiseLayer::AllocateOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBuffers)
     322             : {
     323           0 :   return mPlatformLayer->AllocateOmxBuffer(aType, aBuffers);
     324             : }
     325             : 
     326             : nsresult
     327           0 : OmxPromiseLayer::ReleaseOmxBuffer(OMX_DIRTYPE aType, BUFFERLIST* aBuffers)
     328             : {
     329           0 :   return mPlatformLayer->ReleaseOmxBuffer(aType, aBuffers);
     330             : }
     331             : 
     332             : OMX_STATETYPE
     333           0 : OmxPromiseLayer::GetState()
     334             : {
     335             :   OMX_STATETYPE state;
     336           0 :   OMX_ERRORTYPE err = mPlatformLayer->GetState(&state);
     337           0 :   return err == OMX_ErrorNone ? state : OMX_StateInvalid;
     338             : }
     339             : 
     340             : OMX_ERRORTYPE
     341           0 : OmxPromiseLayer::GetParameter(OMX_INDEXTYPE aParamIndex,
     342             :                               OMX_PTR aComponentParameterStructure,
     343             :                               OMX_U32 aComponentParameterSize)
     344             : {
     345           0 :   return mPlatformLayer->GetParameter(aParamIndex,
     346             :                                       aComponentParameterStructure,
     347           0 :                                       aComponentParameterSize);
     348             : }
     349             : 
     350             : OMX_ERRORTYPE
     351           0 : OmxPromiseLayer::SetParameter(OMX_INDEXTYPE aParamIndex,
     352             :                               OMX_PTR aComponentParameterStructure,
     353             :                               OMX_U32 aComponentParameterSize)
     354             : {
     355           0 :   return mPlatformLayer->SetParameter(aParamIndex,
     356             :                                       aComponentParameterStructure,
     357           0 :                                       aComponentParameterSize);
     358             : }
     359             : 
     360             : OMX_U32
     361           0 : OmxPromiseLayer::InputPortIndex()
     362             : {
     363           0 :   return mPlatformLayer->InputPortIndex();
     364             : }
     365             : 
     366             : OMX_U32
     367           0 : OmxPromiseLayer::OutputPortIndex()
     368             : {
     369           0 :   return mPlatformLayer->OutputPortIndex();
     370             : }
     371             : 
     372             : nsresult
     373           0 : OmxPromiseLayer::Shutdown()
     374             : {
     375           0 :   LOG("");
     376           0 :   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
     377           0 :   MOZ_ASSERT(!GetBufferHolders(OMX_DirInput)->Length());
     378           0 :   MOZ_ASSERT(!GetBufferHolders(OMX_DirOutput)->Length());
     379           0 :   return mPlatformLayer->Shutdown();
     380             : }
     381             : 
     382             : }

Generated by: LCOV version 1.13