Exemple #1
0
STDMETHODIMP CBDDemuxer::GetNextPacket(Packet **ppPacket)
{
  HRESULT hr = m_lavfDemuxer->GetNextPacket(ppPacket);

  ProcessBDEvents();

  Packet * const pPacket = *ppPacket;

  if (hr == S_OK && pPacket && pPacket->rtStart != Packet::INVALID_TIME) {
    REFERENCE_TIME rtOffset = m_rtOffset[pPacket->StreamId];
    if (rtOffset != m_rtNewOffset && pPacket->bPosition != -1 && pPacket->bPosition >= m_bNewOffsetPos) {
      DbgLog((LOG_TRACE, 10, L"Actual clip change detected in stream %d; time: %I64d, old offset: %I64d, new offset: %I64d", pPacket->StreamId, pPacket->rtStart, rtOffset, m_rtNewOffset));
      rtOffset = m_rtOffset[pPacket->StreamId] = m_rtNewOffset;
    }
    //DbgLog((LOG_TRACE, 10, L"Frame: stream: %d, start: %I64d, corrected: %I64d, bytepos: %I64d", pPacket->StreamId, pPacket->rtStart, pPacket->rtStart + rtOffset, pPacket->bPosition));
    pPacket->rtStart += rtOffset;
    pPacket->rtStop += rtOffset;
  }

  if (hr == S_OK && m_EndOfStreamPacketFlushProtection && pPacket && pPacket->bPosition != -1) {
    if (pPacket->bPosition < m_bNewOffsetPos) {
      DbgLog((LOG_TRACE, 10, L"Dropping packet from a previous segment (pos %I64d, segment started at %I64d) at EOS, from stream %d", pPacket->bPosition, m_bNewOffsetPos, pPacket->StreamId));
      SAFE_DELETE(*ppPacket);
      *ppPacket = nullptr;
      return S_FALSE;
    }
  }
  return hr;
}
Exemple #2
0
STDMETHODIMP CBDDemuxer::ProcessPacket(Packet *pPacket)
{
  ProcessBDEvents();

  if (pPacket && pPacket->rtStart != Packet::INVALID_TIME) {
    REFERENCE_TIME rtOffset = m_rtOffset[pPacket->StreamId];
    if (m_StreamClip[pPacket->StreamId] != m_NewClip && pPacket->bPosition != -1 && pPacket->bPosition >= m_bNewOffsetPos) {
      DbgLog((LOG_TRACE, 10, L"Actual clip change detected in stream %d; time: %I64d, old offset: %I64d, new offset: %I64d", pPacket->StreamId, pPacket->rtStart, rtOffset, m_rtNewOffset));
      rtOffset = m_rtOffset[pPacket->StreamId] = m_rtNewOffset;
      m_StreamClip[pPacket->StreamId] = m_NewClip;

      // Flush MVC extensions on stream change, it'll re-fill automatically
      if (m_MVCPlayback && pPacket->StreamId == m_lavfDemuxer->m_nH264MVCBaseStream && m_MVCExtensionClip != m_NewClip) {
        m_lavfDemuxer->FlushMVCExtensionQueue();
        CloseMVCExtensionDemuxer();
        OpenMVCExtensionDemuxer(m_NewClip);
      }
    }
    //DbgLog((LOG_TRACE, 10, L"Frame: stream: %d, start: %I64d, corrected: %I64d, bytepos: %I64d", pPacket->StreamId, pPacket->rtStart, pPacket->rtStart + rtOffset, pPacket->bPosition));
    pPacket->rtStart += rtOffset;
    pPacket->rtStop += rtOffset;
  }

  if (m_EndOfStreamPacketFlushProtection && pPacket && pPacket->bPosition != -1) {
    if (pPacket->bPosition < m_bNewOffsetPos) {
      DbgLog((LOG_TRACE, 10, L"Dropping packet from a previous segment (pos %I64d, segment started at %I64d) at EOS, from stream %d", pPacket->bPosition, m_bNewOffsetPos, pPacket->StreamId));
      return S_FALSE;
    }
  }

  return S_OK;
}
Exemple #3
0
STDMETHODIMP CBDDemuxer::SetTitle(int idx)
{
  HRESULT hr = S_OK;
  int ret; // return values
  if (m_pTitle) {
    bd_free_title_info(m_pTitle);
  }

  // Init Event Queue
  bd_get_event(m_pBD, nullptr);

  // Select title
  m_pTitle = bd_get_title_info(m_pBD, idx, 0);
  ret = bd_select_title(m_pBD, idx);
  if (ret == 0) {
    return E_FAIL;
  }

  if (m_pb) {
    av_free(m_pb->buffer);
    av_free(m_pb);
  }

  uint8_t *buffer = (uint8_t *)av_mallocz(BD_READ_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
  m_pb = avio_alloc_context(buffer, BD_READ_BUFFER_SIZE, 0, this, BDByteStreamRead, nullptr, BDByteStreamSeek);

  SafeRelease(&m_lavfDemuxer);
  SAFE_CO_FREE(m_rtOffset);

  m_lavfDemuxer = new CLAVFDemuxer(m_pLock, m_pSettings);
  m_lavfDemuxer->AddRef();
  m_lavfDemuxer->SetBluRay(this);
  if (FAILED(hr = m_lavfDemuxer->OpenInputStream(m_pb, nullptr, "mpegts", TRUE))) {
    SafeRelease(&m_lavfDemuxer);
    return hr;
  }

  m_lavfDemuxer->SeekByte(0, 0);

  // Process any events that occured during opening
  ProcessBDEvents();

  // Reset EOS protection
  m_EndOfStreamPacketFlushProtection = FALSE;

  // space for storing stream offsets
  m_rtOffset = (REFERENCE_TIME *)CoTaskMemAlloc(sizeof(REFERENCE_TIME) * m_lavfDemuxer->GetNumStreams());
  if (!m_rtOffset)
    return E_OUTOFMEMORY;
  memset(m_rtOffset, 0, sizeof(REFERENCE_TIME) * m_lavfDemuxer->GetNumStreams());

  DbgLog((LOG_TRACE, 20, L"Opened BD title with %d clips and %d chapters", m_pTitle->clip_count, m_pTitle->chapter_count));
  return S_OK;
}
Exemple #4
0
STDMETHODIMP CBDDemuxer::GetNextPacket(Packet **ppPacket)
{
  HRESULT hr = m_lavfDemuxer->GetNextPacket(ppPacket);

  ProcessBDEvents();

  Packet * const pPacket = *ppPacket;

  if (hr == S_OK && pPacket && pPacket->rtStart != Packet::INVALID_TIME) {
    REFERENCE_TIME rtOffset = m_rtOffset[pPacket->StreamId];
    if (rtOffset != m_rtNewOffset && pPacket->bPosition != -1 && pPacket->bPosition >= m_bNewOffsetPos) {
      DbgLog((LOG_TRACE, 10, L"Actual clip change detected in stream %d; time: %I64d, old offset: %I64d, new offset: %I64d", pPacket->StreamId, pPacket->rtStart, rtOffset, m_rtNewOffset));
      rtOffset = m_rtOffset[pPacket->StreamId] = m_rtNewOffset;
    }
    //DbgLog((LOG_TRACE, 10, L"Frame: stream: %d, start: %I64d, corrected: %I64d, bytepos: %I64d", pPacket->StreamId, pPacket->rtStart, pPacket->rtStart + rtOffset, pPacket->bPosition));
    pPacket->rtStart += rtOffset;
    pPacket->rtStop += rtOffset;
  }
  return hr;
}
Exemple #5
0
STDMETHODIMP CBDDemuxer::SetTitle(int idx)
{
  HRESULT hr = S_OK;
  int ret; // return values
  if (m_pTitle) {
    bd_free_title_info(m_pTitle);
  }

  // Init Event Queue
  bd_get_event(m_pBD, nullptr);

  // Select title
  m_pTitle = bd_get_title_info(m_pBD, idx, 0);
  ret = bd_select_title(m_pBD, idx);
  if (ret == 0) {
    return E_FAIL;
  }

  MPLS_PL * mpls = bd_get_title_mpls(m_pBD);
  if (mpls) {
    for (int i = 0; i < mpls->ext_sub_count; i++)
    {
      if (mpls->ext_sub_path[i].type == 8
        && mpls->ext_sub_path[i].sub_playitem_count == mpls->list_count)
      {
        DbgLog((LOG_TRACE, 20, L"CBDDemuxer::SetTitle(): Enabling BD3D MVC demuxing"));
        DbgLog((LOG_TRACE, 20, L" -> MVC_Base_view_R_flag: %d", m_pTitle->mvc_base_view_r_flag));
        m_MVCPlayback = TRUE;
        m_MVCExtensionSubPathIndex = i;
        break;
      }
    }
  }

  CloseMVCExtensionDemuxer();

  if (m_pb) {
    av_free(m_pb->buffer);
    av_free(m_pb);
  }

  uint8_t *buffer = (uint8_t *)av_mallocz(BD_READ_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
  m_pb = avio_alloc_context(buffer, BD_READ_BUFFER_SIZE, 0, this, BDByteStreamRead, nullptr, BDByteStreamSeek);

  SafeRelease(&m_lavfDemuxer);
  SAFE_CO_FREE(m_StreamClip);
  SAFE_CO_FREE(m_rtOffset);

  m_lavfDemuxer = new CLAVFDemuxer(m_pLock, m_pSettings);
  m_lavfDemuxer->AddRef();
  m_lavfDemuxer->SetBluRay(this);
  if (FAILED(hr = m_lavfDemuxer->OpenInputStream(m_pb, nullptr, "mpegts", TRUE))) {
    SafeRelease(&m_lavfDemuxer);
    return hr;
  }

  if (m_MVCPlayback && !m_lavfDemuxer->m_bH264MVCCombine)
  {
    DbgLog((LOG_TRACE, 10, L"CBDDemuxer::SetTitle(): MVC demuxing was requested, but main demuxer did not activate MVC mode, disabling."));
    CloseMVCExtensionDemuxer();
    m_MVCPlayback = FALSE;
  }

  m_lavfDemuxer->SeekByte(0, 0);

  // Process any events that occured during opening
  ProcessBDEvents();

  // Reset EOS protection
  m_EndOfStreamPacketFlushProtection = FALSE;

  // space for storing stream offsets
  m_StreamClip = (uint16_t *)CoTaskMemAlloc(sizeof(*m_StreamClip) * m_lavfDemuxer->GetNumStreams());
  if (!m_StreamClip)
    return E_OUTOFMEMORY;
  memset(m_StreamClip, -1, sizeof(*m_StreamClip) * m_lavfDemuxer->GetNumStreams());

  m_rtOffset = (REFERENCE_TIME *)CoTaskMemAlloc(sizeof(*m_rtOffset) * m_lavfDemuxer->GetNumStreams());
  if (!m_rtOffset)
    return E_OUTOFMEMORY;
  memset(m_rtOffset, 0, sizeof(*m_rtOffset) * m_lavfDemuxer->GetNumStreams());

  DbgLog((LOG_TRACE, 20, L"Opened BD title with %d clips and %d chapters", m_pTitle->clip_count, m_pTitle->chapter_count));
  return S_OK;
}