static OMX_ERRORTYPE
ConfigAudioOutputPort(OmxPlatformLayer& aOmx, const AudioInfo& aInfo)
{
  OMX_PARAM_PORTDEFINITIONTYPE def;
  InitOmxParameter(&def);
  def.nPortIndex = aOmx.OutputPortIndex();
  OMX_ERRORTYPE err = aOmx.GetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
  RETURN_IF_ERR(err);

  def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
  err = aOmx.SetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
  RETURN_IF_ERR(err);

  OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
  InitOmxParameter(&pcmParams);
  pcmParams.nPortIndex = def.nPortIndex;
  err = aOmx.GetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
  RETURN_IF_ERR(err);

  pcmParams.nChannels = aInfo.mChannels;
  pcmParams.eNumData = OMX_NumericalDataSigned;
  pcmParams.bInterleaved = OMX_TRUE;
  pcmParams.nBitPerSample = 16;
  pcmParams.nSamplingRate = aInfo.mRate;
  pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
  err = aOmx.SetParameter(OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
  RETURN_IF_ERR(err);

  LOG("Config OMX_IndexParamAudioPcm, channel %lu, sample rate %lu",
      pcmParams.nChannels, pcmParams.nSamplingRate);

  return OMX_ErrorNone;
}
  OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const VideoInfo& aInfo) override
  {
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OMX_PARAM_PORTDEFINITIONTYPE def;

    // Set up in/out port definition.
    nsTArray<uint32_t> ports;
    aOmx.GetPortIndices(ports);
    for (auto idx : ports) {
      InitOmxParameter(&def);
      def.nPortIndex = idx;
      err = aOmx.GetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
      RETURN_IF_ERR(err);

      def.format.video.nFrameWidth =  aInfo.mDisplay.width;
      def.format.video.nFrameHeight = aInfo.mDisplay.height;
      def.format.video.nStride = aInfo.mImage.width;
      def.format.video.nSliceHeight = aInfo.mImage.height;

      if (def.eDir == OMX_DirInput) {
        def.format.video.eCompressionFormat = aOmx.CompressionFormat();
        def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
        if (def.nBufferSize < MIN_VIDEO_INPUT_BUFFER_SIZE) {
          def.nBufferSize = aInfo.mImage.width * aInfo.mImage.height;
          LOG("Change input buffer size to %lu", def.nBufferSize);
        }
      } else {
        def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
      }

      err = aOmx.SetParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
    }
    return err;
  }
rkv_error_t r_kv_create_avro_value(kv_store_t *kvstore,
                                   const char *space,
                                   const char *schemaName,
                                   avro_value_t **ret_avro_value) {
    int ret;
    avro_schema_t schema = NULL;
    avro_value_iface_t *iface = NULL;
    avro_value_t *avro_value = NULL;

    if (!kvstore || !schemaName || !ret_avro_value) {
        return RKV_INVALID_ARGUEMENTS;
    }

    if ((schema = r_kv_get_schema(kvstore, space, schemaName)) == NULL) {
        return RKV_INVALID_SCHEMA;
    }

    ret = rkv_malloc(sizeof(avro_value_t), (void**)&avro_value);
    RETURN_IF_ERR(ret);

    iface = avro_generic_class_from_schema(schema);
    if (avro_generic_value_new(iface, avro_value) != 0) {
        return RKV_ERROR;
    }

    *ret_avro_value = avro_value;
    return RKV_SUCCESS;
}
  OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
  {
    OMX_AUDIO_PARAM_AMRTYPE def;
    InitOmxParameter(&def);
    def.nPortIndex = aOmx.InputPortIndex();
    OMX_ERRORTYPE err = aOmx.GetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
    RETURN_IF_ERR(err);

    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
    err = aOmx.SetParameter(OMX_IndexParamAudioAmr, &def, sizeof(def));
    RETURN_IF_ERR(err);

    MOZ_ASSERT(aInfo.mChannels == 1);
    MOZ_ASSERT(aInfo.mRate == R);

    return ConfigAudioOutputPort(aOmx, aInfo);
  }
  OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
  {
    OMX_AUDIO_PARAM_MP3TYPE mp3Param;
    InitOmxParameter(&mp3Param);
    mp3Param.nPortIndex = aOmx.InputPortIndex();
    OMX_ERRORTYPE err = aOmx.GetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
    RETURN_IF_ERR(err);

    mp3Param.nChannels = aInfo.mChannels;
    mp3Param.nSampleRate = aInfo.mRate;
    err = aOmx.SetParameter(OMX_IndexParamAudioMp3, &mp3Param, sizeof(mp3Param));
    RETURN_IF_ERR(err);

    LOG("Config OMX_IndexParamAudioMp3, channel %lu, sample rate %lu",
        mp3Param.nChannels, mp3Param.nSampleRate);

    return ConfigAudioOutputPort(aOmx, aInfo);
  }
  OMX_ERRORTYPE Apply(OmxPlatformLayer& aOmx, const AudioInfo& aInfo) override
  {
    OMX_AUDIO_PARAM_AACPROFILETYPE aacProfile;
    InitOmxParameter(&aacProfile);
    aacProfile.nPortIndex = aOmx.InputPortIndex();
    OMX_ERRORTYPE err = aOmx.GetParameter(OMX_IndexParamAudioAac, &aacProfile, sizeof(aacProfile));
    RETURN_IF_ERR(err);

    aacProfile.nChannels = aInfo.mChannels;
    aacProfile.nSampleRate = aInfo.mRate;
    aacProfile.eAACProfile = static_cast<OMX_AUDIO_AACPROFILETYPE>(aInfo.mProfile);
    err = aOmx.SetParameter(OMX_IndexParamAudioAac, &aacProfile, sizeof(aacProfile));
    RETURN_IF_ERR(err);

    LOG("Config OMX_IndexParamAudioAac, channel %lu, sample rate %lu, profile %d",
        aacProfile.nChannels, aacProfile.nSampleRate, aacProfile.eAACProfile);

    return ConfigAudioOutputPort(aOmx, aInfo);
  }
rkv_error_t r_kv_get_avrovalue(const kv_value_t *value,
                               avro_value_t **ret_avro_value,
                               avro_schema_t schema) {

    avro_value_t *avro_value = NULL;
    kv_error_t err;
    rkv_error_t ret;

    if (!value || !ret_avro_value) {
        return RKV_INVALID_ARGUEMENTS;
    }

    ret = rkv_malloc(sizeof(avro_value_t), (void**)&avro_value);
    RETURN_IF_ERR(ret);

    err = kv_avro_generic_to_object((kv_value_t *)value, avro_value, schema);
    if (err != KV_SUCCESS) {
        return RKV_ERROR;
    }
    *ret_avro_value = avro_value;
    return RKV_SUCCESS;
}