void CDVDDemuxClient::Dispose() { DisposeStreams(); m_pInput = nullptr; m_IDemux = nullptr; }
void CDVDDemuxClient::RequestStreams() { int i = -1; for (auto stream : m_IDemux->GetStreams()) { ++i; if (!stream) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid stream at pos %d", i); DisposeStreams(); return; } if (stream->type == STREAM_AUDIO) { CDemuxStreamAudio *source = dynamic_cast<CDemuxStreamAudio*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid audio stream at pos %d", i); DisposeStreams(); return; } CDemuxStreamAudioClient* st = nullptr; if (m_streams[i]) { st = dynamic_cast<CDemuxStreamAudioClient*>(m_streams[i]); if (!st || (st->codec != source->codec)) DisposeStream(i); } if (!m_streams[i]) { st = new CDemuxStreamAudioClient(); st->m_parser = av_parser_init(source->codec); if(st->m_parser) st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } st->iChannels = source->iChannels; st->iSampleRate = source->iSampleRate; st->iBlockAlign = source->iBlockAlign; st->iBitRate = source->iBitRate; st->iBitsPerSample = source->iBitsPerSample; if (source->ExtraSize > 0 && source->ExtraData) { st->ExtraData = new uint8_t[source->ExtraSize]; st->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) st->ExtraData[j] = source->ExtraData[j]; } m_streams[i] = st; st->m_parser_split = true; st->changes++; } else if (stream->type == STREAM_VIDEO) { CDemuxStreamVideo *source = dynamic_cast<CDemuxStreamVideo*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid video stream at pos %d", i); DisposeStreams(); return; } CDemuxStreamVideoClient* st = nullptr; if (m_streams[i]) { st = dynamic_cast<CDemuxStreamVideoClient*>(m_streams[i]); if (!st || (st->codec != source->codec) || (st->iWidth != source->iWidth) || (st->iHeight != source->iHeight)) DisposeStream(i); } if (!m_streams[i]) { st = new CDemuxStreamVideoClient(); st->m_parser = av_parser_init(source->codec); if(st->m_parser) st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } st->iFpsScale = source->irFpsScale; st->iFpsRate = source->irFpsRate; st->iHeight = source->iHeight; st->iWidth = source->iWidth; st->fAspect = source->fAspect; st->stereo_mode = "mono"; if (source->ExtraSize > 0 && source->ExtraData) { st->ExtraData = new uint8_t[source->ExtraSize]; st->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) st->ExtraData[j] = source->ExtraData[j]; } m_streams[i] = st; st->m_parser_split = true; } else if (stream->type == STREAM_SUBTITLE) { CDemuxStreamSubtitle *source = dynamic_cast<CDemuxStreamSubtitle*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid subtitle stream at pos %d", i); DisposeStreams(); return; } CDemuxStreamSubtitleClient* st = nullptr; if (m_streams[i]) { st = dynamic_cast<CDemuxStreamSubtitleClient*>(m_streams[i]); if (!st || (st->codec != source->codec)) DisposeStream(i); } if (!m_streams[i]) { st = new CDemuxStreamSubtitleClient(); } if (source->ExtraSize == 4) { st->ExtraData = new uint8_t[4]; st->ExtraSize = 4; for (int j=0; j<4; j++) st->ExtraData[j] = source->ExtraData[j]; } m_streams[i] = st; } else if (stream->type == STREAM_TELETEXT) { if (m_streams[i]) { if (m_streams[i]->codec != stream->codec) DisposeStream(i); } if (!m_streams[i]) m_streams[i] = new CDemuxStreamTeletext(); } else if (stream->type == STREAM_RADIO_RDS) { if (m_streams[i]) { if (m_streams[i]->codec != stream->codec) DisposeStream(i); } if (!m_streams[i]) m_streams[i] = new CDemuxStreamRadioRDS(); } else { if (m_streams[i]) DisposeStream(i); m_streams[i] = new CDemuxStream(); } m_streams[i]->codec = stream->codec; m_streams[i]->codecName = stream->codecName; m_streams[i]->bandwidth = stream->bandwidth; m_streams[i]->uniqueId = stream->uniqueId; for (int j=0; j<4; j++) m_streams[i]->language[j] = stream->language[j]; m_streams[i]->realtime = stream->realtime; CLog::Log(LOGDEBUG,"CDVDDemuxClient::RequestStreams(): added/updated stream %d with codec_id %d", m_streams[i]->uniqueId, m_streams[i]->codec); } ++i; // check if we need to dispose any streams no longer in props for (int j = i; j < MAX_STREAMS; j++) { if (m_streams[j]) { CLog::Log(LOGDEBUG,"CDVDDemuxClient::RequestStreams(): disposed stream %d with codec_id %d", m_streams[j]->uniqueId, m_streams[j]->codec); DisposeStream(j); } } }
void CDVDDemuxClient::SetStreamProps(CDemuxStream *stream, std::map<int, std::shared_ptr<CDemuxStream>> &map, bool forceInit) { if (!stream) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid stream"); DisposeStreams(); return; } std::shared_ptr<CDemuxStream> currentStream(GetStreamInternal(stream->uniqueId)); std::shared_ptr<CDemuxStream> toStream; if (stream->type == STREAM_AUDIO) { CDemuxStreamAudio *source = dynamic_cast<CDemuxStreamAudio*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid audio stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>> streamAudio; if (currentStream) streamAudio = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>>(currentStream); if (forceInit || !streamAudio || streamAudio->codec != source->codec) { streamAudio.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamAudio>()); streamAudio->m_parser = av_parser_init(source->codec); if (streamAudio->m_parser) streamAudio->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; streamAudio->iSampleRate = source->iSampleRate; streamAudio->iChannels = source->iChannels; } streamAudio->iBlockAlign = source->iBlockAlign; streamAudio->iBitRate = source->iBitRate; streamAudio->iBitsPerSample = source->iBitsPerSample; if (source->ExtraSize > 0 && source->ExtraData) { delete[] streamAudio->ExtraData; streamAudio->ExtraData = new uint8_t[source->ExtraSize]; streamAudio->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) streamAudio->ExtraData[j] = source->ExtraData[j]; } streamAudio->m_parser_split = true; streamAudio->changes++; map[stream->uniqueId] = streamAudio; toStream = streamAudio; } else if (stream->type == STREAM_VIDEO) { CDemuxStreamVideo *source = dynamic_cast<CDemuxStreamVideo*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid video stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamVideo>> streamVideo; if (currentStream) streamVideo = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamVideo>>(currentStream); if (forceInit || !streamVideo || streamVideo->codec != source->codec) { streamVideo.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamVideo>()); streamVideo->m_parser = av_parser_init(source->codec); if (streamVideo->m_parser) streamVideo->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; streamVideo->iHeight = source->iHeight; streamVideo->iWidth = source->iWidth; } streamVideo->iFpsScale = source->iFpsScale; streamVideo->iFpsRate = source->iFpsRate; streamVideo->fAspect = source->fAspect; streamVideo->iBitRate = source->iBitRate; if (source->ExtraSize > 0 && source->ExtraData) { delete[] streamVideo->ExtraData; streamVideo->ExtraData = new uint8_t[source->ExtraSize]; streamVideo->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) streamVideo->ExtraData[j] = source->ExtraData[j]; } streamVideo->m_parser_split = true; streamVideo->changes++; map[stream->uniqueId] = streamVideo; toStream = streamVideo; } else if (stream->type == STREAM_SUBTITLE) { CDemuxStreamSubtitle *source = dynamic_cast<CDemuxStreamSubtitle*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid subtitle stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>> streamSubtitle; if (currentStream) streamSubtitle = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>>(currentStream); if (!streamSubtitle || streamSubtitle->codec != source->codec) { streamSubtitle.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>()); streamSubtitle->m_parser = av_parser_init(source->codec); if (streamSubtitle->m_parser) streamSubtitle->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } if (source->ExtraSize == 4) { delete[] streamSubtitle->ExtraData; streamSubtitle->ExtraData = new uint8_t[4]; streamSubtitle->ExtraSize = 4; for (int j=0; j<4; j++) streamSubtitle->ExtraData[j] = source->ExtraData[j]; } map[stream->uniqueId] = streamSubtitle; toStream = streamSubtitle; } else if (stream->type == STREAM_TELETEXT) { CDemuxStreamTeletext *source = dynamic_cast<CDemuxStreamTeletext*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid teletext stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>> streamTeletext; if (currentStream) streamTeletext = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>>(currentStream); if (!streamTeletext || streamTeletext->codec != source->codec) { streamTeletext.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>()); } map[stream->uniqueId] = streamTeletext; toStream = streamTeletext; } else if (stream->type == STREAM_RADIO_RDS) { CDemuxStreamRadioRDS *source = dynamic_cast<CDemuxStreamRadioRDS*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStream - invalid radio-rds stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>> streamRDS; if (currentStream) streamRDS = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>>(currentStream); if (!streamRDS || streamRDS->codec != source->codec) { streamRDS.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>()); } map[stream->uniqueId] = streamRDS; toStream = streamRDS; } else { std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStream>> streamGen; streamGen = std::make_shared<CDemuxStreamClientInternalTpl<CDemuxStream>>(); map[stream->uniqueId] = streamGen; toStream = streamGen; } // only update profile / level if we create a new stream // existing streams may be corrected by ParsePacket if (!currentStream) { toStream->profile = stream->profile; toStream->level = stream->level; } toStream->uniqueId = stream->uniqueId; toStream->codec = stream->codec; toStream->codecName = stream->codecName; toStream->flags = stream->flags; toStream->cryptoSession = stream->cryptoSession; toStream->externalInterfaces = stream->externalInterfaces; toStream->language = stream->language; CLog::Log(LOGDEBUG,"CDVDDemuxClient::RequestStream(): added/updated stream %d with codec_id %d", toStream->uniqueId, toStream->codec); }
// IDemux void CInputStream::UpdateStreams() { DisposeStreams(); INPUTSTREAM_IDS streamIDs; try { streamIDs = m_pStruct->GetStreamIds(); } catch (std::exception &e) { DisposeStreams(); CLog::Log(LOGERROR, "CInputStream::UpdateStreams - error GetStreamIds. Reason: %s", e.what()); return; } if (streamIDs.m_streamCount > INPUTSTREAM_IDS::MAX_STREAM_COUNT) { DisposeStreams(); return; } for (unsigned int i=0; i<streamIDs.m_streamCount; i++) { INPUTSTREAM_INFO stream; try { stream = m_pStruct->GetStream(streamIDs.m_streamIds[i]); } catch (std::exception &e) { DisposeStreams(); CLog::Log(LOGERROR, "CInputStream::GetTotalTime - error GetStream. Reason: %s", e.what()); return; } if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_NONE) continue; std::string codecName(stream.m_codecName); StringUtils::ToLower(codecName); AVCodec *codec = avcodec_find_decoder_by_name(codecName.c_str()); if (!codec) continue; CDemuxStream *demuxStream; if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_AUDIO) { CDemuxStreamAudio *audioStream = new CDemuxStreamAudio(); audioStream->iChannels = stream.m_Channels; audioStream->iSampleRate = stream.m_SampleRate; audioStream->iBlockAlign = stream.m_BlockAlign; audioStream->iBitRate = stream.m_BitRate; audioStream->iBitsPerSample = stream.m_BitsPerSample; demuxStream = audioStream; } else if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_VIDEO) { CDemuxStreamVideo *videoStream = new CDemuxStreamVideo(); videoStream->iFpsScale = stream.m_FpsScale; videoStream->iFpsRate = stream.m_FpsRate; videoStream->iWidth = stream.m_Width; videoStream->iHeight = stream.m_Height; videoStream->fAspect = stream.m_Aspect; videoStream->stereo_mode = "mono"; demuxStream = videoStream; } else if (stream.m_streamType == INPUTSTREAM_INFO::TYPE_SUBTITLE) { // TODO needs identifier in INPUTSTREAM_INFO continue; } else continue; demuxStream->codec = codec->id; demuxStream->bandwidth = stream.m_Bandwidth; demuxStream->codecName = stream.m_codecInternalName; demuxStream->uniqueId = streamIDs.m_streamIds[i]; demuxStream->language[0] = stream.m_language[0]; demuxStream->language[1] = stream.m_language[1]; demuxStream->language[2] = stream.m_language[2]; demuxStream->language[3] = stream.m_language[3]; if (stream.m_ExtraData && stream.m_ExtraSize) { demuxStream->ExtraData = new uint8_t[stream.m_ExtraSize]; demuxStream->ExtraSize = stream.m_ExtraSize; for (unsigned int j=0; j<stream.m_ExtraSize; j++) demuxStream->ExtraData[j] = stream.m_ExtraData[j]; } m_streams[demuxStream->uniqueId] = demuxStream; } }
void CDVDDemuxClient::RequestStreams() { std::map<int, std::shared_ptr<CDemuxStream>> m_newStreamMap; for (auto stream : m_IDemux->GetStreams()) { if (!stream) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid stream"); DisposeStreams(); return; } std::shared_ptr<CDemuxStream> dStream = GetStreamInternal(stream->uniqueId); if (stream->type == STREAM_AUDIO) { CDemuxStreamAudio *source = dynamic_cast<CDemuxStreamAudio*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid audio stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>> streamAudio; if (dStream) streamAudio = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamAudio>>(dStream); if (!streamAudio || streamAudio->codec != source->codec) { streamAudio.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamAudio>()); streamAudio->m_parser = av_parser_init(source->codec); if (streamAudio->m_parser) streamAudio->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } streamAudio->iChannels = source->iChannels; streamAudio->iSampleRate = source->iSampleRate; streamAudio->iBlockAlign = source->iBlockAlign; streamAudio->iBitRate = source->iBitRate; streamAudio->iBitsPerSample = source->iBitsPerSample; if (source->ExtraSize > 0 && source->ExtraData) { streamAudio->ExtraData = new uint8_t[source->ExtraSize]; streamAudio->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) streamAudio->ExtraData[j] = source->ExtraData[j]; } streamAudio->m_parser_split = true; streamAudio->changes++; m_newStreamMap[stream->uniqueId] = streamAudio; dStream = streamAudio; } else if (stream->type == STREAM_VIDEO) { CDemuxStreamVideo *source = dynamic_cast<CDemuxStreamVideo*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid video stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamVideo>> streamVideo; if (dStream) streamVideo = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamVideo>>(dStream); if (!streamVideo || streamVideo->codec != source->codec || streamVideo->iWidth != source->iWidth || streamVideo->iHeight != source->iHeight) { streamVideo.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamVideo>()); streamVideo->m_parser = av_parser_init(source->codec); if (streamVideo->m_parser) streamVideo->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } streamVideo->iFpsScale = source->iFpsScale; streamVideo->iFpsRate = source->iFpsRate; streamVideo->iHeight = source->iHeight; streamVideo->iWidth = source->iWidth; streamVideo->fAspect = source->fAspect; streamVideo->stereo_mode = "mono"; if (source->ExtraSize > 0 && source->ExtraData) { streamVideo->ExtraData = new uint8_t[source->ExtraSize]; streamVideo->ExtraSize = source->ExtraSize; for (unsigned int j=0; j<source->ExtraSize; j++) streamVideo->ExtraData[j] = source->ExtraData[j]; } streamVideo->m_parser_split = true; streamVideo->changes++; m_newStreamMap[stream->uniqueId] = streamVideo; dStream = streamVideo; } else if (stream->type == STREAM_SUBTITLE) { CDemuxStreamSubtitle *source = dynamic_cast<CDemuxStreamSubtitle*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid subtitle stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>> streamSubtitle; if (dStream) streamSubtitle = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>>(dStream); if (!streamSubtitle || streamSubtitle->codec != source->codec) { streamSubtitle.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamSubtitle>()); streamSubtitle->m_parser = av_parser_init(source->codec); if (streamSubtitle->m_parser) streamSubtitle->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } if (source->ExtraSize == 4) { streamSubtitle->ExtraData = new uint8_t[4]; streamSubtitle->ExtraSize = 4; for (int j=0; j<4; j++) streamSubtitle->ExtraData[j] = source->ExtraData[j]; } m_newStreamMap[stream->uniqueId] = streamSubtitle; dStream = streamSubtitle; } else if (stream->type == STREAM_TELETEXT) { CDemuxStreamTeletext *source = dynamic_cast<CDemuxStreamTeletext*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid teletext stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>> streamTeletext; if (dStream) streamTeletext = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>>(dStream); if (!streamTeletext || streamTeletext->codec != source->codec) { streamTeletext.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamTeletext>()); } m_newStreamMap[stream->uniqueId] = streamTeletext; dStream = streamTeletext; } else if (stream->type == STREAM_RADIO_RDS) { CDemuxStreamRadioRDS *source = dynamic_cast<CDemuxStreamRadioRDS*>(stream); if (!source) { CLog::Log(LOGERROR, "CDVDDemuxClient::RequestStreams - invalid radio-rds stream with id %d", stream->uniqueId); DisposeStreams(); return; } std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>> streamRDS; if (dStream) streamRDS = std::dynamic_pointer_cast<CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>>(dStream); if (!streamRDS || streamRDS->codec != source->codec) { streamRDS.reset(new CDemuxStreamClientInternalTpl<CDemuxStreamRadioRDS>()); } m_newStreamMap[stream->uniqueId] = streamRDS; dStream = streamRDS; } else { std::shared_ptr<CDemuxStreamClientInternalTpl<CDemuxStream>> streamGen; streamGen = std::make_shared<CDemuxStreamClientInternalTpl<CDemuxStream>>(); m_newStreamMap[stream->uniqueId] = streamGen; dStream = streamGen; } dStream->uniqueId = stream->uniqueId; dStream->codec = stream->codec; dStream->codecName = stream->codecName; dStream->bandwidth = stream->bandwidth; dStream->uniqueId = stream->uniqueId; for (int j=0; j<4; j++) dStream->language[j] = stream->language[j]; dStream->realtime = stream->realtime; CLog::Log(LOGDEBUG,"CDVDDemuxClient::RequestStreams(): added/updated stream %d with codec_id %d", dStream->uniqueId, dStream->codec); } m_streams = m_newStreamMap; }