Exemplo n.º 1
0
nsresult
GonkAudioDecoderManager::Output(int64_t aStreamOffset,
                                nsRefPtr<MediaData>& aOutData)
{
  aOutData = nullptr;
  status_t err;
  err = mDecoder->Output(&mAudioBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);

  switch (err) {
    case OK:
    {
      nsRefPtr<AudioData> data;
      nsresult rv = CreateAudioData(aStreamOffset, getter_AddRefs(data));
      if (rv == NS_ERROR_NOT_AVAILABLE) {
        // Decoder outputs an empty video buffer, try again
        return NS_ERROR_NOT_AVAILABLE;
      } else if (rv != NS_OK || data == nullptr) {
        return NS_ERROR_UNEXPECTED;
      }
      aOutData = data;
      return NS_OK;
    }
    case android::INFO_FORMAT_CHANGED:
    {
      // If the format changed, update our cached info.
      GADM_LOG("Decoder format changed");
      sp<AMessage> audioCodecFormat;

      if (mDecoder->getOutputFormat(&audioCodecFormat) != OK ||
        audioCodecFormat == nullptr) {
        return NS_ERROR_UNEXPECTED;
      }

      int32_t codec_channel_count = 0;
      int32_t codec_sample_rate = 0;

      if (!audioCodecFormat->findInt32("channel-count", &codec_channel_count) ||
        !audioCodecFormat->findInt32("sample-rate", &codec_sample_rate)) {
        return NS_ERROR_UNEXPECTED;
      }

      // Update AudioInfo
      mAudioChannels = codec_channel_count;
      mAudioRate = codec_sample_rate;

      return Output(aStreamOffset, aOutData);
    }
    case android::INFO_OUTPUT_BUFFERS_CHANGED:
    {
      GADM_LOG("Info Output Buffers Changed");
      if (mDecoder->UpdateOutputBuffers()) {
        return Output(aStreamOffset, aOutData);
      }
      return NS_ERROR_FAILURE;
    }
    case -EAGAIN:
    {
      return NS_ERROR_NOT_AVAILABLE;
    }
    case android::ERROR_END_OF_STREAM:
    {
      GADM_LOG("Got EOS frame!");
      nsRefPtr<AudioData> data;
      nsresult rv = CreateAudioData(aStreamOffset, getter_AddRefs(data));
      if (rv == NS_ERROR_NOT_AVAILABLE) {
        // For EOS, no need to do any thing.
        return NS_ERROR_ABORT;
      } else if (rv != NS_OK || data == nullptr) {
        GADM_LOG("Failed to create audio data!");
        return NS_ERROR_UNEXPECTED;
      }
      aOutData = data;
      return NS_ERROR_ABORT;
    }
    case -ETIMEDOUT:
    {
      GADM_LOG("Timeout. can try again next time");
      return NS_ERROR_UNEXPECTED;
    }
    default:
    {
      GADM_LOG("Decoder failed, err=%d", err);
      return NS_ERROR_UNEXPECTED;
    }
  }

  return NS_OK;
}
Exemplo n.º 2
0
nsresult
GonkAudioDecoderManager::Output(int64_t aStreamOffset,
                                nsAutoPtr<MediaData>& aOutData)
{
  aOutData = nullptr;
  status_t err;
  err = mDecoder->Output(&mAudioBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);

  switch (err) {
    case OK:
    {
      AudioData* data = nullptr;
      nsresult rv = CreateAudioData(aStreamOffset, &data);
      if (rv == NS_ERROR_NOT_AVAILABLE) {
        // Decoder outputs an empty video buffer, try again
        return NS_ERROR_NOT_AVAILABLE;
      } else if (rv != NS_OK || data == nullptr) {
        return NS_ERROR_UNEXPECTED;
      }
      aOutData = data;
      return NS_OK;
    }
    case android::INFO_FORMAT_CHANGED:
    case android::INFO_OUTPUT_BUFFERS_CHANGED:
    {
      // If the format changed, update our cached info.
      ALOG("Decoder format changed");
      return Output(aStreamOffset, aOutData);
    }
    case -EAGAIN:
    {
      return NS_ERROR_NOT_AVAILABLE;
    }
    case android::ERROR_END_OF_STREAM:
    {
      ALOG("Got EOS frame!");
      AudioData* data = nullptr;
      nsresult rv = CreateAudioData(aStreamOffset, &data);
      if (rv == NS_ERROR_NOT_AVAILABLE) {
        // For EOS, no need to do any thing.
        return NS_ERROR_ABORT;
      } else if (rv != NS_OK || data == nullptr) {
        ALOG("Failed to create audio data!");
        return NS_ERROR_UNEXPECTED;
      }
      aOutData = data;
      return NS_ERROR_ABORT;
    }
    case -ETIMEDOUT:
    {
      ALOG("Timeout. can try again next time");
      return NS_ERROR_UNEXPECTED;
    }
    default:
    {
      ALOG("Decoder failed, err=%d", err);
      return NS_ERROR_UNEXPECTED;
    }
  }

  return NS_OK;
}
Exemplo n.º 3
0
nsresult
GonkAudioDecoderManager::Output(int64_t aStreamOffset,
                                RefPtr<MediaData>& aOutData)
{
  aOutData = nullptr;
  if (mAudioQueue.GetSize() > 0) {
    aOutData = mAudioQueue.PopFront();
    return mAudioQueue.AtEndOfStream() ? NS_ERROR_ABORT : NS_OK;
  }

  status_t err;
  MediaBuffer* audioBuffer = nullptr;
  err = mDecoder->Output(&audioBuffer, READ_OUTPUT_BUFFER_TIMEOUT_US);
  AutoReleaseMediaBuffer a(audioBuffer, mDecoder.get());

  switch (err) {
    case OK:
    {
      nsresult rv = CreateAudioData(audioBuffer, aStreamOffset);
      NS_ENSURE_SUCCESS(rv, rv);
      break;
    }
    case android::INFO_FORMAT_CHANGED:
    {
      // If the format changed, update our cached info.
      GADM_LOG("Decoder format changed");
      sp<AMessage> audioCodecFormat;

      if (mDecoder->getOutputFormat(&audioCodecFormat) != OK ||
        audioCodecFormat == nullptr) {
        return NS_ERROR_UNEXPECTED;
      }

      int32_t codec_channel_count = 0;
      int32_t codec_sample_rate = 0;

      if (!audioCodecFormat->findInt32("channel-count", &codec_channel_count) ||
        !audioCodecFormat->findInt32("sample-rate", &codec_sample_rate)) {
        return NS_ERROR_UNEXPECTED;
      }

      // Update AudioInfo
      mAudioChannels = codec_channel_count;
      mAudioRate = codec_sample_rate;

      return Output(aStreamOffset, aOutData);
    }
    case android::INFO_OUTPUT_BUFFERS_CHANGED:
    {
      GADM_LOG("Info Output Buffers Changed");
      if (mDecoder->UpdateOutputBuffers()) {
        return Output(aStreamOffset, aOutData);
      }
      return NS_ERROR_FAILURE;
    }
    case -EAGAIN:
    {
      return NS_ERROR_NOT_AVAILABLE;
    }
    case android::ERROR_END_OF_STREAM:
    {
      GADM_LOG("Got EOS frame!");
      nsresult rv = CreateAudioData(audioBuffer, aStreamOffset);
      NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT);
      MOZ_ASSERT(mAudioQueue.GetSize() > 0);
      mAudioQueue.Finish();
      break;
    }
    case -ETIMEDOUT:
    {
      GADM_LOG("Timeout. can try again next time");
      return NS_ERROR_UNEXPECTED;
    }
    default:
    {
      GADM_LOG("Decoder failed, err=%d", err);
      return NS_ERROR_UNEXPECTED;
    }
  }

  if (mAudioQueue.GetSize() > 0) {
    aOutData = mAudioQueue.PopFront();
    // Return NS_ERROR_ABORT at the last sample.
    return mAudioQueue.AtEndOfStream() ? NS_ERROR_ABORT : NS_OK;
  }

  return NS_ERROR_NOT_AVAILABLE;
}