Esempio n. 1
0
bool OMXReader::Close()
{
  if (m_pFormatContext)
  {
    if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext)
    {
      CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak");
      m_ioContext = m_pFormatContext->pb;
    }
    m_dllAvFormat.avformat_close_input(&m_pFormatContext);
  }

  if(m_ioContext)
  {
    m_dllAvUtil.av_free(m_ioContext->buffer);
    m_dllAvUtil.av_free(m_ioContext);
  }
  
  m_ioContext       = NULL;
  m_pFormatContext  = NULL;

  if(m_pFile)
  {
    m_pFile->Close();
    delete m_pFile;
    m_pFile = NULL;
  }

  m_dllAvFormat.avformat_network_deinit();

  m_dllAvUtil.Unload();
  m_dllAvCodec.Unload();
  m_dllAvFormat.Unload();

  m_open            = false;
  m_filename        = "";
  m_bMatroska       = false;
  m_bAVI            = false;
  m_bMpeg           = false;
  m_video_count     = 0;
  m_audio_count     = 0;
  m_subtitle_count  = 0;
  m_audio_index     = -1;
  m_video_index     = -1;
  m_subtitle_index  = -1;
  m_eof             = false;
  m_chapter_count   = 0;
  m_iCurrentPts     = DVD_NOPTS_VALUE;
  m_speed           = DVD_PLAYSPEED_NORMAL;

  ClearStreams();

  return true;
}
Esempio n. 2
0
bool OMXReader::close()
{
    if (avFormatContext)
    {
        if (avioContext && avFormatContext->pb && avFormatContext->pb != avioContext)
        {
            ofLog(OF_LOG_WARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak");
            avioContext = avFormatContext->pb;
        }
        avformat_close_input(&avFormatContext);
    }
    
    if(avioContext)
    {
        av_free(avioContext->buffer);
        av_free(avioContext);
    }
    
    avioContext       = NULL;
    avFormatContext  = NULL;
    
    if(fileObject)
    {
        fileObject->close();
        delete fileObject;
        fileObject = NULL;
    }
    
    
    
    
    isOpen            = false;
    fileName        = "";
    isMatroska       = false;
    isAVI            = false;
    videoCount     = 0;
    audioCount     = 0;
    subtitleCount  = 0;
    audioIndex     = -1;
    videoIndex     = -1;
    subtitleIndex  = -1;
    isEOF             = false;
    chapterCount   = 0;
    currentPTS     = DVD_NOPTS_VALUE;
    speed           = DVD_PLAYSPEED_NORMAL;
    
    ClearStreams();
    
    return true;
}
Esempio n. 3
0
OMXReader::OMXReader()
{
  m_open        = false;
  m_filename    = "";
  m_bMatroska   = false;
  m_bAVI        = false;
  g_abort       = false;
  m_pFile       = NULL;
  m_ioContext   = NULL;
  m_pFormatContext = NULL;
  m_eof           = false;
  m_chapter_count = 0;
  m_iCurrentPts   = DVD_NOPTS_VALUE;

  for(int i = 0; i < MAX_STREAMS; i++)
    m_streams[i].extradata = NULL;

  ClearStreams();

  pthread_mutex_init(&m_lock, NULL);
}
Esempio n. 4
0
OMXReader::OMXReader()
{
    isOpen = false;
    fileName = "";
    isMatroska = false;
    isAVI = false;
    fileObject = NULL;
    avioContext = NULL;
    avFormatContext = NULL;
    isEOF = false;
    chapterCount = 0;
    currentPTS = DVD_NOPTS_VALUE;
    
    for(int i = 0; i < MAX_STREAMS; i++)
    {
        omxStreams[i].extradata = NULL;
    }
    
    ClearStreams();
    
    pthread_mutex_init(&m_lock, NULL);
}
Esempio n. 5
0
Multiplexer::~Multiplexer()
{
    ClearStreams();
    delete m_pdatastreams;
}
Esempio n. 6
0
bool OMXReader::GetStreams()
{
  if(!m_pFormatContext)
    return false;

  unsigned int    m_program         = UINT_MAX;

  ClearStreams();

  if (m_pFormatContext->nb_programs)
  {
    // look for first non empty stream and discard nonselected programs
    for (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++)
    {
      if(m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0)
        m_program = i;

      if(i != m_program)
        m_pFormatContext->programs[i]->discard = AVDISCARD_ALL;
    }
      if(m_program != UINT_MAX)
      {
        // add streams from selected program
        for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
          AddStream(m_pFormatContext->programs[m_program]->stream_index[i]);
      }
    }

  // if there were no programs or they were all empty, add all streams
  if (m_program == UINT_MAX)
  {
    for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
      AddStream(i);
  }

  if(m_video_count)
    SetActiveStreamInternal(OMXSTREAM_VIDEO, 0);

  if(m_audio_count)
    SetActiveStreamInternal(OMXSTREAM_AUDIO, 0);

  if(m_subtitle_count)
    SetActiveStreamInternal(OMXSTREAM_SUBTITLE, 0);

  int i = 0;
  for(i = 0; i < MAX_OMX_CHAPTERS; i++)
  {
    m_chapters[i].name      = "";
    m_chapters[i].seekto_ms = 0;
    m_chapters[i].ts        = 0;
  }

  m_chapter_count = 0;

  if(m_video_index != -1)
  {
    //m_current_chapter = 0;
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,14,0)
    m_chapter_count = (m_pFormatContext->nb_chapters > MAX_OMX_CHAPTERS) ? MAX_OMX_CHAPTERS : m_pFormatContext->nb_chapters;
    for(i = 0; i < m_chapter_count; i++)
    {
      if(i > MAX_OMX_CHAPTERS)
        break;

      AVChapter *chapter = m_pFormatContext->chapters[i];
      if(!chapter)
        continue;

      //m_chapters[i].seekto_ms = ConvertTimestamp(chapter->start, chapter->time_base.den, chapter->time_base.num) / 1000;
      m_chapters[i].seekto_ms = ConvertTimestamp(chapter->start, &chapter->time_base) / 1000;
      m_chapters[i].ts        = m_chapters[i].seekto_ms / 1000;

#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,83,0)
      AVDictionaryEntry *titleTag = m_dllAvUtil.av_dict_get(m_pFormatContext->chapters[i]->metadata,"title", NULL, 0);
      if (titleTag)
        m_chapters[i].name = titleTag->value;
#else
      if(m_pFormatContext->chapters[i]->title)
        m_chapters[i].name = m_pFormatContext->chapters[i]->title;
#endif
      printf("Chapter : \t%d \t%s \t%8.2f\n", i, m_chapters[i].name.c_str(), m_chapters[i].ts);
    }
  }
#endif

  return true;
}
Esempio n. 7
0
bool OMXReader::Open(std::string filename, bool dump_format)
{
  if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load())
    return false;
  
  m_iCurrentPts = DVD_NOPTS_VALUE;
  m_filename    = filename; 
  m_speed       = DVD_PLAYSPEED_NORMAL;
  m_program     = UINT_MAX;
  const AVIOInterruptCB int_cb = { interrupt_cb, NULL };

  ClearStreams();

  m_dllAvFormat.av_register_all();
  m_dllAvFormat.avformat_network_init();
  m_dllAvUtil.av_log_set_level(AV_LOG_QUIET);

  int           result    = -1;
  AVInputFormat *iformat  = NULL;
  unsigned char *buffer   = NULL;
  unsigned int  flags     = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;
