std::string OMXPlayerVideo::GetText() { OMXPacket *pkt = NULL; std::string strSubtitle = ""; LockSubtitles(); if (!m_subtitle_packets.empty()) { pkt = m_subtitle_packets.front(); if(!m_overlays.empty()) { COMXOverlay *overlay = m_overlays.front(); double now = m_av_clock->GetClock(); double iPTSStartTime = pkt->pts; double iPTSStopTime = (overlay->iPTSStartTime > 0) ? iPTSStartTime + (overlay->iPTSStopTime - overlay->iPTSStartTime) : 0LL; if((iPTSStartTime <= now) && (iPTSStopTime >= now || iPTSStopTime == 0LL)) { COMXOverlayText::CElement* e = ((COMXOverlayText*)overlay)->m_pHead; while (e) { if (e->IsElementType(COMXOverlayText::ELEMENT_TYPE_TEXT)) { COMXOverlayText::CElementText* t = (COMXOverlayText::CElementText*)e; strSubtitle += t->m_text; strSubtitle += "\n"; } e = e->pNext; } } else if(iPTSStopTime < now) { m_subtitle_packets.pop_front(); m_overlays.pop_front(); delete overlay; OMXReader::FreePacket(pkt); } } } UnLockSubtitles(); return strSubtitle; }
bool OMXPlayerVideo::Decode(OMXPacket *pkt) { if(!pkt) return false; bool ret = false; if(!((unsigned long)m_decoder->GetFreeSpace() > pkt->size)) OMXClock::OMXSleep(10); if (pkt->dts == DVD_NOPTS_VALUE && pkt->pts == DVD_NOPTS_VALUE) pkt->pts = m_pts; else if (pkt->pts == DVD_NOPTS_VALUE) pkt->pts = pkt->dts; if(pkt->pts != DVD_NOPTS_VALUE) { m_pts = pkt->pts; m_pts += m_iVideoDelay; } if(pkt->hints.codec == CODEC_ID_TEXT || pkt->hints.codec == CODEC_ID_SSA ) { if(!m_pSubtitleCodec) { m_pSubtitleCodec = new COMXOverlayCodecText(); m_pSubtitleCodec->Open( pkt->hints ); } int result = m_pSubtitleCodec->Decode(pkt->data, pkt->size, pkt->pts, pkt->duration); COMXOverlay* overlay; std::string strSubtitle = ""; double pts = pkt->dts != DVD_NOPTS_VALUE ? pkt->dts : pkt->pts; double duration = pkt->duration; if(result == OC_OVERLAY) { while((overlay = m_pSubtitleCodec->GetOverlay()) != NULL) { if(overlay->iPTSStopTime > overlay->iPTSStartTime) duration = overlay->iPTSStopTime - overlay->iPTSStartTime; else if(pkt->duration != DVD_NOPTS_VALUE) duration = pkt->duration; else duration = 0.0; if (pkt->pts != DVD_NOPTS_VALUE) pts = pkt->pts; else if(pkt->dts != DVD_NOPTS_VALUE) pts = pkt->dts; else pts = overlay->iPTSStartTime; pts -= m_iSubtitleDelay; overlay->iPTSStartTime = pts; if(duration) overlay->iPTSStopTime = pts + duration; else { overlay->iPTSStopTime = 0; overlay->replace = true; } COMXOverlayText::CElement* e = ((COMXOverlayText*)overlay)->m_pHead; while (e) { if (e->IsElementType(COMXOverlayText::ELEMENT_TYPE_TEXT)) { COMXOverlayText::CElementText* t = (COMXOverlayText::CElementText*)e; strSubtitle += t->m_text; strSubtitle += "\n"; } e = e->pNext; } m_overlays.push_back(overlay); if(strSubtitle.length()) m_decoder->DecodeText((uint8_t *)strSubtitle.c_str(), strSubtitle.length(), overlay->iPTSStartTime, overlay->iPTSStartTime); } } ret = true; } else if((unsigned long)m_decoder->GetFreeSpace() > pkt->size) { if(m_bMpeg) m_decoder->Decode(pkt->data, pkt->size, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE); else m_decoder->Decode(pkt->data, pkt->size, m_pts, m_pts); m_av_clock->SetVideoClock(m_pts); Output(m_pts); ret = true; } return ret; }
bool OMXPlayerVideo::Decode(OMXPacket *pkt) { if(!pkt) return false; if(pkt->hints.codec == AV_CODEC_ID_TEXT || pkt->hints.codec == AV_CODEC_ID_SSA ) { if(!m_pSubtitleCodec) { m_pSubtitleCodec = new COMXOverlayCodecText(); m_pSubtitleCodec->Open( pkt->hints ); } int result = m_pSubtitleCodec->Decode(pkt->data, pkt->size, pkt->pts, pkt->duration); COMXOverlay* overlay; std::string strSubtitle = ""; double pts = pkt->dts != DVD_NOPTS_VALUE ? pkt->dts : pkt->pts; double duration = pkt->duration; if(result == OC_OVERLAY) { while((overlay = m_pSubtitleCodec->GetOverlay()) != NULL) { if(overlay->iPTSStopTime > overlay->iPTSStartTime) duration = overlay->iPTSStopTime - overlay->iPTSStartTime; else if(pkt->duration != DVD_NOPTS_VALUE) duration = pkt->duration; else duration = 0.0; if (pkt->pts != DVD_NOPTS_VALUE) pts = pkt->pts; else if(pkt->dts != DVD_NOPTS_VALUE) pts = pkt->dts; else pts = overlay->iPTSStartTime; pts -= m_iSubtitleDelay; overlay->iPTSStartTime = pts; if(duration) overlay->iPTSStopTime = pts + duration; else { overlay->iPTSStopTime = 0; overlay->replace = true; } COMXOverlayText::CElement* e = ((COMXOverlayText*)overlay)->m_pHead; while (e) { if (e->IsElementType(COMXOverlayText::ELEMENT_TYPE_TEXT)) { COMXOverlayText::CElementText* t = (COMXOverlayText::CElementText*)e; strSubtitle += t->m_text; strSubtitle += "\n"; } e = e->pNext; } m_overlays.push_back(overlay); if(strSubtitle.length()) m_decoder->DecodeText((uint8_t *)strSubtitle.c_str(), strSubtitle.length(), overlay->iPTSStartTime, overlay->iPTSStartTime); } } } else { // some packed bitstream AVI files set almost all pts values to DVD_NOPTS_VALUE, but have a scattering of real pts values. // the valid pts values match the dts values. // if a stream has had more than 4 valid pts values in the last 16, the use UNKNOWN, otherwise use dts m_history_valid_pts = (m_history_valid_pts << 1) | (pkt->pts != DVD_NOPTS_VALUE); double pts = pkt->pts; if(pkt->pts == DVD_NOPTS_VALUE && (m_iCurrentPts == DVD_NOPTS_VALUE || count_bits(m_history_valid_pts & 0xffff) < 4)) pts = pkt->dts; if (pts != DVD_NOPTS_VALUE) pts += m_iVideoDelay; if(pts != DVD_NOPTS_VALUE) m_iCurrentPts = pts; while((int) m_decoder->GetFreeSpace() < pkt->size) { OMXClock::OMXSleep(10); if(m_flush_requested) return true; } CLog::Log(LOGINFO, "CDVDPlayerVideo::Decode dts:%.0f pts:%.0f cur:%.0f, size:%d", pkt->dts, pkt->pts, m_iCurrentPts, pkt->size); m_decoder->Decode(pkt->data, pkt->size, pts); } return true; }