示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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);
}
示例#4
0
文件: OMXReader.cpp 项目: darcyg/pi
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;
}