#ifndef STANDALONE
  if( CFileItem(m_filename, false).IsInternetStream() )
    flags |= READ_CACHED;
#endif

  if(m_filename.substr(0, 8) == "shout://" )
    m_filename.replace(0, 8, "http://");

  if(m_filename.substr(0,6) == "mms://" || m_filename.substr(0,7) == "http://" || 
      m_filename.substr(0,7) == "rtmp://" || m_filename.substr(0,6) == "udp://")
  {
    // ffmpeg dislikes the useragent from AirPlay urls
    //int idx = m_filename.Find("|User-Agent=AppleCoreMedia");
    size_t idx = m_filename.find("|");
    if(idx != string::npos)
      m_filename = m_filename.substr(0, idx);

    result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, NULL);
    if(result < 0)
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - avformat_open_input %s ", m_filename.c_str());
      Close();
      return false;
    }
  }
  else
  {
    m_pFile = new CFile();

    if (!m_pFile->Open(m_filename, flags))
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - %s ", m_filename.c_str());
      Close();
      return false;
    }

    buffer = (unsigned char*)m_dllAvUtil.av_malloc(FFMPEG_FILE_BUFFER_SIZE);
    m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, m_pFile, dvd_file_read, NULL, dvd_file_seek);
    m_ioContext->max_packet_size = 6144;
    if(m_ioContext->max_packet_size)
      m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size;

    if(m_pFile->IoControl(IOCTRL_SEEK_POSSIBLE, NULL) == 0)
      m_ioContext->seekable = 0;

    m_dllAvFormat.av_probe_input_buffer(m_ioContext, &iformat, m_filename.c_str(), NULL, 0, 0);

    if(!iformat)
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - av_probe_input_buffer %s ", m_filename.c_str());
      Close();
      return false;
    }

    m_pFormatContext     = m_dllAvFormat.avformat_alloc_context();
    m_pFormatContext->pb = m_ioContext;
    result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, NULL);
    if(result < 0)
    {
      Close();
      return false;
    }
  }

  // set the interrupt callback, appeared in libavformat 53.15.0
  m_pFormatContext->interrupt_callback = int_cb;

  m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
  m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0;
  m_bMpeg = strcmp(m_pFormatContext->iformat->name, "mpeg") == 0;

  // if format can be nonblocking, let's use that
  m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;

  // analyse very short to speed up mjpeg playback start
  if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0)
    m_pFormatContext->max_analyze_duration = 500000;

