コード例 #1
0
nsRefPtr<MediaDecoderReader::SeekPromise>
AppleMP3Reader::Seek(int64_t aTime, int64_t aEndTime)
{
  MOZ_ASSERT(OnTaskQueue());

  // Find the exact frame/packet that contains |aTime|.
  mCurrentAudioFrame = aTime * mAudioSampleRate / USECS_PER_S;
  SInt64 packet = mCurrentAudioFrame / mAudioFramesPerCompressedPacket;

  // |AudioFileStreamSeek| will pass back through |byteOffset| the byte offset
  // into the stream it expects next time it reads.
  SInt64 byteOffset;
  UInt32 flags = 0;

  OSStatus rv = AudioFileStreamSeek(mAudioFileStream,
                                    packet,
                                    &byteOffset,
                                    &flags);

  if (rv) {
    LOGE("Couldn't seek demuxer. Error code %x\n", rv);
    return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
  }

  LOGD("computed byte offset = %lld; estimated = %s\n",
       byteOffset,
       (flags & kAudioFileStreamSeekFlag_OffsetIsEstimated) ? "YES" : "NO");

  mDecoder->GetResource()->Seek(nsISeekableStream::NS_SEEK_SET, byteOffset);

  ResetDecode();

  return SeekPromise::CreateAndResolve(aTime, __func__);
}
コード例 #2
0
void Audio_Stream::seekToTime(unsigned newSeekTime)
{
    unsigned duration = durationInSeconds();
    if (!(duration > 0)) {
        return;
    }
    
    if (state() == SEEKING) {
        return;
    } else {
        setState(SEEKING);
    }
    
    m_seekTime = newSeekTime;
    
    double offset = (double)newSeekTime / (double)duration;
    UInt64 seekByteOffset = m_dataOffset + offset * (contentLength() - m_dataOffset);
    
    HTTP_Stream_Position position;

    position.start = seekByteOffset;
    position.end = contentLength();
    
    double packetDuration = m_srcFormat.mFramesPerPacket / m_srcFormat.mSampleRate;
    
    if (packetDuration > 0 && bitrate() > 0) {
        UInt32 ioFlags = 0;
        SInt64 packetAlignedByteOffset;
        SInt64 seekPacket = floor((double)newSeekTime / packetDuration);
        
        OSStatus err = AudioFileStreamSeek(m_audioFileStream, seekPacket, &packetAlignedByteOffset, &ioFlags);
        if (!err) {
            position.start = packetAlignedByteOffset + m_dataOffset;
        }
    }
    
    close();
    
    AS_TRACE("Seeking position %llu\n", position.start);
    
    if (m_httpStream->open(position)) {
        AS_TRACE("%s: HTTP stream opened, buffering...\n", __PRETTY_FUNCTION__);
        m_httpStreamRunning = true;
    } else {
        AS_TRACE("%s: failed to open the fHTTP stream\n", __PRETTY_FUNCTION__);
        setState(FAILED);
    }
}
コード例 #3
0
SInt64 DZAudioQueuePlayer::seek(float time)
{
    // Cannot seek if parameters not available or parser/queue not ready.
    if (this->_format.mSampleRate <= 0 || this->_format.mFramesPerPacket <= 0) {
        return -1;
    }
    if (this->_parser == NULL || this->_queue == NULL
        || this->_status == DZAudioQueuePlayerStatus_NotReady
        || this->_status == DZAudioQueuePlayerStatus_Error) {
        return -1;
    }
    
    // Get audio data offset.
    SInt64 dataOffset = 0;
    UInt32 propertySize = sizeof(dataOffset);
    if (dzDebugError(AudioFileStreamGetProperty(this->_parser, kAudioFileStreamProperty_DataOffset, &propertySize, &dataOffset), "Fail to get stream data offset.")) {
        return -1;
    }
    
    // Reset audio queue to clear the current queue buffer.
    if (dzDebugError(AudioQueueReset(this->_queue), "Fail to reset audio queue.")) {
        return -1;
    }
    
    // Get audio queue current time.
    AudioTimeStamp timeStamp;
    if (this->_status == DZAudioQueuePlayerStatus_ReadyToStart) {
        timeStamp.mSampleTime = 0;
    } else if (dzDebugError(AudioQueueGetCurrentTime(this->_queue, NULL, &(timeStamp), NULL),
                     "Fail to get audio queue current time.")) {
        return -1;
    }
    
    // Calculate packet offset and so the byte offset.
    SInt64 packetOffset = round(time * this->_format.mSampleRate / this->_format.mFramesPerPacket);
    SInt64 byteOffset = 0;
    UInt32 ioFlag = 0;
    if (dzDebugError(AudioFileStreamSeek(this->_parser, packetOffset, &byteOffset, &ioFlag),
                     "Fail to seek in audio file stream.")) {
        return -1;
    }
    this->_timeAmendment = time - timeStamp.mSampleTime / this->_format.mSampleRate;
    return byteOffset + dataOffset;
}
コード例 #4
0
void
AppleMP3Reader::Seek(int64_t aTime,
                     int64_t aStartTime,
                     int64_t aEndTime,
                     int64_t aCurrentTime)
{
  MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread");
  NS_ASSERTION(aStartTime < aEndTime,
               "Seeking should happen over a positive range");

  // Find the exact frame/packet that contains |aTime|.
  mCurrentAudioFrame = aTime * mAudioSampleRate / USECS_PER_S;
  SInt64 packet = mCurrentAudioFrame / mAudioFramesPerCompressedPacket;

  // |AudioFileStreamSeek| will pass back through |byteOffset| the byte offset
  // into the stream it expects next time it reads.
  SInt64 byteOffset;
  UInt32 flags = 0;

  OSStatus rv = AudioFileStreamSeek(mAudioFileStream,
                                    packet,
                                    &byteOffset,
                                    &flags);

  if (rv) {
    LOGE("Couldn't seek demuxer. Error code %x\n", rv);
    GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
    return;
  }

  LOGD("computed byte offset = %lld; estimated = %s\n",
       byteOffset,
       (flags & kAudioFileStreamSeekFlag_OffsetIsEstimated) ? "YES" : "NO");

  mDecoder->GetResource()->Seek(nsISeekableStream::NS_SEEK_SET, byteOffset);

  ResetDecode();

  GetCallback()->OnSeekCompleted(NS_OK);
}