Exemple #1
0
DemuxPacket* CDVDDemuxSMD::ReadAudioData()
{
  DemuxPacket* pPacket = NULL;

  ismd_result_t ismd_ret;
  ismd_dev_t demux = -1;
  ismd_port_handle_t audio_data_port = -1;
  ismd_demux_filter_handle_t m_demux_aes_filter_handle = -1;
  ismd_buffer_handle_t buffer = -1;
  ismd_buffer_descriptor_t ismd_buf_desc;
  ismd_es_buf_attr_t *buf_attrs;
  ismd_port_status_t port_status;
  uint8_t *buf_ptr;

  demux = g_IntelSMDGlobals.GetDemuxer();
  if(demux == -1)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::ReadAudioData failed at g_IntelSMDGlobals.GetDemuxer");
    return NULL;
  }

  m_demux_aes_filter_handle = g_IntelSMDGlobals.GetDemuxAudioFilter();
  if(demux == -1)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::ReadAudioData failed at g_IntelSMDGlobals.GetDemuxAudioFilter");
    return NULL;
  }

  ismd_ret = ismd_demux_filter_get_output_port(demux, m_demux_aes_filter_handle, &audio_data_port);

  if(ismd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::ReadAudioData failed at ismd_demux_filter_get_output_port %d", ismd_ret);
    return NULL;
  }

  ismd_port_get_status(audio_data_port, &port_status);
  if(port_status.cur_depth == 0)
    return NULL;

  ismd_port_read(audio_data_port, &buffer);

  ismd_ret = ismd_buffer_read_desc(buffer, &ismd_buf_desc);
  if (ismd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDVideoCodecSMD::ReadAudioData ismd_buffer_read_desc failed. %d", ismd_ret);
    return NULL;
  }

  buf_ptr = (uint8_t *)OS_MAP_IO_TO_MEM_NOCACHE(ismd_buf_desc.phys.base,ismd_buf_desc.phys.size);

  int size = ismd_buf_desc.phys.level;

  if(size == 0)
  {
    ismd_ret = ismd_buffer_dereference(buffer);
    if (ismd_ret != ISMD_SUCCESS)
    {
      CLog::Log(LOGERROR, "CDVDVideoCodecSMD::ReadAudioData ismd_buffer_dereference failed. %d", ismd_ret);
    }
    return NULL;
  }

  buf_attrs = (ismd_es_buf_attr_t *) ismd_buf_desc.attributes;

  pPacket = CDVDDemuxUtils::AllocateDemuxPacket(size);
  pPacket->iStreamId =  AUDIO_STREAM;
  pPacket->pts = g_IntelSMDGlobals.IsmdToDvdPts(buf_attrs->original_pts);
  pPacket->dts = g_IntelSMDGlobals.IsmdToDvdPts(buf_attrs->original_pts);
  pPacket->iSize = size;
  memcpy(pPacket->pData, buf_ptr, size);

  OS_UNMAP_IO_FROM_MEM(buf_ptr, ismd_buf_desc.phys.size);

  //need to dereference this buffer as SMD driver created reference when it made the buffer so it can be freed
  ismd_ret = ismd_buffer_dereference(buffer);
  if (ismd_ret != ISMD_SUCCESS)
    CLog::Log(LOGERROR, "CDVDVideoCodecSMD::ReadAudioData ismd_buffer_dereference failed. %d", ismd_ret);

  return pPacket;
}
Exemple #2
0
DemuxPacket* CDVDDemuxSMD::Read()
{
  ismd_result_t result = ISMD_SUCCESS;
  ismd_port_status_t port_status;
  ismd_buffer_handle_t buffer = ISMD_BUFFER_HANDLE_INVALID;
  ismd_buffer_descriptor_t buffer_desc;
  char data_buffer[READ_SIZE];
  int data_buffer_size = 0;
  unsigned int amount_to_read;
  unsigned int amount_read = 0;
  char *virtual_buffer_address = NULL;
  bool full = false;
  uint8_t *chunk;
  ismd_es_buf_attr_t *buf_attrs;
  char buf[READ_SIZE];
  DemuxPacket* pPacket = NULL;
  int packets_num;
  const std::vector<DvbTunerPtr>& tuners = DVBManager::GetInstance().GetTuners();

  amount_to_read = READ_SIZE;
  amount_read = m_pInput->Read((BYTE *) buf, amount_to_read);

  // no use to continue if we're not tuned
  if (tuners[0]->GetTuningState() != DvbTuner::TUNING_STATE_TUNED)
  {
    Stop();
    goto end;
  }

  if(!tuners[0]->IsSignalOk())
  {
    Stop();
    goto end;
  }

  if (amount_read == 0)
  {
    //CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read time out");
    goto end;
  }

  if (amount_read == -1 && tuners[0]->GetTuningState() == DvbTuner::TUNING_STATE_TUNED)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::Read amount_read is -1 while tuning");
    goto end;
  }

  if (amount_read % 188 != 0 && tuners[0]->GetTuningState() == DvbTuner::TUNING_STATE_TUNED)
    CLog::Log(LOGWARNING, "CDVDDemuxSMD:Read: amount_read % 188 != 0 (%d)", amount_read);

  if(tuners[0]->GetTuningState() == DvbTuner::TUNING_STATE_TUNED)
    Start();

  if(m_lastPatStopWatch.GetElapsedMilliseconds() > PAT_TIMEOUT)
  {
    CLog::Log(LOGWARNING, "CDVDDemuxSMD:Read: timeout for PAT. Reopening DVR");
    tuners[0]->RemoveAllPidFilters();
    m_lastPatStopWatch.StartZero();
  }

  chunk = (uint8_t*) buf;
  packets_num = amount_read / 188;
  for (int i = 0; i < packets_num; i++)
  {
    if (chunk[0] != 0x47)
    {
      CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read sync byte is not 0x47 (%02X)", chunk[0]);
      chunk += 188;
      continue;
    }

    uint16_t chunkPid = ((uint16_t) (chunk[1] & 0x1f) << 8) + chunk[2];

    if (chunkPid == PAT_PID && m_state == DEMUX_STATE_IDLE)
    {
      dvbpsi_PushPacket(dvbpsiPAT, chunk);
    }
    else if (chunkPid == m_pmtPid && m_state == DEMUX_STATE_FOUND_PAT)
    {
      dvbpsi_PushPacket(dvbpsiPMT, chunk);
    }
    else if (m_state == DEMUX_STATE_FOUND_PMT)
    {
      if (m_nAudioCodec == CODEC_ID_NONE)
        CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read audio codec not found");
      if (m_nVideoCodec == CODEC_ID_NONE)
        CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read video codec not found");
      if (m_pcrPid == -1)
        CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read PCR  not found");

      SetState(DEMUX_STATE_RUNNING);
      CLog::Log(LOGINFO,"CDVDDemuxSMD::Read Audio PID %d Video PID %d Audio Codec %d Video Codec %d PCR %d\n",
            m_nAudioPID, m_nVideoPID, m_nAudioCodec, m_nVideoCodec, m_pcrPid);
      StartDemuxer();
    }
    else if (chunkPid == EIT_PID && tuners[0]->GetTunerType() == DvbTuner::TUNER_TYPE_DVBT)
    {
      if(m_epgLoader)
        m_epgLoader->ProcessPacket(chunk);
    }
    else if (chunkPid == m_nVideoPID || chunkPid == m_nAudioPID)
    {
      if (chunkPid == m_nVideoPID)
        m_videoStats.AddSampleBytes(188 - 4);
      if (chunkPid == m_nAudioPID)
        m_audioStats.AddSampleBytes(188 - 4);
      OS_MEMCPY(data_buffer + data_buffer_size, chunk, 188);
      data_buffer_size += 188;
      if (data_buffer_size > BUFFER_SIZE)
      {
        CLog::Log(LOGERROR, "CDVDDemuxSMD::Read data_buffer_size is too big: %d", data_buffer_size);
        goto end;
      }
    }

    chunk += 188;
  }

  // no video/audio data was found, nothing to push into SMD
  if (data_buffer_size == 0)
  {
    goto end;
  }

  if(m_state != DEMUX_STATE_RUNNING)
  {
    goto end;
  }

  result = ismd_port_get_status(m_demux_input_port, &port_status);

  if (result != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD:Read: ismd_port_get_status failed %d", result);
    goto end;
  }
  else
  {
    full = port_status.cur_depth >= port_status.max_depth;
  }

  // if port/queue has no space
  if (full)
  {
    // wait for the port event - this will indicate when there is space
    result = ismd_event_wait(m_reading_thread_port_event, 100);
    ismd_event_acknowledge(m_reading_thread_port_event);

    if (result == ISMD_SUCCESS || result == ISMD_ERROR_TIMEOUT)
    {
      if (result == ISMD_ERROR_TIMEOUT)
      {
        CLog::Log(LOGWARNING, "CDVDDemuxSMD::Read Demux is full");
        goto end;
      }
    }
    else
    {
      CLog::Log(LOGERROR, "CDVDDemuxSMD::Read ismd_event_wait failed on reading_thread_port_event %d", result);
      goto end;
    }
  }

  // get buffer
  buffer = ISMD_BUFFER_HANDLE_INVALID;
  result = ismd_buffer_alloc(BUFFER_SIZE, &buffer);
  if (result != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::Read ismd_buffer_alloc failed %d", result);
    goto end;
  }

  result = ismd_buffer_read_desc(buffer, &buffer_desc);
  if (result != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::Read ismd_buffer_read_desc failed %d", result);
    ismd_buffer_dereference(buffer);
    goto end;
  }

  virtual_buffer_address = (char*)OS_MAP_IO_TO_MEM_NOCACHE(buffer_desc.phys.base, buffer_desc.phys.size);
  OS_MEMCPY(virtual_buffer_address, data_buffer, data_buffer_size);

  buf_attrs = (ismd_es_buf_attr_t *) buffer_desc.attributes;

  buffer_desc.phys.level = data_buffer_size;
  buf_attrs->original_pts = 0;
  buf_attrs->local_pts = ISMD_NO_PTS;
  buf_attrs->discontinuity = false;

  result = ismd_buffer_update_desc(buffer, &buffer_desc);
  if (result != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::Read ismd_buffer_update_desc failed %d", result);
    ismd_buffer_dereference(buffer);
    goto end;
  }

  OS_UNMAP_IO_FROM_MEM(virtual_buffer_address, buffer_desc.phys.size);

  result = ismd_port_write(m_demux_input_port, buffer);
  if (result != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "CDVDDemuxSMD::Read ismd_port_write failed %d", result);
    ismd_buffer_dereference(buffer);
    goto end;
  }

  // we wait until first frame show up and then unmute the renderer
  if (!m_bFirstFrame)
  {
    ismd_vidrend_stream_position_info_t info;
    ismd_vidrend_get_stream_position(g_IntelSMDGlobals.GetVidRender(), &info);
    if (info.flip_time != ISMD_NO_PTS)
    {
      g_IntelSMDGlobals.MuteVideoRender(false);
      m_bFirstFrame = true;
    }
  }

  // look for video changes
  ConfigureVideo();

