LCOV - code coverage report
Current view: top level - dom/media/platforms/omx - OmxPlatformLayer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 135 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 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 "OmxPlatformLayer.h"
       8             : 
       9             : #include "OMX_VideoExt.h" // For VP8.
      10             : 
      11             : #if defined(MOZ_WIDGET_GONK) && (ANDROID_VERSION == 20 || ANDROID_VERSION == 19)
      12             : #define OMX_PLATFORM_GONK
      13             : #include "GonkOmxPlatformLayer.h"
      14             : #endif
      15             : 
      16             : #include "VPXDecoder.h"
      17             : 
      18             : #ifdef LOG
      19             : #undef LOG
      20             : #endif
      21             : 
      22             : #define LOG(arg, ...) MOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, ("OmxPlatformLayer -- %s: " arg, __func__, ##__VA_ARGS__))
      23             : 
      24             : #define RETURN_IF_ERR(err)     \
      25             :   if (err != OMX_ErrorNone) {  \
      26             :     LOG("error: 0x%08x", err); \
      27             :     return err;                \
      28             :   }                            \
      29             : 
      30             : // Common OMX decoder configuration code.
      31             : namespace mozilla {
      32             : 
      33             : // This helper class encapsulates the details of component parameters setting
      34             : // for different OMX audio & video codecs.
      35             : template<typename ParamType>
      36           0 : class OmxConfig
      37             : {
      38             : public:
      39           0 :   virtual ~OmxConfig() {}
      40             :   // Subclasses should implement this method to configure the codec.
      41             :   virtual OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const ParamType& aParam) = 0;
      42             : };
      43             : 
      44             : typedef OmxConfig<AudioInfo> OmxAudioConfig;
      45             : typedef OmxConfig<VideoInfo> OmxVideoConfig;
      46             : 
      47             : template<typename ConfigType>
      48             : UniquePtr<ConfigType> ConfigForMime(const nsACString&);
      49             : 
      50             : static OMX_ERRORTYPE
      51           0 : ConfigAudioOutputPort(OmxPlatformLayer& aOmx, const AudioInfo& aInfo)
      52             : {
      53             :   OMX_ERRORTYPE err;
      54             : 
      55             :   OMX_PARAM_PORTDEFINITIONTYPE def;
      56           0 :   InitOmxParameter(&def);
      57           0 :   def.nPortIndex = aOmx.OutputPortIndex();
      58           0 :   err = aOmx.GetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
      59           0 :   RETURN_IF_ERR(err);
      60             : 
      61           0 :   def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
      62           0 :   err = aOmx.SetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
      63           0 :   RETURN_IF_ERR(err);
      64             : 
      65             :   OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
      66           0 :   InitOmxParameter(&pcmParams);
      67           0 :   pcmParams.nPortIndex = def.nPortIndex;
      68           0 :   err = aOmx.GetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
      69           0 :   RETURN_IF_ERR(err);
      70             : 
      71           0 :   pcmParams.nChannels = aInfo.mChannels;
      72           0 :   pcmParams.eNumData = OMX_NumericalDataSigned;
      73           0 :   pcmParams.bInterleaved = OMX_TRUE;
      74           0 :   pcmParams.nBitPerSample = 16;
      75           0 :   pcmParams.nSamplingRate = aInfo.mRate;
      76           0 :   pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
      77           0 :   err = aOmx.SetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
      78           0 :   RETURN_IF_ERR(err);
      79             : 
      80           0 :   LOG("Config OMX_IndexParamAudioPcm, channel %lu, sample rate %lu",
      81             :       pcmParams.nChannels, pcmParams.nSamplingRate);
      82             : 
      83           0 :   return OMX_ErrorNone;
      84             : }
      85             : 
      86           0 : class OmxAacConfig : public OmxAudioConfig
      87             : {
      88             : public:
      89           0 :   OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
      90             :   {
      91             :     OMX_ERRORTYPE err;
      92             : 
      93             :     OMX_AUDIO_PARAM_AACPROFILETYPE aacProfile;
      94           0 :     InitOmxParameter(&aacProfile);
      95           0 :     aacProfile.nPortIndex = aOmx.InputPortIndex();
      96           0 :     err = aOmx.GetParameter(OMX_IndexParamAudioAac, &aacProfile, sizeof(aacProfile));
      97           0 :     RETURN_IF_ERR(err);
      98             : 
      99           0 :     aacProfile.nChannels = aInfo.mChannels;
     100           0 :     aacProfile.nSampleRate = aInfo.mRate;
     101           0 :     aacProfile.eAACProfile = static_cast<OMX_AUDIO_AACPROFILETYPE>(aInfo.mProfile);
     102           0 :     err = aOmx.SetParameter(OMX_IndexParamAudioAac, &aacProfile, sizeof(aacProfile));
     103           0 :     RETURN_IF_ERR(err);
     104             : 
     105           0 :     LOG("Config OMX_IndexParamAudioAac, channel %lu, sample rate %lu, profile %d",
     106             :         aacProfile.nChannels, aacProfile.nSampleRate, aacProfile.eAACProfile);
     107             : 
     108           0 :     return ConfigAudioOutputPort(aOmx, aInfo);
     109             :   }
     110             : };
     111             : 
     112           0 : class OmxMp3Config : public OmxAudioConfig
     113             : {
     114             : public:
     115           0 :   OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
     116             :   {
     117             :     OMX_ERRORTYPE err;
     118             : 
     119             :     OMX_AUDIO_PARAM_MP3TYPE mp3Param;
     120           0 :     InitOmxParameter(&mp3Param);
     121           0 :     mp3Param.nPortIndex = aOmx.InputPortIndex();
     122           0 :     err = aOmx.GetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
     123           0 :     RETURN_IF_ERR(err);
     124             : 
     125           0 :     mp3Param.nChannels = aInfo.mChannels;
     126           0 :     mp3Param.nSampleRate = aInfo.mRate;
     127           0 :     err = aOmx.SetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
     128           0 :     RETURN_IF_ERR(err);
     129             : 
     130           0 :     LOG("Config OMX_IndexParamAudioMp3, channel %lu, sample rate %lu",
     131             :         mp3Param.nChannels, mp3Param.nSampleRate);
     132             : 
     133           0 :     return ConfigAudioOutputPort(aOmx, aInfo);
     134             :   }
     135             : };
     136             : 
     137             : enum OmxAmrSampleRate {
     138             :   kNarrowBand = 8000,
     139             :   kWideBand = 16000,
     140             : };
     141             : 
     142             : template <OmxAmrSampleRate R>
     143           0 : class OmxAmrConfig : public OmxAudioConfig
     144             : {
     145             : public:
     146           0 :   OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
     147             :   {
     148             :     OMX_ERRORTYPE err;
     149             : 
     150             :     OMX_AUDIO_PARAM_AMRTYPE def;
     151           0 :     InitOmxParameter(&def);
     152           0 :     def.nPortIndex = aOmx.InputPortIndex();
     153           0 :     err = aOmx.GetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
     154           0 :     RETURN_IF_ERR(err);
     155             : 
     156           0 :     def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
     157           0 :     err = aOmx.SetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
     158           0 :     RETURN_IF_ERR(err);
     159             : 
     160           0 :     MOZ_ASSERT(aInfo.mChannels == 1);
     161           0 :     MOZ_ASSERT(aInfo.mRate == R);
     162             : 
     163           0 :     return ConfigAudioOutputPort(aOmx, aInfo);
     164             :   }
     165             : };
     166             : 
     167             : template<>
     168             : UniquePtr<OmxAudioConfig>
     169           0 : ConfigForMime(const nsACString& aMimeType)
     170             : {
     171           0 :   UniquePtr<OmxAudioConfig> conf;
     172             : 
     173           0 :   if (OmxPlatformLayer::SupportsMimeType(aMimeType)) {
     174           0 :     if (aMimeType.EqualsLiteral("audio/mp4a-latm")) {
     175           0 :       conf.reset(new OmxAacConfig());
     176           0 :     } else if (aMimeType.EqualsLiteral("audio/mp3") ||
     177           0 :                 aMimeType.EqualsLiteral("audio/mpeg")) {
     178           0 :       conf.reset(new OmxMp3Config());
     179           0 :     } else if (aMimeType.EqualsLiteral("audio/3gpp")) {
     180           0 :       conf.reset(new OmxAmrConfig<OmxAmrSampleRate::kNarrowBand>());
     181           0 :     } else if (aMimeType.EqualsLiteral("audio/amr-wb")) {
     182           0 :       conf.reset(new OmxAmrConfig<OmxAmrSampleRate::kWideBand>());
     183             :     }
     184             :   }
     185           0 :   return Move(conf);
     186             : }
     187             : 
     188             : // There should be a better way to calculate it.
     189             : #define MIN_VIDEO_INPUT_BUFFER_SIZE 64 * 1024
     190             : 
     191           0 : class OmxCommonVideoConfig : public OmxVideoConfig
     192             : {
     193             : public:
     194           0 :   explicit OmxCommonVideoConfig()
     195           0 :     : OmxVideoConfig()
     196           0 :   {}
     197             : 
     198           0 :   OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const VideoInfo& aInfo) override
     199             :   {
     200             :     OMX_ERRORTYPE err;
     201             :     OMX_PARAM_PORTDEFINITIONTYPE def;
     202             : 
     203             :     // Set up in/out port definition.
     204           0 :     nsTArray<uint32_t> ports;
     205           0 :     aOmx.GetPortIndices(ports);
     206           0 :     for (auto idx : ports) {
     207           0 :       InitOmxParameter(&def);
     208           0 :       def.nPortIndex = idx;
     209           0 :       err = aOmx.GetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
     210           0 :       RETURN_IF_ERR(err);
     211             : 
     212           0 :       def.format.video.nFrameWidth =  aInfo.mDisplay.width;
     213           0 :       def.format.video.nFrameHeight = aInfo.mDisplay.height;
     214           0 :       def.format.video.nStride = aInfo.mImage.width;
     215           0 :       def.format.video.nSliceHeight = aInfo.mImage.height;
     216             : 
     217           0 :       if (def.eDir == OMX_DirInput) {
     218           0 :         def.format.video.eCompressionFormat = aOmx.CompressionFormat();
     219           0 :         def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
     220           0 :         if (def.nBufferSize < MIN_VIDEO_INPUT_BUFFER_SIZE) {
     221           0 :           def.nBufferSize = aInfo.mImage.width * aInfo.mImage.height;
     222           0 :           LOG("Change input buffer size to %lu", def.nBufferSize);
     223             :         }
     224             :       } else {
     225           0 :         def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
     226             :       }
     227             : 
     228           0 :       err = aOmx.SetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
     229             :     }
     230           0 :     return err;
     231             :   }
     232             : };
     233             : 
     234             : template<>
     235             : UniquePtr<OmxVideoConfig>
     236           0 : ConfigForMime(const nsACString& aMimeType)
     237             : {
     238           0 :   UniquePtr<OmxVideoConfig> conf;
     239             : 
     240           0 :   if (OmxPlatformLayer::SupportsMimeType(aMimeType)) {
     241           0 :     conf.reset(new OmxCommonVideoConfig());
     242             :   }
     243           0 :   return Move(conf);
     244             : }
     245             : 
     246             : OMX_ERRORTYPE
     247           0 : OmxPlatformLayer::Config()
     248             : {
     249           0 :   MOZ_ASSERT(mInfo);
     250             : 
     251             :   OMX_PORT_PARAM_TYPE portParam;
     252           0 :   InitOmxParameter(&portParam);
     253           0 :   if (mInfo->IsAudio()) {
     254           0 :     GetParameter(OMX_IndexParamAudioInit, &portParam, sizeof(portParam));
     255           0 :     mStartPortNumber = portParam.nStartPortNumber;
     256           0 :     UniquePtr<OmxAudioConfig> conf(ConfigForMime<OmxAudioConfig>(mInfo->mMimeType));
     257           0 :     MOZ_ASSERT(conf.get());
     258           0 :     return conf->Apply(*this, *(mInfo->GetAsAudioInfo()));
     259           0 :   } else if (mInfo->IsVideo()) {
     260           0 :     GetParameter(OMX_IndexParamVideoInit, &portParam, sizeof(portParam));
     261           0 :     UniquePtr<OmxVideoConfig> conf(ConfigForMime<OmxVideoConfig>(mInfo->mMimeType));
     262           0 :     MOZ_ASSERT(conf.get());
     263           0 :     return conf->Apply(*this, *(mInfo->GetAsVideoInfo()));
     264             :   } else {
     265           0 :     MOZ_ASSERT_UNREACHABLE("non-AV data (text?) is not supported.");
     266             :     return OMX_ErrorNotImplemented;
     267             :   }
     268             : }
     269             : 
     270             : OMX_VIDEO_CODINGTYPE
     271           0 : OmxPlatformLayer::CompressionFormat()
     272             : {
     273           0 :   MOZ_ASSERT(mInfo);
     274             : 
     275           0 :   if (mInfo->mMimeType.EqualsLiteral("video/avc")) {
     276           0 :     return OMX_VIDEO_CodingAVC;
     277           0 :   } else if (mInfo->mMimeType.EqualsLiteral("video/mp4v-es") ||
     278           0 :        mInfo->mMimeType.EqualsLiteral("video/mp4")) {
     279           0 :     return OMX_VIDEO_CodingMPEG4;
     280           0 :   } else if (mInfo->mMimeType.EqualsLiteral("video/3gpp")) {
     281           0 :     return OMX_VIDEO_CodingH263;
     282           0 :   } else if (VPXDecoder::IsVP8(mInfo->mMimeType)) {
     283           0 :     return static_cast<OMX_VIDEO_CODINGTYPE>(OMX_VIDEO_CodingVP8);
     284             :   } else {
     285           0 :     MOZ_ASSERT_UNREACHABLE("Unsupported compression format");
     286             :     return OMX_VIDEO_CodingUnused;
     287             :   }
     288             : }
     289             : 
     290             : // Implementations for different platforms will be defined in their own files.
     291             : #ifdef OMX_PLATFORM_GONK
     292             : 
     293             : bool
     294             : OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
     295             : {
     296             :   return GonkOmxPlatformLayer::FindComponents(aMimeType);
     297             : }
     298             : 
     299             : OmxPlatformLayer*
     300             : OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
     301             :                          OmxPromiseLayer* aPromiseLayer,
     302             :                          TaskQueue* aTaskQueue,
     303             :                          layers::ImageContainer* aImageContainer)
     304             : {
     305             :   return new GonkOmxPlatformLayer(aDataDecoder, aPromiseLayer, aTaskQueue, aImageContainer);
     306             : }
     307             : 
     308             : #else // For platforms without OMX IL support.
     309             : 
     310             : bool
     311           0 : OmxPlatformLayer::SupportsMimeType(const nsACString& aMimeType)
     312             : {
     313           0 :   return false;
     314             : }
     315             : 
     316             : OmxPlatformLayer*
     317           0 : OmxPlatformLayer::Create(OmxDataDecoder* aDataDecoder,
     318             :                         OmxPromiseLayer* aPromiseLayer,
     319             :                         TaskQueue* aTaskQueue,
     320             :                         layers::ImageContainer* aImageContainer)
     321             : {
     322           0 :   return nullptr;
     323             : }
     324             : 
     325             : #endif
     326             : 
     327             : }

Generated by: LCOV version 1.13