static int dvd_file_read(void *h, uint8_t* buf, int size) { if(interrupt_cb(NULL)) return -1; XFILE::CFile *pFile = (XFILE::CFile *)h; return pFile->Read(buf, size); }
static int read_callback(void *h, uint8_t* buf, int size) { if(interrupt_cb(NULL)) return -1; XFILE::File *pFile = (XFILE::File *)h; return pFile->Read(buf, size); }
static offset_t dvd_file_seek(void *h, offset_t pos, int whence) { if(interrupt_cb(NULL)) return -1; XFILE::CFile *pFile = (XFILE::CFile *)h; if(whence == AVSEEK_SIZE) return pFile->GetLength(); else return pFile->Seek(pos, whence & ~AVSEEK_FORCE); }
OMXPacket *OMXReader::Read() { AVPacket pkt; OMXPacket *m_omx_pkt = NULL; int result = -1; if(!m_pFormatContext || m_eof) return NULL; Lock(); // assume we are not eof if(m_pFormatContext->pb) m_pFormatContext->pb->eof_reached = 0; // keep track if ffmpeg doesn't always set these pkt.size = 0; pkt.data = NULL; pkt.stream_index = MAX_OMX_STREAMS; RESET_TIMEOUT(1); result = m_dllAvFormat.av_read_frame(m_pFormatContext, &pkt); if (result < 0) { m_eof = true; //FlushRead(); //m_dllAvCodec.av_free_packet(&pkt); UnLock(); return NULL; } if (pkt.size < 0 || pkt.stream_index >= MAX_OMX_STREAMS || interrupt_cb(NULL)) { // XXX, in some cases ffmpeg returns a negative packet size if(m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached) { CLog::Log(LOGERROR, "OMXReader::Read no valid packet"); //FlushRead(); } m_dllAvCodec.av_free_packet(&pkt); m_eof = true; UnLock(); return NULL; } AVStream *pStream = m_pFormatContext->streams[pkt.stream_index]; /* only read packets for active streams */ /* if(!IsActive(pkt.stream_index)) { m_dllAvCodec.av_free_packet(&pkt); UnLock(); return NULL; } */ // lavf sometimes bugs out and gives 0 dts/pts instead of no dts/pts // since this could only happens on initial frame under normal // circomstances, let's assume it is wrong all the time #if 0 if(pkt.dts == 0) pkt.dts = AV_NOPTS_VALUE; if(pkt.pts == 0) pkt.pts = AV_NOPTS_VALUE; #endif if(m_bMatroska && pStream->codec && pStream->codec->codec_type == AVMEDIA_TYPE_VIDEO) { // matroska can store different timestamps // for different formats, for native stored // stuff it is pts, but for ms compatibility // tracks, it is really dts. sadly ffmpeg // sets these two timestamps equal all the // time, so we select it here instead if(pStream->codec->codec_tag == 0) pkt.dts = AV_NOPTS_VALUE; else pkt.pts = AV_NOPTS_VALUE; } // we need to get duration slightly different for matroska embedded text subtitels if(m_bMatroska && pStream->codec->codec_id == AV_CODEC_ID_SUBRIP && pkt.convergence_duration != 0) pkt.duration = pkt.convergence_duration; if(m_bAVI && pStream->codec && pStream->codec->codec_type == AVMEDIA_TYPE_VIDEO) { // AVI's always have borked pts, specially if m_pFormatContext->flags includes // AVFMT_FLAG_GENPTS so always use dts pkt.pts = AV_NOPTS_VALUE; } m_omx_pkt = AllocPacket(pkt.size); /* oom error allocation av packet */ if(!m_omx_pkt) { m_eof = true; m_dllAvCodec.av_free_packet(&pkt); UnLock(); return NULL; } m_omx_pkt->codec_type = pStream->codec->codec_type; /* copy content into our own packet */ m_omx_pkt->size = pkt.size; if (pkt.data) memcpy(m_omx_pkt->data, pkt.data, m_omx_pkt->size); m_omx_pkt->stream_index = pkt.stream_index; GetHints(pStream, &m_omx_pkt->hints); m_omx_pkt->dts = ConvertTimestamp(pkt.dts, pStream->time_base.den, pStream->time_base.num); m_omx_pkt->pts = ConvertTimestamp(pkt.pts, pStream->time_base.den, pStream->time_base.num); m_omx_pkt->duration = DVD_SEC_TO_TIME((double)pkt.duration * pStream->time_base.num / pStream->time_base.den); // used to guess streamlength if (m_omx_pkt->dts != DVD_NOPTS_VALUE && (m_omx_pkt->dts > m_iCurrentPts || m_iCurrentPts == DVD_NOPTS_VALUE)) m_iCurrentPts = m_omx_pkt->dts; // check if stream has passed full duration, needed for live streams if(pkt.dts != (int64_t)AV_NOPTS_VALUE) { int64_t duration; duration = pkt.dts; if(pStream->start_time != (int64_t)AV_NOPTS_VALUE) duration -= pStream->start_time; if(duration > pStream->duration) { pStream->duration = duration; duration = m_dllAvUtil.av_rescale_rnd(pStream->duration, (int64_t)pStream->time_base.num * AV_TIME_BASE, pStream->time_base.den, AV_ROUND_NEAR_INF); if ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE) || (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration)) m_pFormatContext->duration = duration; } } m_dllAvCodec.av_free_packet(&pkt); UnLock(); return m_omx_pkt; }