#ifdef STANDALONE
  if(/*m_bAVI || */m_bMatroska)
    m_pFormatContext->max_analyze_duration = 0;
#endif

  result = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
  if(result < 0)
  {
    Close();
    return false;
  }

  if(!GetStreams())
  {
    Close();
    return false;
  }

  if(m_pFile)
  {
    int64_t len = m_pFile->GetLength();
    int64_t tim = GetStreamLength();

    if(len > 0 && tim > 0)
    {
      unsigned rate = len * 1000 / tim;
      unsigned maxrate = rate + 1024 * 1024 / 8;
      if(m_pFile->IoControl(IOCTRL_CACHE_SETRATE, &maxrate) >= 0)
        CLog::Log(LOGDEBUG, "COMXPlayer::OpenFile - set cache throttle rate to %u bytes per second", maxrate);
    }
  }

  printf("file : %s reult %d format %s audio streams %d video streams %d chapters %d subtitles %d\n", 
      m_filename.c_str(), result, m_pFormatContext->iformat->name, m_audio_count, m_video_count, m_chapter_count, m_subtitle_count);


  m_speed       = DVD_PLAYSPEED_NORMAL;

  if(dump_format)
    m_dllAvFormat.av_dump_format(m_pFormatContext, 0, m_filename.c_str(), 0);

  UpdateCurrentPTS();

  m_open        = true;

  return true;
}
Esempio n. 8
0
bool OMXReader::open(std::string filename, bool doSkipAvProbe)
{
    
    currentPTS = DVD_NOPTS_VALUE;
    fileName    = filename; 
    speed       = DVD_PLAYSPEED_NORMAL;
    programID     = UINT_MAX;
    AVIOInterruptCB int_cb = { interrupt_cb, NULL };
    
    ClearStreams();
    
    
    int           result    = -1;
    AVInputFormat *iformat  = NULL;
    unsigned char *buffer   = NULL;
    unsigned int  flags     = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;
    
    if(fileName.substr(0, 8) == "shout://" )
        fileName.replace(0, 8, "http://");
    
    if(fileName.substr(0,6) == "mms://" || fileName.substr(0,7) == "mmsh://" || fileName.substr(0,7) == "mmst://" || fileName.substr(0,7) == "mmsu://" ||
       fileName.substr(0,7) == "http://" || 
       fileName.substr(0,7) == "rtmp://" || fileName.substr(0,6) == "udp://" ||
       fileName.substr(0,7) == "rtsp://" )
    {
        doSkipAvProbe = false;
        // ffmpeg dislikes the useragent from AirPlay urls
        //int idx = fileName.Find("|User-Agent=AppleCoreMedia");
        size_t idx = fileName.find("|");
        if(idx != string::npos)
            fileName = fileName.substr(0, idx);
        
        AVDictionary *d = NULL;
        // Enable seeking if http
        if(fileName.substr(0,7) == "http://")
        {
            av_dict_set(&d, "seekable", "1", 0);
        }
        ofLog(OF_LOG_VERBOSE, "OMXPlayer::OpenFile - avformat_open_input %s ", fileName.c_str());
        result = avformat_open_input(&avFormatContext, fileName.c_str(), iformat, &d);
        if(av_dict_count(d) == 0)
        {
            ofLog(OF_LOG_VERBOSE, "OMXPlayer::OpenFile - avformat_open_input enabled SEEKING ");
            if(fileName.substr(0,7) == "http://")
                avFormatContext->pb->seekable = AVIO_SEEKABLE_NORMAL;
        }
        av_dict_free(&d);
        if(result < 0)
        {
            ofLog(OF_LOG_ERROR, "OMXPlayer::OpenFile - avformat_open_input %s ", fileName.c_str());
            close();
            return false;
        }
    }
    else
    {
        fileObject = new File();
        
        if (!fileObject->open(fileName, flags))
        {
            ofLog(OF_LOG_ERROR, "OMXPlayer::OpenFile - %s ", fileName.c_str());
            close();
            return false;
        }
        
        buffer = (unsigned char*)av_malloc(FFMPEG_FILE_BUFFER_SIZE);
        
        avioContext = avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, fileObject, read_callback, NULL, seek_callback);
        avioContext->max_packet_size = 6144;
        if(avioContext->max_packet_size)
            avioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / avioContext->max_packet_size;
        
        if(fileObject->IoControl(IOCTRL_SEEK_POSSIBLE, NULL) == 0)
            avioContext->seekable = 0;
        
        
        av_probe_input_buffer(avioContext, &iformat, fileName.c_str(), NULL, 0, 0);
        
        if(!iformat)
        {
            ofLog(OF_LOG_ERROR, "OMXPlayer::OpenFile - av_probe_input_buffer %s ", fileName.c_str());
            close();
            return false;
        }
        
        //#warning experimental
        //iformat->flags |= AVFMT_SEEK_TO_PTS;
        avFormatContext     = avformat_alloc_context();
        avFormatContext->pb = avioContext;
        
        
        
        
        result = avformat_open_input(&avFormatContext, fileName.c_str(), iformat, NULL);
        if(result < 0)
        {
            close();
            return false;
        }
    }
    
    // set the interrupt callback, appeared in libavformat 53.15.0
    avFormatContext->interrupt_callback = int_cb;
    
    isMatroska = strncmp(avFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
    isAVI = strcmp(avFormatContext->iformat->name, "avi") == 0;
    
    // if format can be nonblocking, let's use that
    avFormatContext->flags |= AVFMT_FLAG_NONBLOCK;
    
    // analyse very short to speed up mjpeg playback start
    if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && avioContext->seekable == 0)
        avFormatContext->max_analyze_duration = 500000;
    
    if(/*isAVI || */isMatroska)
        avFormatContext->max_analyze_duration = 0;
    
    
    if(!doSkipAvProbe)
    {
        unsigned long long startTime = ofGetElapsedTimeMillis();
        result = avformat_find_stream_info(avFormatContext, NULL);
        unsigned long long endTime = ofGetElapsedTimeMillis();
        ofLogNotice(__func__) << "avformat_find_stream_info TOOK " << endTime-startTime <<  " MS";
        
        
        
        if(result < 0)
        {
            close();
            return false;
        }
    }
    
    if(!getStreams())
    {
        close();
        return false;
    }
    
    if(fileObject)
    {
        int64_t len = fileObject->GetLength();
        int64_t tim = getStreamLength();
        
        if(len > 0 && tim > 0)
        {
            unsigned rate = len * 1000 / tim;
            unsigned maxrate = rate + 1024 * 1024 / 8;
            if(fileObject->IoControl(IOCTRL_CACHE_SETRATE, &maxrate) >= 0)
                ofLog(OF_LOG_VERBOSE, "OMXPlayer::OpenFile - set cache throttle rate to %u bytes per second", maxrate);
        }
    }
    
    speed       = DVD_PLAYSPEED_NORMAL;
    /*
     if(dump_format)
     av_dump_format(avFormatContext, 0, fileName.c_str(), 0);*/
    
    updateCurrentPTS();
    
    isOpen        = true;
    
    return true;
}
Esempio n. 9
0
bool OMXReader::getStreams()
{
    if(!avFormatContext)
        return false;
    
    unsigned int    programID         = UINT_MAX;
    
    ClearStreams();
    
    if (avFormatContext->nb_programs)
    {
        // look for first non empty stream and discard nonselected programs
        for (unsigned int i = 0; i < avFormatContext->nb_programs; i++)
        {
            if(programID == UINT_MAX && avFormatContext->programs[i]->nb_stream_indexes > 0)
                programID = i;
            
            if(i != programID)
                avFormatContext->programs[i]->discard = AVDISCARD_ALL;
        }
        if(programID != UINT_MAX)
        {
            // add streams from selected program
            for (unsigned int i = 0; i < avFormatContext->programs[programID]->nb_stream_indexes; i++)
                addStream(avFormatContext->programs[programID]->stream_index[i]);
        }
    }
    
    // if there were no programs or they were all empty, add all streams
    if (programID == UINT_MAX)
    {
        for (unsigned int i = 0; i < avFormatContext->nb_streams; i++)
            addStream(i);
    }
    
    if(videoCount)
        setActiveStreamInternal(OMXSTREAM_VIDEO, 0);
    
    if(audioCount)
        setActiveStreamInternal(OMXSTREAM_AUDIO, 0);
    
    if(subtitleCount)
        setActiveStreamInternal(OMXSTREAM_SUBTITLE, 0);
    
    int i = 0;
    for(i = 0; i < MAX_OMX_CHAPTERS; i++)
    {
        omxChapters[i].name      = "";
        omxChapters[i].seekto_ms = 0;
        omxChapters[i].ts        = 0;
    }
    
    chapterCount = 0;
    
    if(videoIndex != -1)
    {
        //m_current_chapter = 0;
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,14,0)
        chapterCount = (avFormatContext->nb_chapters > MAX_OMX_CHAPTERS) ? MAX_OMX_CHAPTERS : avFormatContext->nb_chapters;
        for(i = 0; i < chapterCount; i++)
        {
            if(i > MAX_OMX_CHAPTERS)
                break;
            
            AVChapter *chapter = avFormatContext->chapters[i];
            if(!chapter)
                continue;
            
            omxChapters[i].seekto_ms = ConvertTimestamp(chapter->start, chapter->time_base.den, chapter->time_base.num) / 1000;
            omxChapters[i].ts        = omxChapters[i].seekto_ms / 1000;
            
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,83,0)
            AVDictionaryEntry *titleTag = av_dict_get(avFormatContext->chapters[i]->metadata,"title", NULL, 0);
            if (titleTag)
                omxChapters[i].name = titleTag->value;
#else
            if(avFormatContext->chapters[i]->title)
                omxChapters[i].name = avFormatContext->chapters[i]->title;
#endif
            printf("Chapter : \t%d \t%s \t%8.2f\n", i, omxChapters[i].name.c_str(), omxChapters[i].ts);
        }
    }
