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; }