Exemplo n.º 1
0
nsresult WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
                          int64_t aCurrentTime)
{
    NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");

    LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: About to seek to %fs",
                       this, mDecoder, aTarget/1000000.0));
    if (NS_FAILED(ResetDecode())) {
        return NS_ERROR_FAILURE;
    }
    uint32_t trackToSeek = mHasVideo ? mVideoTrack : mAudioTrack;
    int r = nestegg_track_seek(mContext, trackToSeek, aTarget * NS_PER_USEC);
    if (r != 0) {
        return NS_ERROR_FAILURE;
    }
#ifdef MOZ_DASH
    // Find next cluster index;
    MediaResource* resource = mDecoder->GetResource();
    int64_t newOffset = resource->Tell();
    for (uint32_t i = 1; i < mClusterByteRanges.Length(); i++) {
        if (newOffset < mClusterByteRanges[i].mStart) {
            mNextCluster = i;
            LOG(PR_LOG_DEBUG,
                ("WebMReader [%p] for decoder [%p] updating mNextCluster to [%d] "
                 "after seek to offset [%lld]",
                 this, mDecoder, mNextCluster, resource->Tell()));
            break;
        }
    }
#endif
    return DecodeToTarget(aTarget);
}
Exemplo n.º 2
0
gboolean GStreamerReader::SeekData(GstAppSrc* aSrc, guint64 aOffset)
{
  aOffset += mDataOffset;

  ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
  MediaResource* resource = mDecoder->GetResource();
  int64_t resourceLength = resource->GetLength();

  if (gst_app_src_get_size(mSource) == -1) {
    /* It's possible that we didn't know the length when we initialized mSource
     * but maybe we do now
     */
    gst_app_src_set_size(mSource, GetDataLength());
  }

  nsresult rv = NS_ERROR_FAILURE;
  if (aOffset < static_cast<guint64>(resourceLength)) {
    rv = resource->Seek(SEEK_SET, aOffset);
  }

  if (NS_FAILED(rv)) {
    LOG(PR_LOG_ERROR, "seek at %lu failed", aOffset);
  } else {
    MOZ_ASSERT(aOffset == static_cast<guint64>(resource->Tell()));
  }

  return NS_SUCCEEDED(rv);
}
Exemplo n.º 3
0
static int64_t webm_tell(void *aUserData)
{
  NS_ASSERTION(aUserData, "aUserData must point to a valid AbstractMediaDecoder");
  AbstractMediaDecoder* decoder = reinterpret_cast<AbstractMediaDecoder*>(aUserData);
  MediaResource* resource = decoder->GetResource();
  NS_ASSERTION(resource, "Decoder has no media resource");
  return resource->Tell();
}
static bool Read(Decoder *aDecoder, char *aBuffer, int64_t aOffset, uint32_t aCount, uint32_t* aBytes)
{
  MediaResource *resource = GetResource(aDecoder);
  if (aOffset != resource->Tell()) {
    nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
    if (NS_FAILED(rv)) {
      return false;
    }
  }
  nsresult rv = resource->Read(aBuffer, aCount, aBytes);
  if (NS_FAILED(rv)) {
    return false;
  }
  return true;
}
/*
 * If we're not at end of stream, read |aNumBytes| from the media resource,
 * put it in |aData|, and return true.
 * Otherwise, put as much data as is left into |aData|, set |aNumBytes| to the
 * amount of data we have left, and return false.
 *
 * This function also passes the read data on to the MP3 frame parser for
 * stream duration estimation.
 */
nsresult
AppleMP3Reader::ReadAndNotify(uint32_t *aNumBytes, char *aData)
{
    MediaResource *resource = mDecoder->GetResource();

    uint64_t offset = resource->Tell();

    // Loop until we have all the data asked for, or we've reached EOS
    uint32_t totalBytes = 0;
    uint32_t numBytes;
    do {
        uint32_t bytesWanted = *aNumBytes - totalBytes;
        nsresult rv = resource->Read(aData + totalBytes, bytesWanted, &numBytes);
        totalBytes += numBytes;

        if (NS_FAILED(rv)) {
            *aNumBytes = 0;
            return NS_ERROR_FAILURE;
        }
    } while(totalBytes < *aNumBytes && numBytes);

    // Pass the buffer to the MP3 frame parser to improve our duration estimate.
    if (mMP3FrameParser.IsMP3()) {
        mMP3FrameParser.Parse(aData, totalBytes, offset);
        uint64_t duration = mMP3FrameParser.GetDuration();
        if (duration != mDuration) {
            LOGD("Updating media duration to %lluus\n", duration);
            mDuration = duration;
            ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
            mDecoder->UpdateEstimatedMediaDuration(duration);
        }
    }

    *aNumBytes = totalBytes;

    // We will have read some data in the last iteration iff we filled the buffer.
    // XXX Maybe return a better value than NS_ERROR_FAILURE?
    return numBytes ? NS_OK : NS_ERROR_FAILURE;
}
Exemplo n.º 6
0
void GStreamerReader::ReadAndPushData(guint aLength)
{
  MediaResource* resource = mDecoder->GetResource();
  NS_ASSERTION(resource, "Decoder has no media resource");
  int64_t offset1 = resource->Tell();
  unused << offset1;
  nsresult rv = NS_OK;

  GstBuffer* buffer = gst_buffer_new_and_alloc(aLength);
#if GST_VERSION_MAJOR >= 1
  GstMapInfo info;
  gst_buffer_map(buffer, &info, GST_MAP_WRITE);
  guint8 *data = info.data;
#else
  guint8* data = GST_BUFFER_DATA(buffer);
#endif
  uint32_t size = 0, bytesRead = 0;
  while(bytesRead < aLength) {
    rv = resource->Read(reinterpret_cast<char*>(data + bytesRead),
        aLength - bytesRead, &size);
    if (NS_FAILED(rv) || size == 0)
      break;

    bytesRead += size;
  }

  int64_t offset2 = resource->Tell();
  unused << offset2;

#if GST_VERSION_MAJOR >= 1
  gst_buffer_unmap(buffer, &info);
  gst_buffer_set_size(buffer, bytesRead);
#else
  GST_BUFFER_SIZE(buffer) = bytesRead;
#endif

  GstFlowReturn ret = gst_app_src_push_buffer(mSource, gst_buffer_ref(buffer));
  if (ret != GST_FLOW_OK) {
    LOG(PR_LOG_ERROR, "ReadAndPushData push ret %s(%d)", gst_flow_get_name(ret), ret);
  }

  if (NS_FAILED(rv)) {
    /* Terminate the stream if there is an error in reading */
    LOG(PR_LOG_ERROR, "ReadAndPushData read error, rv=%x", rv);
    gst_app_src_end_of_stream(mSource);
  } else if (bytesRead < aLength) {
    /* If we read less than what we wanted, we reached the end */
    LOG(PR_LOG_WARNING, "ReadAndPushData read underflow, "
        "bytesRead=%u, aLength=%u, offset(%lld,%lld)",
        bytesRead, aLength, offset1, offset2);
    gst_app_src_end_of_stream(mSource);
  }

  gst_buffer_unref(buffer);

  /* Ensure offset change is consistent in this function.
   * If there are other stream operations on another thread at the same time,
   * it will disturb the GStreamer state machine.
   */
  MOZ_ASSERT(offset1 + bytesRead == offset2);
}