#endif
    
    return true;
}
Esempio n. 10
0
bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false */, float timeout /* = 0.0f */, std::string cookie /* = "" */, std::string user_agent /* = "" */)
{
  if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load())
    return false;

  timeout_default_duration = (int64_t) (timeout * 1e9);
  m_iCurrentPts = DVD_NOPTS_VALUE;
  m_filename    = filename; 
  m_speed       = DVD_PLAYSPEED_NORMAL;
  m_program     = UINT_MAX;
  const AVIOInterruptCB int_cb = { interrupt_cb, NULL };
  RESET_TIMEOUT(3);

  ClearStreams();

  m_dllAvFormat.av_register_all();
  m_dllAvFormat.avformat_network_init();
  m_dllAvUtil.av_log_set_level(dump_format ? AV_LOG_INFO:AV_LOG_QUIET);

  int           result    = -1;
  AVInputFormat *iformat  = NULL;
  unsigned char *buffer   = NULL;
  unsigned int  flags     = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;

  m_pFormatContext     = m_dllAvFormat.avformat_alloc_context();
  if (!m_pFormatContext) {
     log_err("Failed to create format context.");
     return false;
  }

  // set the interrupt callback, appeared in libavformat 53.15.0
  m_pFormatContext->interrupt_callback = int_cb;

  // if format can be nonblocking, let's use that
  m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;

  if(m_filename.substr(0, 8) == "shout://" )
    m_filename.replace(0, 8, "http://");

  if(m_filename.substr(0,6) == "mms://" || m_filename.substr(0,7) == "mmsh://" || m_filename.substr(0,7) == "mmst://" || m_filename.substr(0,7) == "mmsu://" ||
      m_filename.substr(0,7) == "http://" || m_filename.substr(0,8) == "https://" ||
      m_filename.substr(0,7) == "rtmp://" || m_filename.substr(0,6) == "udp://" ||
      m_filename.substr(0,7) == "rtsp://" || m_filename.substr(0,6) == "rtp://" ||
      m_filename.substr(0,6) == "ftp://" || m_filename.substr(0,7) == "sftp://" ||
      m_filename.substr(0,6) == "smb://")
  {
    // ffmpeg dislikes the useragent from AirPlay urls
    //int idx = m_filename.Find("|User-Agent=AppleCoreMedia");
    size_t idx = m_filename.find("|");
    if(idx != string::npos)
      m_filename = m_filename.substr(0, idx);

    AVDictionary *d = NULL;
    // Enable seeking if http, ftp
    if(!live && (m_filename.substr(0,7) == "http://" || m_filename.substr(0,6) == "ftp://" ||
       m_filename.substr(0,7) == "sftp://" || m_filename.substr(0,6) == "smb://"))
    {
       av_dict_set(&d, "seekable", "1", 0);
       if(!cookie.empty())
       {
          av_dict_set(&d, "cookies", cookie.c_str(), 0);
       }
       if(!user_agent.empty())
       {
          av_dict_set(&d, "user_agent", user_agent.c_str(), 0);
       }
    }
    CLog::Log(LOGDEBUG, "COMXPlayer::OpenFile - avformat_open_input %s ", m_filename.c_str());
    result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, &d);
    if(av_dict_count(d) == 0)
    {
       CLog::Log(LOGDEBUG, "COMXPlayer::OpenFile - avformat_open_input enabled SEEKING ");
       if(m_filename.substr(0,7) == "http://")
         m_pFormatContext->pb->seekable = AVIO_SEEKABLE_NORMAL;
    }
    av_dict_free(&d);
    if(result < 0)
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - avformat_open_input %s ", m_filename.c_str());
      Close();
      return false;
    }
  }
  else
  {
    m_pFile = new CFile();

    if (!m_pFile->Open(m_filename, flags))
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - %s ", m_filename.c_str());
      Close();
      return false;
    }

    buffer = (unsigned char*)m_dllAvUtil.av_malloc(FFMPEG_FILE_BUFFER_SIZE);
    m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, m_pFile, dvd_file_read, NULL, dvd_file_seek);
    if (!m_ioContext) {
       log_err("Failed to create avio context.");
       return false;
    }

    m_ioContext->max_packet_size = 6144;
    if(m_ioContext->max_packet_size)
      m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size;

    if(m_pFile->IoControl(IOCTRL_SEEK_POSSIBLE, NULL) == 0)
      m_ioContext->seekable = 0;

    m_dllAvFormat.av_probe_input_buffer(m_ioContext, &iformat, m_filename.c_str(), NULL, 0, 0);

    if(!iformat)
    {
      CLog::Log(LOGERROR, "COMXPlayer::OpenFile - av_probe_input_buffer %s ", m_filename.c_str());
      Close();
      return false;
    }

    m_pFormatContext->pb = m_ioContext;
    if (!m_pFormatContext->internal) {
       log_err("AVFormat internal null.");
       abort();
    }

    result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, NULL);
    if(result < 0)
    {
      Close();
      return false;
    }
  }

  m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
  m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0;

  // analyse very short to speed up mjpeg playback start
  if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0)
    m_pFormatContext->max_analyze_duration = 500000;

  if(/*m_bAVI || */m_bMatroska)
    m_pFormatContext->max_analyze_duration = 0;

  if (live)
    m_pFormatContext->flags |= AVFMT_FLAG_NOBUFFER;

  result = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
  if(result < 0)
  {
    Close();
    return false;
  }

  if(!GetStreams())
  {
    Close();
    return false;
  }

  if(m_pFile)
  {
    int64_t len = m_pFile->GetLength();
    int64_t tim = GetStreamLength();

    if(len > 0 && tim > 0)
    {
      unsigned rate = len * 1000 / tim;
      unsigned maxrate = rate + 1024 * 1024 / 8;
      if(m_pFile->IoControl(IOCTRL_CACHE_SETRATE, &maxrate) >= 0)
        CLog::Log(LOGDEBUG, "COMXPlayer::OpenFile - set cache throttle rate to %u bytes per second", maxrate);
    }
  }

  m_speed       = DVD_PLAYSPEED_NORMAL;

  if(dump_format)
    m_dllAvFormat.av_dump_format(m_pFormatContext, 0, m_filename.c_str(), 0);

  UpdateCurrentPTS();

  m_open        = true;

  return true;
}