void MediaOmxReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
{
  MOZ_ASSERT(OnTaskQueue());
  nsRefPtr<AbstractMediaDecoder> decoder = SafeGetDecoder();
  if (!decoder) { // reader has shut down
    return;
  }
  if (HasVideo()) {
    return;
  }
  if (!mMP3FrameParser.NeedsData()) {
    return;
  }

  nsRefPtr<MediaByteBuffer> bytes =
    mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
  NS_ENSURE_TRUE_VOID(bytes);
  mMP3FrameParser.Parse(bytes->Elements(), aLength, aOffset);
  if (!mMP3FrameParser.IsMP3()) {
    return;
  }

  int64_t duration = mMP3FrameParser.GetDuration();
  if (duration != mLastParserDuration) {
    mLastParserDuration = duration;
    decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
  }
}
int64_t MediaOmxReader::ProcessCachedData(int64_t aOffset)
{
  // Could run on decoder thread or IO thread.
  nsRefPtr<AbstractMediaDecoder> decoder = SafeGetDecoder();
  if (!decoder) { // reader has shut down
    return -1;
  }
  // We read data in chunks of 32 KiB. We can reduce this
  // value if media, such as sdcards, is too slow.
  // Because of SD card's slowness, need to keep sReadSize to small size.
  // See Bug 914870.
  static const int64_t sReadSize = 32 * 1024;

  NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");

  MOZ_ASSERT(decoder->GetResource());
  int64_t resourceLength = decoder->GetResource()->GetCachedDataEnd(0);
  NS_ENSURE_TRUE(resourceLength >= 0, -1);

  if (aOffset >= resourceLength) {
    return 0; // Cache is empty, nothing to do
  }

  int64_t bufferLength = std::min<int64_t>(resourceLength-aOffset, sReadSize);
  nsRefPtr<NotifyDataArrivedRunnable> runnable(
    new NotifyDataArrivedRunnable(this, bufferLength, aOffset, resourceLength));

  if (OnTaskQueue()) {
    runnable->Run();
  } else {
    OwnerThread()->Dispatch(runnable.forget());
  }

  return resourceLength - aOffset - bufferLength;
}
Exemple #3
0
void MediaOmxReader::NotifyDataArrivedInternal()
{
  MOZ_ASSERT(OnTaskQueue());
  RefPtr<AbstractMediaDecoder> decoder = SafeGetDecoder();
  if (!decoder) { // reader has shut down
    return;
  }
  if (HasVideo()) {
    return;
  }
  if (!mMP3FrameParser.NeedsData()) {
    return;
  }

  AutoPinned<MediaResource> resource(mDecoder->GetResource());
  MediaByteRangeSet byteRanges;
  nsresult rv = resource->GetCachedRanges(byteRanges);

  if (NS_FAILED(rv)) {
    return;
  }

  if (byteRanges == mLastCachedRanges) {
    return;
  }
  MediaByteRangeSet intervals = byteRanges - mLastCachedRanges;
  mLastCachedRanges = byteRanges;

  for (const auto& interval : intervals) {
    RefPtr<MediaByteBuffer> bytes =
      resource->MediaReadAt(interval.mStart, interval.Length());
    NS_ENSURE_TRUE_VOID(bytes);
    mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
    if (!mMP3FrameParser.IsMP3()) {
      return;
    }
  }
  int64_t duration = mMP3FrameParser.GetDuration();
  if (duration != mLastParserDuration) {
    mLastParserDuration = duration;
    decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
  }
}