end:
  pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
  pPacket->flags |= DEMUX_PACKET_FLAG_PASSTHROUGH;

  return pPacket;
}
unsigned int CAESinkIntelSMD::SendDataToInput(unsigned char* buffer_data, unsigned int buffer_size)
{
  VERBOSE();
  ismd_result_t smd_ret;
  ismd_buffer_handle_t ismdBuffer;
  ismd_buffer_descriptor_t ismdBufferDesc;

  //printf("audio packet size %d\n", buffer_size);

  if(m_dwBufferLen < buffer_size)
  {
    CLog::Log(LOGERROR, "%s data size %d is bigger that smd buffer size %d\n", __DEBUG_ID__,
        buffer_size, m_dwBufferLen);
    return 0;
  }

  if(m_audioDeviceInput == -1)
  {
    CLog::Log(LOGERROR, "%s - inputPort == -1", __DEBUG_ID__);
    return 0;
  }


  int counter = 0;
  while (counter < 1000)
  {
    smd_ret = ismd_buffer_alloc(m_dwBufferLen, &ismdBuffer);
    if (smd_ret != ISMD_SUCCESS)
    {
      if(g_IntelSMDGlobals.GetAudioDeviceState(m_audioDevice) != ISMD_DEV_STATE_STOP)
      {
        counter++;
        usleep(5000);
      }
      else
      {
        break;
      }
    }
    else
      break;
  }

  if (smd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s - error allocating buffer: %d", __DEBUG_ID__, smd_ret);
    return 0;
  }

  smd_ret = ismd_buffer_read_desc(ismdBuffer, &ismdBufferDesc);
  if (smd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s - error reading descriptor: %d", __DEBUG_ID__, smd_ret);
    ismd_buffer_dereference(ismdBuffer);
    return 0;
  }

  short* buf_ptr = (short *) OS_MAP_IO_TO_MEM_NOCACHE(ismdBufferDesc.phys.base, buffer_size);
  if(buf_ptr == NULL)
  {
    CLog::Log(LOGERROR, "%s - unable to mmap buffer %d", __DEBUG_ID__, ismdBufferDesc.phys.base);
    ismd_buffer_dereference(ismdBuffer);
    return 0;
  }

  memcpy(buf_ptr, buffer_data, buffer_size);
  OS_UNMAP_IO_FROM_MEM(buf_ptr, buffer_size);

  ismdBufferDesc.phys.level = buffer_size;

  smd_ret = ismd_buffer_update_desc(ismdBuffer, &ismdBufferDesc);
  if (smd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s - error updating descriptor: %d", __DEBUG_ID__, smd_ret);
    ismd_buffer_dereference(ismdBuffer);
    return 0;
  }
  counter = 0;
  while (counter < 100)
  {
    smd_ret = ismd_port_write(m_audioDeviceInput, ismdBuffer);
    if (smd_ret != ISMD_SUCCESS)
    {
      if(g_IntelSMDGlobals.GetAudioDeviceState(m_audioDevice) != ISMD_DEV_STATE_STOP)
      {
        counter++;
        usleep(5000);
      }
      else
      {
        break;
      }
    }
    else
      break;
  }
  if(smd_ret != ISMD_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s failed to write buffer %d\n", __DEBUG_ID__, smd_ret);
    ismd_buffer_dereference(ismdBuffer);
    buffer_size = 0;
  }

  return buffer_size;
}