[bluray] Fix stream info/language retrieval for blurays in non-nav mode.
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDDemuxers / DVDDemuxFFmpeg.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "system.h"
22 #ifndef __STDC_CONSTANT_MACROS
23 #define __STDC_CONSTANT_MACROS
24 #endif
25 #ifndef __STDC_LIMIT_MACROS
26 #define __STDC_LIMIT_MACROS
27 #endif
28 #ifdef TARGET_POSIX
29 #include "stdint.h"
30 #endif
31 #include "DVDDemuxFFmpeg.h"
32 #include "DVDInputStreams/DVDInputStream.h"
33 #include "DVDInputStreams/DVDInputStreamNavigator.h"
34 #ifdef HAVE_LIBBLURAY
35 #include "DVDInputStreams/DVDInputStreamBluray.h"
36 #endif
37 #include "DVDInputStreams/DVDInputStreamPVRManager.h"
38 #include "DVDInputStreams/DVDInputStreamFFmpeg.h"
39 #include "DVDDemuxUtils.h"
40 #include "DVDClock.h" // for DVD_TIME_BASE
41 #include "commons/Exception.h"
42 #include "settings/AdvancedSettings.h"
43 #include "settings/Settings.h"
44 #include "filesystem/File.h"
45 #include "filesystem/Directory.h"
46 #include "utils/log.h"
47 #include "threads/Thread.h"
48 #include "threads/SystemClock.h"
49 #include "utils/TimeUtils.h"
50 #include "URL.h"
51
52 void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo)
53 {
54   if(!m_stream) return;
55   char temp[128];
56   m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
57   strInfo = temp;
58 }
59
60 void CDemuxStreamAudioFFmpeg::GetStreamName(std::string& strInfo)
61 {
62   if(!m_stream) return;
63   if(!m_description.empty())
64     strInfo = m_description;
65   else
66     CDemuxStream::GetStreamName(strInfo);
67 }
68
69 void CDemuxStreamSubtitleFFmpeg::GetStreamName(std::string& strInfo)
70 {
71   if(!m_stream) return;
72   if(!m_description.empty())
73     strInfo = m_description;
74   else
75     CDemuxStream::GetStreamName(strInfo);
76 }
77
78 void CDemuxStreamVideoFFmpeg::GetStreamInfo(std::string& strInfo)
79 {
80   if(!m_stream) return;
81   char temp[128];
82   m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
83   strInfo = temp;
84 }
85
86 void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo)
87 {
88   if(!m_stream) return;
89   char temp[128];
90   m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
91   strInfo = temp;
92 }
93
94 // these need to be put somewhere that are compiled, we should have some better place for it
95
96 int DllAvFormat::m_avformat_refcnt = 0;
97 CCriticalSection DllAvCodec::m_critSection;
98 static CCriticalSection m_logSection;
99 std::map<uintptr_t, CStdString> g_logbuffer;
100
101 void ff_avutil_log(void* ptr, int level, const char* format, va_list va)
102 {
103   CSingleLock lock(m_logSection);
104   uintptr_t threadId = (uintptr_t)CThread::GetCurrentThreadId();
105   CStdString &buffer = g_logbuffer[threadId];
106
107   AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
108
109   if(level >= AV_LOG_DEBUG && 
110      (g_advancedSettings.m_extraLogLevels & LOGFFMPEG) == 0)
111     return;
112   else if(g_advancedSettings.m_logLevel <= LOG_LEVEL_NORMAL)
113     return;
114
115   int type;
116   switch(level)
117   {
118     case AV_LOG_INFO   : type = LOGINFO;    break;
119     case AV_LOG_ERROR  : type = LOGERROR;   break;
120     case AV_LOG_DEBUG  :
121     default            : type = LOGDEBUG;   break;
122   }
123
124   CStdString message, prefix;
125   message.FormatV(format, va);
126
127   prefix.Format("ffmpeg[%X]: ", threadId);
128   if(avc)
129   {
130     if(avc->item_name)
131       prefix += CStdString("[") + avc->item_name(ptr) + "] ";
132     else if(avc->class_name)
133       prefix += CStdString("[") + avc->class_name + "] ";
134   }
135
136   buffer += message;
137   int pos, start = 0;
138   while( (pos = buffer.find_first_of('\n', start)) >= 0 )
139   {
140     if(pos>start)
141       CLog::Log(type, "%s%s", prefix.c_str(), buffer.substr(start, pos-start).c_str());
142     start = pos+1;
143   }
144   buffer.erase(0, start);
145 }
146
147 static void ff_flush_avutil_log_buffers(void)
148 {
149   CSingleLock lock(DllAvCodec::m_critSection);
150
151   /* Loop through the logbuffer list and remove any blank buffers
152      If the thread using the buffer is still active, it will just
153      add a new buffer next time it writes to the log */
154   std::map<uintptr_t, CStdString>::iterator it;
155   for (it = g_logbuffer.begin(); it != g_logbuffer.end(); )
156     if ((*it).second.IsEmpty())
157       g_logbuffer.erase(it++);
158     else
159       ++it;
160 }
161
162 static int interrupt_cb(void* ctx)
163 {
164   CDVDDemuxFFmpeg* demuxer = static_cast<CDVDDemuxFFmpeg*>(ctx);
165   if(demuxer && demuxer->Aborted())
166     return 1;
167   return 0;
168 }
169
170 ////////////////////////////////////////////////////////////////////////////////////////////////
171 ////////////////////////////////////////////////////////////////////////////////////////////////
172 /*
173 static int dvd_file_open(URLContext *h, const char *filename, int flags)
174 {
175   return -1;
176 }
177 */
178
179 static int dvd_file_read(void *h, uint8_t* buf, int size)
180 {
181   if(interrupt_cb(h))
182     return AVERROR_EXIT;
183
184   CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
185   return pInputStream->Read(buf, size);
186 }
187 /*
188 static int dvd_file_write(URLContext *h, uint8_t* buf, int size)
189 {
190   return -1;
191 }
192 */
193 static offset_t dvd_file_seek(void *h, offset_t pos, int whence)
194 {
195   if(interrupt_cb(h))
196     return AVERROR_EXIT;
197
198   CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
199   if(whence == AVSEEK_SIZE)
200     return pInputStream->GetLength();
201   else
202     return pInputStream->Seek(pos, whence & ~AVSEEK_FORCE);
203 }
204
205 ////////////////////////////////////////////////////////////////////////////////////////////////
206 ////////////////////////////////////////////////////////////////////////////////////////////////
207
208 CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux()
209 {
210   m_pFormatContext = NULL;
211   m_pInput = NULL;
212   m_ioContext = NULL;
213   m_iCurrentPts = DVD_NOPTS_VALUE;
214   m_bMatroska = false;
215   m_bAVI = false;
216   m_speed = DVD_PLAYSPEED_NORMAL;
217   m_program = UINT_MAX;
218   m_pkt.result = -1;
219   memset(&m_pkt.pkt, 0, sizeof(AVPacket));
220 }
221
222 CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg()
223 {
224   Dispose();
225   ff_flush_avutil_log_buffers();
226 }
227
228 bool CDVDDemuxFFmpeg::Aborted()
229 {
230   if(m_timeout.IsTimePast())
231     return true;
232
233   CDVDInputStreamFFmpeg * input = dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput);
234   if(input && input->Aborted())
235     return true;
236
237   return false;
238 }
239
240 bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
241 {
242   AVInputFormat* iformat = NULL;
243   std::string strFile;
244   m_iCurrentPts = DVD_NOPTS_VALUE;
245   m_speed = DVD_PLAYSPEED_NORMAL;
246   m_program = UINT_MAX;
247   const AVIOInterruptCB int_cb = { interrupt_cb, this };
248
249   if (!pInput) return false;
250
251   if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load())  {
252     CLog::Log(LOGERROR,"CDVDDemuxFFmpeg::Open - failed to load ffmpeg libraries");
253     return false;
254   }
255
256   // register codecs
257   m_dllAvFormat.av_register_all();
258
259   m_pInput = pInput;
260   strFile = m_pInput->GetFileName();
261
262   bool streaminfo = true; /* set to true if we want to look for streams before playback*/
263
264   if( m_pInput->GetContent().length() > 0 )
265   {
266     std::string content = m_pInput->GetContent();
267
268     /* check if we can get a hint from content */
269     if     ( content.compare("video/x-vobsub") == 0 )
270       iformat = m_dllAvFormat.av_find_input_format("mpeg");
271     else if( content.compare("video/x-dvd-mpeg") == 0 )
272       iformat = m_dllAvFormat.av_find_input_format("mpeg");
273     else if( content.compare("video/x-mpegts") == 0 )
274       iformat = m_dllAvFormat.av_find_input_format("mpegts");
275     else if( content.compare("multipart/x-mixed-replace") == 0 )
276       iformat = m_dllAvFormat.av_find_input_format("mjpeg");
277   }
278
279   // open the demuxer
280   m_pFormatContext  = m_dllAvFormat.avformat_alloc_context();
281   m_pFormatContext->interrupt_callback = int_cb;
282
283   // try to abort after 30 seconds
284   m_timeout.Set(30000);
285
286   if( m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG) )
287   {
288     // special stream type that makes avformat handle file opening
289     // allows internal ffmpeg protocols to be used
290     CURL url = m_pInput->GetURL();
291     CStdString protocol = url.GetProtocol();
292
293     AVDictionary *options = GetFFMpegOptionsFromURL(url);
294
295     int result=-1;
296     if (protocol.Equals("mms"))
297     {
298       // try mmsh, then mmst
299       url.SetProtocol("mmsh");
300       url.SetProtocolOptions("");
301       result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options);
302       if (result < 0)
303       {
304         url.SetProtocol("mmst");
305         strFile = url.Get();
306       } 
307     }
308     if (result < 0 && m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 )
309     {
310       CLog::Log(LOGDEBUG, "Error, could not open file %s", strFile.c_str());
311       Dispose();
312       m_dllAvUtil.av_dict_free(&options);
313       return false;
314     }
315     m_dllAvUtil.av_dict_free(&options);
316   }
317   else
318   {
319     unsigned char* buffer = (unsigned char*)m_dllAvUtil.av_malloc(FFMPEG_FILE_BUFFER_SIZE);
320     m_ioContext = m_dllAvFormat.avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek);
321     m_ioContext->max_packet_size = m_pInput->GetBlockSize();
322     if(m_ioContext->max_packet_size)
323       m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size;
324
325     if(m_pInput->Seek(0, SEEK_POSSIBLE) == 0)
326       m_ioContext->seekable = 0;
327
328     if( iformat == NULL )
329     {
330       // let ffmpeg decide which demuxer we have to open
331
332       bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed");
333
334       if (!trySPDIFonly)
335         m_dllAvFormat.av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0);
336
337       // Use the more low-level code in case we have been built against an old
338       // FFmpeg without the above av_probe_input_buffer(), or in case we only
339       // want to probe for spdif (DTS or IEC 61937) compressed audio
340       // specifically, or in case the file is a wav which may contain DTS or
341       // IEC 61937 (e.g. ac3-in-wav) and we want to check for those formats.
342       if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0))
343       {
344         AVProbeData pd;
345         uint8_t probe_buffer[FFMPEG_FILE_BUFFER_SIZE + AVPROBE_PADDING_SIZE];
346
347         // init probe data
348         pd.buf = probe_buffer;
349         pd.filename = strFile.c_str();
350
351         // read data using avformat's buffers
352         pd.buf_size = m_dllAvFormat.avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : m_ioContext->buffer_size);
353         if (pd.buf_size <= 0)
354         {
355           CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, strFile.c_str());
356           return false;
357         }
358         memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE);
359
360         // restore position again
361         m_dllAvFormat.avio_seek(m_ioContext , 0, SEEK_SET);
362
363         // the advancedsetting is for allowing the user to force outputting the
364         // 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode
365         // it (this is temporary until we handle 44.1 kHz passthrough properly)
366         if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0 && !g_advancedSettings.m_dvdplayerIgnoreDTSinWAV))
367         {
368           // check for spdif and dts
369           // This is used with wav files and audio CDs that may contain
370           // a DTS or AC3 track padded for S/PDIF playback. If neither of those
371           // is present, we assume it is PCM audio.
372           // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS
373           // may be just padded.
374           AVInputFormat *iformat2;
375           iformat2 = m_dllAvFormat.av_find_input_format("spdif");
376
377           if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)
378           {
379             iformat = iformat2;
380           }
381           else
382           {
383             // not spdif or no spdif demuxer, try dts
384             iformat2 = m_dllAvFormat.av_find_input_format("dts");
385
386             if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)
387             {
388               iformat = iformat2;
389             }
390             else if (trySPDIFonly)
391             {
392               // not dts either, return false in case we were explicitely
393               // requested to only check for S/PDIF padded compressed audio
394               CLog::Log(LOGDEBUG, "%s - not spdif or dts file, fallbacking", __FUNCTION__);
395               return false;
396             }
397           }
398         }
399       }
400
401       if(!iformat)
402       {
403         std::string content = m_pInput->GetContent();
404
405         /* check if we can get a hint from content */
406         if( content.compare("audio/aacp") == 0 )
407           iformat = m_dllAvFormat.av_find_input_format("aac");
408         else if( content.compare("audio/aac") == 0 )
409           iformat = m_dllAvFormat.av_find_input_format("aac");
410         else if( content.compare("video/flv") == 0 )
411           iformat = m_dllAvFormat.av_find_input_format("flv");
412         else if( content.compare("video/x-flv") == 0 )
413           iformat = m_dllAvFormat.av_find_input_format("flv");
414       }
415
416       if (!iformat)
417       {
418         CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, strFile.c_str());
419         return false;
420       }
421       else
422       {
423         if (iformat->name)
424           CLog::Log(LOGDEBUG, "%s - probing detected format [%s]", __FUNCTION__, iformat->name);
425         else
426           CLog::Log(LOGDEBUG, "%s - probing detected unnamed format", __FUNCTION__);
427       }
428     }
429
430
431     m_pFormatContext->pb = m_ioContext;
432
433     if (m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0)
434     {
435       CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, strFile.c_str());
436       Dispose();
437       return false;
438     }
439   }
440
441   // Avoid detecting framerate if advancedsettings.xml says so
442   if (g_advancedSettings.m_videoFpsDetect == 0) 
443       m_pFormatContext->fps_probe_size = 0;
444   
445   // analyse very short to speed up mjpeg playback start
446   if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0)
447     m_pFormatContext->max_analyze_duration = 500000;
448
449   // we need to know if this is matroska or avi later
450   m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0;   // for "matroska.webm"
451   m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0;
452
453   if (streaminfo)
454   {
455     /* too speed up dvd switches, only analyse very short */
456     if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD))
457       m_pFormatContext->max_analyze_duration = 500000;
458
459
460     CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__);
461     int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
462     if (iErr < 0)
463     {
464       CLog::Log(LOGWARNING,"could not find codec parameters for %s", strFile.c_str());
465       if (m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)
466       ||  m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY)
467       || (m_pFormatContext->nb_streams == 1 && m_pFormatContext->streams[0]->codec->codec_id == AV_CODEC_ID_AC3))
468       {
469         // special case, our codecs can still handle it.
470       }
471       else
472       {
473         Dispose();
474         return false;
475       }
476     }
477     CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__);
478   }
479   // reset any timeout
480   m_timeout.SetInfinite();
481
482   // if format can be nonblocking, let's use that
483   m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;
484
485   // print some extra information
486   m_dllAvFormat.av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0);
487
488   UpdateCurrentPTS();
489
490   CreateStreams();
491
492   return true;
493 }
494
495 void CDVDDemuxFFmpeg::Dispose()
496 {
497   m_pkt.result = -1;
498   m_dllAvCodec.av_free_packet(&m_pkt.pkt);
499
500   if (m_pFormatContext)
501   {
502     if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext)
503     {
504       CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak");
505       m_ioContext = m_pFormatContext->pb;
506     }
507     m_dllAvFormat.avformat_close_input(&m_pFormatContext);
508   }
509
510   if(m_ioContext)
511   {
512     m_dllAvUtil.av_free(m_ioContext->buffer);
513     m_dllAvUtil.av_free(m_ioContext);
514   }
515
516   m_ioContext = NULL;
517   m_pFormatContext = NULL;
518   m_speed = DVD_PLAYSPEED_NORMAL;
519
520   DisposeStreams();
521
522   m_pInput = NULL;
523
524   m_dllAvFormat.Unload();
525   m_dllAvCodec.Unload();
526   m_dllAvUtil.Unload();
527 }
528
529 void CDVDDemuxFFmpeg::Reset()
530 {
531   CDVDInputStream* pInputStream = m_pInput;
532   Dispose();
533   Open(pInputStream);
534 }
535
536 void CDVDDemuxFFmpeg::Flush()
537 {
538   // naughty usage of an internal ffmpeg function
539   if (m_pFormatContext)
540     m_dllAvFormat.av_read_frame_flush(m_pFormatContext);
541
542   m_iCurrentPts = DVD_NOPTS_VALUE;
543
544   m_pkt.result = -1;
545   m_dllAvCodec.av_free_packet(&m_pkt.pkt);
546 }
547
548 void CDVDDemuxFFmpeg::Abort()
549 {
550   m_timeout.SetExpired();
551 }
552
553 void CDVDDemuxFFmpeg::SetSpeed(int iSpeed)
554 {
555   if(!m_pFormatContext)
556     return;
557
558   if(m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE)
559   {
560     m_pInput->Pause((double)m_iCurrentPts);
561     m_dllAvFormat.av_read_pause(m_pFormatContext);
562   }
563   else if(m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE)
564   {
565     m_pInput->Pause((double)m_iCurrentPts);
566     m_dllAvFormat.av_read_play(m_pFormatContext);
567   }
568   m_speed = iSpeed;
569
570   AVDiscard discard = AVDISCARD_NONE;
571   if(m_speed > 4*DVD_PLAYSPEED_NORMAL)
572     discard = AVDISCARD_NONKEY;
573   else if(m_speed > 2*DVD_PLAYSPEED_NORMAL)
574     discard = AVDISCARD_BIDIR;
575   else if(m_speed < DVD_PLAYSPEED_PAUSE)
576     discard = AVDISCARD_NONKEY;
577
578
579   for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
580   {
581     if(m_pFormatContext->streams[i])
582     {
583       if(m_pFormatContext->streams[i]->discard != AVDISCARD_ALL)
584         m_pFormatContext->streams[i]->discard = discard;
585     }
586   }
587 }
588
589 AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url)
590 {
591   CStdString protocol = url.GetProtocol();
592
593   AVDictionary *options = NULL;
594
595   if (protocol.Equals("http") || protocol.Equals("https"))
596   {
597     std::map<CStdString, CStdString> protocolOptions;
598     url.GetProtocolOptions(protocolOptions);
599     std::string headers;
600     bool hasUserAgent = false;
601     for(std::map<CStdString, CStdString>::const_iterator it = protocolOptions.begin(); it != protocolOptions.end(); ++it)
602     {
603       const CStdString &name = it->first;
604       const CStdString &value = it->second;
605
606       if (name.Equals("seekable"))
607         m_dllAvUtil.av_dict_set(&options, "seekable", value.c_str(), 0);
608       else if (name.Equals("User-Agent"))
609       {
610         m_dllAvUtil.av_dict_set(&options, "user-agent", value.c_str(), 0);
611         hasUserAgent = true;
612       }
613       else if (!name.Equals("auth") && !name.Equals("Encoding"))
614         // all other protocol options can be added as http header.
615         headers.append(name).append(": ").append(value).append("\r\n");
616     }
617     if (!hasUserAgent)
618       // set default xbmc user-agent.
619       m_dllAvUtil.av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0);
620
621     if (!headers.empty())
622       m_dllAvUtil.av_dict_set(&options, "headers", headers.c_str(), 0);
623   }
624   return options;
625 }
626
627 double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num)
628 {
629   if (pts == (int64_t)AV_NOPTS_VALUE)
630     return DVD_NOPTS_VALUE;
631
632   // do calculations in floats as they can easily overflow otherwise
633   // we don't care for having a completly exact timestamp anyway
634   double timestamp = (double)pts * num  / den;
635   double starttime = 0.0f;
636
637   // for dvd's we need the original time
638   if(dynamic_cast<CDVDInputStream::IMenus*>(m_pInput))
639     starttime = dynamic_cast<CDVDInputStream::IMenus*>(m_pInput)->GetTimeStampCorrection() / DVD_TIME_BASE;
640   else if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE)
641     starttime = (double)m_pFormatContext->start_time / AV_TIME_BASE;
642
643   if(timestamp > starttime)
644     timestamp -= starttime;
645   // allow for largest possible difference in pts and dts for a single packet
646   else if( timestamp + 0.5f > starttime )
647     timestamp = 0;
648
649   return timestamp*DVD_TIME_BASE;
650 }
651
652 DemuxPacket* CDVDDemuxFFmpeg::Read()
653 {
654   DemuxPacket* pPacket = NULL;
655   // on some cases where the received packet is invalid we will need to return an empty packet (0 length) otherwise the main loop (in CDVDPlayer)
656   // would consider this the end of stream and stop.
657   bool bReturnEmpty = false;
658   { CSingleLock lock(m_critSection); // open lock scope
659   if (m_pFormatContext)
660   {
661     // assume we are not eof
662     if(m_pFormatContext->pb)
663       m_pFormatContext->pb->eof_reached = 0;
664
665     // check for saved packet after a program change
666     if (m_pkt.result < 0)
667     {
668       // keep track if ffmpeg doesn't always set these
669       m_pkt.pkt.size = 0;
670       m_pkt.pkt.data = NULL;
671
672       // timeout reads after 100ms
673       m_timeout.Set(20000);
674       m_pkt.result = m_dllAvFormat.av_read_frame(m_pFormatContext, &m_pkt.pkt);
675       m_timeout.SetInfinite();
676     }
677
678     if (m_pkt.result == AVERROR(EINTR) || m_pkt.result == AVERROR(EAGAIN))
679     {
680       // timeout, probably no real error, return empty packet
681       bReturnEmpty = true;
682     }
683     else if (m_pkt.result < 0)
684     {
685       Flush();
686     }
687     else if (IsProgramChange())
688     {
689       // update streams
690       CreateStreams(m_program);
691
692       pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
693       pPacket->iStreamId = DMX_SPECIALID_STREAMCHANGE;
694
695       return pPacket;
696     }
697     // check size and stream index for being in a valid range
698     else if (m_pkt.pkt.size < 0 ||
699              m_pkt.pkt.stream_index < 0 ||
700              m_pkt.pkt.stream_index >= m_pFormatContext->nb_streams)
701     {
702       // XXX, in some cases ffmpeg returns a negative packet size
703       if(m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached)
704       {
705         CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() no valid packet");
706         bReturnEmpty = true;
707         Flush();
708       }
709       else
710         CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached");
711
712       m_pkt.result = -1;
713       m_dllAvCodec.av_free_packet(&m_pkt.pkt);
714     }
715     else
716     {
717       AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index];
718
719       if (m_program != UINT_MAX)
720       {
721         /* check so packet belongs to selected program */
722         for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
723         {
724           if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i])
725           {
726             pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
727             break;
728           }
729         }
730
731         if (!pPacket)
732           bReturnEmpty = true;
733       }
734       else
735         pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
736
737       if (pPacket)
738       {
739         // lavf sometimes bugs out and gives 0 dts/pts instead of no dts/pts
740         // since this could only happens on initial frame under normal
741         // circomstances, let's assume it is wrong all the time
742         if(m_pkt.pkt.dts == 0)
743           m_pkt.pkt.dts = AV_NOPTS_VALUE;
744         if(m_pkt.pkt.pts == 0)
745           m_pkt.pkt.pts = AV_NOPTS_VALUE;
746
747         if(m_bMatroska && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
748         { // matroska can store different timestamps
749           // for different formats, for native stored
750           // stuff it is pts, but for ms compatibility
751           // tracks, it is really dts. sadly ffmpeg
752           // sets these two timestamps equal all the
753           // time, so we select it here instead
754           if(stream->codec->codec_tag == 0)
755             m_pkt.pkt.dts = AV_NOPTS_VALUE;
756           else
757             m_pkt.pkt.pts = AV_NOPTS_VALUE;
758         }
759
760         // we need to get duration slightly different for matroska embedded text subtitels
761         if(m_bMatroska && stream->codec->codec_id == AV_CODEC_ID_TEXT && m_pkt.pkt.convergence_duration != 0)
762           m_pkt.pkt.duration = m_pkt.pkt.convergence_duration;
763
764         if(m_bAVI && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
765         {
766           // AVI's always have borked pts, specially if m_pFormatContext->flags includes
767           // AVFMT_FLAG_GENPTS so always use dts
768           m_pkt.pkt.pts = AV_NOPTS_VALUE;
769         }
770
771         // copy contents into our own packet
772         pPacket->iSize = m_pkt.pkt.size;
773
774         // maybe we can avoid a memcpy here by detecting where pkt.destruct is pointing too?
775         if (m_pkt.pkt.data)
776           memcpy(pPacket->pData, m_pkt.pkt.data, pPacket->iSize);
777
778         pPacket->pts = ConvertTimestamp(m_pkt.pkt.pts, stream->time_base.den, stream->time_base.num);
779         pPacket->dts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num);
780         pPacket->duration =  DVD_SEC_TO_TIME((double)m_pkt.pkt.duration * stream->time_base.num / stream->time_base.den);
781
782         // used to guess streamlength
783         if (pPacket->dts != DVD_NOPTS_VALUE && (pPacket->dts > m_iCurrentPts || m_iCurrentPts == DVD_NOPTS_VALUE))
784           m_iCurrentPts = pPacket->dts;
785
786
787         // check if stream has passed full duration, needed for live streams
788         if(m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE)
789         {
790           int64_t duration;
791           duration = m_pkt.pkt.dts;
792           if(stream->start_time != (int64_t)AV_NOPTS_VALUE)
793             duration -= stream->start_time;
794
795           if(duration > stream->duration)
796           {
797             stream->duration = duration;
798             duration = m_dllAvUtil.av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF);
799             if ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE)
800                 ||  (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration))
801               m_pFormatContext->duration = duration;
802           }
803         }
804
805         // store internal id until we know the continuous id presented to player
806         // the stream might not have been created yet
807         pPacket->iStreamId = m_pkt.pkt.stream_index;
808       }
809       m_pkt.result = -1;
810       m_dllAvCodec.av_free_packet(&m_pkt.pkt);
811     }
812   }
813   } // end of lock scope
814   if (bReturnEmpty && !pPacket)
815     pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
816
817   if (!pPacket) return NULL;
818
819   // check streams, can we make this a bit more simple?
820   if (pPacket && pPacket->iStreamId >= 0)
821   {
822     CDemuxStream *stream = GetStreamInternal(pPacket->iStreamId);
823     if (!stream ||
824         stream->pPrivate != m_pFormatContext->streams[pPacket->iStreamId] ||
825         stream->codec != m_pFormatContext->streams[pPacket->iStreamId]->codec->codec_id)
826     {
827       // content has changed, or stream did not yet exist
828       stream = AddStream(pPacket->iStreamId);
829     }
830     // we already check for a valid m_streams[pPacket->iStreamId] above
831     else if (stream->type == STREAM_AUDIO)
832     {
833       if (((CDemuxStreamAudio*)stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codec->channels ||
834           ((CDemuxStreamAudio*)stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codec->sample_rate)
835       {
836         // content has changed
837         stream = AddStream(pPacket->iStreamId);
838       }
839     }
840     else if (stream->type == STREAM_VIDEO)
841     {
842       if (((CDemuxStreamVideo*)stream)->iWidth != m_pFormatContext->streams[pPacket->iStreamId]->codec->width ||
843           ((CDemuxStreamVideo*)stream)->iHeight != m_pFormatContext->streams[pPacket->iStreamId]->codec->height)
844       {
845         // content has changed
846         stream = AddStream(pPacket->iStreamId);
847       }
848     }
849     if (!stream)
850     {
851       CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::AddStream - internal error, stream is null");
852       CDVDDemuxUtils::FreeDemuxPacket(pPacket);
853       return NULL;
854     }
855     // set continuous stream id for player
856     pPacket->iStreamId = stream->iId;
857   }
858   return pPacket;
859 }
860
861 bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
862 {
863   if(time < 0)
864     time = 0;
865
866   m_pkt.result = -1;
867   m_dllAvCodec.av_free_packet(&m_pkt.pkt);
868
869   CDVDInputStream::ISeekTime* ist = dynamic_cast<CDVDInputStream::ISeekTime*>(m_pInput);
870   if (ist)
871   {
872     if (!ist->SeekTime(time))
873       return false;
874
875     if(startpts)
876       *startpts = DVD_NOPTS_VALUE;
877
878     Flush();
879
880     // also empty the internal ffmpeg buffer
881     m_ioContext->buf_ptr = m_ioContext->buf_end;
882
883     return true;
884   }
885
886   if(!m_pInput->Seek(0, SEEK_POSSIBLE)
887   && !m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
888   {
889     CLog::Log(LOGDEBUG, "%s - input stream reports it is not seekable", __FUNCTION__);
890     return false;
891   }
892
893   int64_t seek_pts = (int64_t)time * (AV_TIME_BASE / 1000);
894   if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE)
895     seek_pts += m_pFormatContext->start_time;
896
897   int ret;
898   {
899     CSingleLock lock(m_critSection);
900     ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0);
901
902     if(ret >= 0)
903       UpdateCurrentPTS();
904   }
905
906   if(m_iCurrentPts == DVD_NOPTS_VALUE)
907     CLog::Log(LOGDEBUG, "%s - unknown position after seek", __FUNCTION__);
908   else
909     CLog::Log(LOGDEBUG, "%s - seek ended up on time %d", __FUNCTION__, (int)(m_iCurrentPts / DVD_TIME_BASE * 1000));
910
911   // in this case the start time is requested time
912   if(startpts)
913     *startpts = DVD_MSEC_TO_TIME(time);
914
915   // demuxer will return failure, if you seek to eof
916   if (m_pInput->IsEOF() && ret <= 0)
917     return true;
918
919   return (ret >= 0);
920 }
921
922 bool CDVDDemuxFFmpeg::SeekByte(int64_t pos)
923 {
924   CSingleLock lock(m_critSection);
925   int ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE);
926
927   if(ret >= 0)
928     UpdateCurrentPTS();
929
930   m_pkt.result = -1;
931   m_dllAvCodec.av_free_packet(&m_pkt.pkt);
932
933   return (ret >= 0);
934 }
935
936 void CDVDDemuxFFmpeg::UpdateCurrentPTS()
937 {
938   m_iCurrentPts = DVD_NOPTS_VALUE;
939   for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
940   {
941     AVStream *stream = m_pFormatContext->streams[i];
942     if(stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE)
943     {
944       double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num);
945       if(m_iCurrentPts == DVD_NOPTS_VALUE || m_iCurrentPts > ts )
946         m_iCurrentPts = ts;
947     }
948   }
949 }
950
951 int CDVDDemuxFFmpeg::GetStreamLength()
952 {
953   if (!m_pFormatContext)
954     return 0;
955
956   if (m_pFormatContext->duration < 0)
957     return 0;
958
959   return (int)(m_pFormatContext->duration / (AV_TIME_BASE / 1000));
960 }
961
962 /**
963  * @brief Finds stream based on demuxer index
964  */
965 CDemuxStream* CDVDDemuxFFmpeg::GetStream(int iStreamId)
966 {
967   if(iStreamId >= 0 && (size_t)iStreamId < m_stream_index.size())
968     return m_stream_index[iStreamId]->second;
969   else
970     return NULL;
971 }
972
973 /**
974  * @brief Finds stream based on ffmpeg index
975  */
976 CDemuxStream* CDVDDemuxFFmpeg::GetStreamInternal(int iId)
977 {
978   std::map<int, CDemuxStream*>::iterator it = m_streams.find(iId);
979   if (it == m_streams.end())
980     return NULL;
981   else
982     return it->second;
983 }
984
985 int CDVDDemuxFFmpeg::GetNrOfStreams()
986 {
987   return m_stream_index.size();
988 }
989
990 static double SelectAspect(AVStream* st, bool* forced)
991 {
992   *forced = false;
993   /* if stream aspect is 1:1 or 0:0 use codec aspect */
994   if((st->sample_aspect_ratio.den == 1 || st->sample_aspect_ratio.den == 0)
995   && (st->sample_aspect_ratio.num == 1 || st->sample_aspect_ratio.num == 0)
996   && st->codec->sample_aspect_ratio.num != 0)
997     return av_q2d(st->codec->sample_aspect_ratio);
998
999   *forced = true;
1000   if(st->sample_aspect_ratio.num != 0)
1001     return av_q2d(st->sample_aspect_ratio);
1002
1003   return 0.0;
1004 }
1005
1006 void CDVDDemuxFFmpeg::CreateStreams(unsigned int program)
1007 {
1008   DisposeStreams();
1009
1010   // add the ffmpeg streams to our own stream map
1011   if (m_pFormatContext->nb_programs)
1012   {
1013     // check if desired program is available
1014     if (program < m_pFormatContext->nb_programs && m_pFormatContext->programs[program]->nb_stream_indexes > 0)
1015     {
1016       m_program = program;
1017     }
1018     else
1019       m_program = UINT_MAX;
1020
1021     // look for first non empty stream and discard nonselected programs
1022     for (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++)
1023     {
1024       if(m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0)
1025       {
1026         m_program = i;
1027       }
1028
1029       if(i != m_program)
1030         m_pFormatContext->programs[i]->discard = AVDISCARD_ALL;
1031     }
1032     if(m_program != UINT_MAX)
1033     {
1034       // add streams from selected program
1035       for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
1036         AddStream(m_pFormatContext->programs[m_program]->stream_index[i]);
1037     }
1038   }
1039   else
1040     m_program = UINT_MAX;
1041
1042   // if there were no programs or they were all empty, add all streams
1043   if (m_program == UINT_MAX)
1044   {
1045     for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
1046       AddStream(i);
1047   }
1048 }
1049
1050 void CDVDDemuxFFmpeg::DisposeStreams()
1051 {
1052   std::map<int, CDemuxStream*>::iterator it;
1053   for(it = m_streams.begin(); it != m_streams.end(); ++it)
1054     delete it->second;
1055   m_streams.clear();
1056   m_stream_index.clear();
1057 }
1058
1059 CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId)
1060 {
1061   AVStream* pStream = m_pFormatContext->streams[iId];
1062   if (pStream)
1063   {
1064     CDemuxStream* stream = NULL;
1065
1066     switch (pStream->codec->codec_type)
1067     {
1068     case AVMEDIA_TYPE_AUDIO:
1069       {
1070         CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(this, pStream);
1071         stream = st;
1072         st->iChannels = pStream->codec->channels;
1073         st->iSampleRate = pStream->codec->sample_rate;
1074         st->iBlockAlign = pStream->codec->block_align;
1075         st->iBitRate = pStream->codec->bit_rate;
1076         st->iBitsPerSample = pStream->codec->bits_per_coded_sample;
1077         
1078         if(m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0))
1079           st->m_description = m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)->value;
1080
1081         break;
1082       }
1083     case AVMEDIA_TYPE_VIDEO:
1084       {
1085         CDemuxStreamVideoFFmpeg* st = new CDemuxStreamVideoFFmpeg(this, pStream);
1086         stream = st;
1087         if(strcmp(m_pFormatContext->iformat->name, "flv") == 0)
1088           st->bVFR = true;
1089         else
1090           st->bVFR = false;
1091
1092         // never trust pts in avi files with h264.
1093         if (m_bAVI && pStream->codec->codec_id == AV_CODEC_ID_H264)
1094           st->bPTSInvalid = true;
1095
1096         //average fps is more accurate for mkv files
1097         if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num)
1098         {
1099           st->iFpsRate = pStream->avg_frame_rate.num;
1100           st->iFpsScale = pStream->avg_frame_rate.den;
1101         }
1102         else if(pStream->r_frame_rate.den && pStream->r_frame_rate.num)
1103         {
1104           st->iFpsRate = pStream->r_frame_rate.num;
1105           st->iFpsScale = pStream->r_frame_rate.den;
1106         }
1107         else
1108         {
1109           st->iFpsRate  = 0;
1110           st->iFpsScale = 0;
1111         }
1112
1113         // added for aml hw decoder, mkv frame-rate can be wrong.
1114         if (pStream->r_frame_rate.den && pStream->r_frame_rate.num)
1115         {
1116           st->irFpsRate = pStream->r_frame_rate.num;
1117           st->irFpsScale = pStream->r_frame_rate.den;
1118         }
1119         else
1120         {
1121           st->irFpsRate = 0;
1122           st->irFpsScale = 0;
1123         }
1124
1125         if (pStream->codec_info_nb_frames >  0
1126         &&  pStream->codec_info_nb_frames <= 2
1127         &&  m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD))
1128         {
1129           CLog::Log(LOGDEBUG, "%s - fps may be unreliable since ffmpeg decoded only %d frame(s)", __FUNCTION__, pStream->codec_info_nb_frames);
1130           st->iFpsRate  = 0;
1131           st->iFpsScale = 0;
1132         }
1133
1134         st->iWidth = pStream->codec->width;
1135         st->iHeight = pStream->codec->height;
1136         st->fAspect = SelectAspect(pStream, &st->bForcedAspect) * pStream->codec->width / pStream->codec->height;
1137         st->iOrientation = 0;
1138         st->iBitsPerPixel = pStream->codec->bits_per_coded_sample;
1139
1140         AVDictionaryEntry *rtag = m_dllAvUtil.av_dict_get(pStream->metadata, "rotate", NULL, 0);
1141         if (rtag) 
1142           st->iOrientation = atoi(rtag->value);
1143         
1144         if ( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) )
1145         {
1146           if (pStream->codec->codec_id == AV_CODEC_ID_PROBE)
1147           {
1148             // fix MPEG-1/MPEG-2 video stream probe returning AV_CODEC_ID_PROBE for still frames.
1149             // ffmpeg issue 1871, regression from ffmpeg r22831.
1150             if ((pStream->id & 0xF0) == 0xE0)
1151             {
1152               pStream->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO;
1153               pStream->codec->codec_tag = MKTAG('M','P','2','V');
1154               CLog::Log(LOGERROR, "%s - AV_CODEC_ID_PROBE detected, forcing AV_CODEC_ID_MPEG2VIDEO", __FUNCTION__);
1155             }
1156           }
1157         }
1158         break;
1159       }
1160     case AVMEDIA_TYPE_DATA:
1161       {
1162         stream = new CDemuxStream();
1163         stream->type = STREAM_DATA;
1164         break;
1165       }
1166     case AVMEDIA_TYPE_SUBTITLE:
1167       {
1168         if (pStream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && CSettings::Get().GetBool("videoplayer.teletextenabled"))
1169         {
1170           CDemuxStreamTeletext* st = new CDemuxStreamTeletext();
1171           stream = st;
1172           stream->type = STREAM_TELETEXT;
1173           break;
1174         }
1175         else
1176         {
1177           CDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream);
1178           stream = st;
1179             
1180           if(m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0))
1181             st->m_description = m_dllAvUtil.av_dict_get(pStream->metadata, "title", NULL, 0)->value;
1182         
1183           break;
1184         }
1185       }
1186     case AVMEDIA_TYPE_ATTACHMENT:
1187       { //mkv attachments. Only bothering with fonts for now.
1188         if(pStream->codec->codec_id == AV_CODEC_ID_TTF
1189 #if (!defined USE_EXTERNAL_FFMPEG)
1190           || pStream->codec->codec_id == AV_CODEC_ID_OTF
1191 #endif
1192           )
1193         {
1194           std::string fileName = "special://temp/fonts/";
1195           XFILE::CDirectory::Create(fileName);
1196           AVDictionaryEntry *nameTag = m_dllAvUtil.av_dict_get(pStream->metadata, "filename", NULL, 0);
1197           if (!nameTag) {
1198             CLog::Log(LOGERROR, "%s: TTF attachment has no name", __FUNCTION__);
1199             break;
1200           }
1201           fileName += nameTag->value;
1202           XFILE::CFile file;
1203           if(pStream->codec->extradata && file.OpenForWrite(fileName))
1204           {
1205             file.Write(pStream->codec->extradata, pStream->codec->extradata_size);
1206             file.Close();
1207           }
1208         }
1209         stream = new CDemuxStream();
1210         stream->type = STREAM_NONE;
1211         break;
1212       }
1213     default:
1214       {
1215         stream = new CDemuxStream();
1216         stream->type = STREAM_NONE;
1217         break;
1218       }
1219     }
1220
1221     // set ffmpeg type
1222     stream->orig_type = pStream->codec->codec_type;
1223
1224     // generic stuff
1225     if (pStream->duration != (int64_t)AV_NOPTS_VALUE)
1226       stream->iDuration = (int)((pStream->duration / AV_TIME_BASE) & 0xFFFFFFFF);
1227
1228     stream->codec = pStream->codec->codec_id;
1229     stream->codec_fourcc = pStream->codec->codec_tag;
1230     stream->profile = pStream->codec->profile;
1231     stream->level   = pStream->codec->level;
1232
1233     stream->source = STREAM_SOURCE_DEMUX;
1234     stream->pPrivate = pStream;
1235     stream->flags = (CDemuxStream::EFlags)pStream->disposition;
1236
1237     AVDictionaryEntry *langTag = m_dllAvUtil.av_dict_get(pStream->metadata, "language", NULL, 0);
1238     if (langTag)
1239       strncpy(stream->language, langTag->value, 3);
1240
1241     if( pStream->codec->extradata && pStream->codec->extradata_size > 0 )
1242     {
1243       stream->ExtraSize = pStream->codec->extradata_size;
1244       stream->ExtraData = new uint8_t[pStream->codec->extradata_size];
1245       memcpy(stream->ExtraData, pStream->codec->extradata, pStream->codec->extradata_size);
1246     }
1247
1248 #ifdef HAVE_LIBBLURAY
1249     if( m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) )
1250       static_cast<CDVDInputStreamBluray*>(m_pInput)->GetStreamInfo(pStream->id, stream->language);
1251 #endif
1252     if( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) )
1253     {
1254       // this stuff is really only valid for dvd's.
1255       // this is so that the physicalid matches the
1256       // id's reported from libdvdnav
1257       switch(stream->codec)
1258       {
1259         case AV_CODEC_ID_AC3:
1260           stream->iPhysicalId = pStream->id - 128;
1261           break;
1262         case AV_CODEC_ID_DTS:
1263           stream->iPhysicalId = pStream->id - 136;
1264           break;
1265         case AV_CODEC_ID_MP2:
1266           stream->iPhysicalId = pStream->id - 448;
1267           break;
1268         case AV_CODEC_ID_PCM_S16BE:
1269           stream->iPhysicalId = pStream->id - 160;
1270           break;
1271         case AV_CODEC_ID_DVD_SUBTITLE:
1272           stream->iPhysicalId = pStream->id - 0x20;
1273           break;
1274         default:
1275           stream->iPhysicalId = pStream->id & 0x1f;
1276           break;
1277       }
1278     }
1279     else
1280       stream->iPhysicalId = pStream->id;
1281
1282     AddStream(iId, stream);
1283     return stream;
1284   }
1285   else
1286     return NULL;
1287 }
1288
1289 /**
1290  * @brief Adds or updates a demux stream based in ffmpeg id
1291  */
1292 void CDVDDemuxFFmpeg::AddStream(int iId, CDemuxStream* stream)
1293 {
1294   std::pair<std::map<int, CDemuxStream*>::iterator, bool> res;
1295
1296   res = m_streams.insert(std::make_pair(iId, stream));
1297   if(res.second)
1298   {
1299     /* was new stream */
1300     stream->iId = m_stream_index.size();
1301     m_stream_index.push_back(res.first);
1302   }
1303   else
1304   {
1305     /* replace old stream, keeping old index */
1306     stream->iId = res.first->second->iId;
1307
1308     delete res.first->second;
1309     res.first->second = stream;
1310   }
1311   if(g_advancedSettings.m_logLevel > LOG_LEVEL_NORMAL)
1312     CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream(%d, ...) -> %d", iId, stream->iId);
1313 }
1314
1315
1316 std::string CDVDDemuxFFmpeg::GetFileName()
1317 {
1318   if(m_pInput)
1319     return m_pInput->GetFileName();
1320   else
1321     return "";
1322 }
1323
1324 int CDVDDemuxFFmpeg::GetChapterCount()
1325 {
1326   CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1327   if(ich)
1328     return ich->GetChapterCount();
1329
1330   if(m_pFormatContext == NULL)
1331     return 0;
1332
1333   return m_pFormatContext->nb_chapters;
1334 }
1335
1336 int CDVDDemuxFFmpeg::GetChapter()
1337 {
1338   CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1339   if(ich)
1340     return ich->GetChapter();
1341
1342   if(m_pFormatContext == NULL
1343   || m_iCurrentPts == DVD_NOPTS_VALUE)
1344     return 0;
1345
1346   for(unsigned i = 0; i < m_pFormatContext->nb_chapters; i++)
1347   {
1348     AVChapter *chapter = m_pFormatContext->chapters[i];
1349     if(m_iCurrentPts >= ConvertTimestamp(chapter->start, chapter->time_base.den, chapter->time_base.num)
1350     && m_iCurrentPts <  ConvertTimestamp(chapter->end,   chapter->time_base.den, chapter->time_base.num))
1351       return i + 1;
1352   }
1353
1354   return 0;
1355 }
1356
1357 void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName)
1358 {
1359   CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1360   if(ich)  
1361     ich->GetChapterName(strChapterName);
1362   else
1363   {
1364     int chapterIdx = GetChapter();
1365     if(chapterIdx <= 0)
1366       return;
1367
1368     AVDictionaryEntry *titleTag = m_dllAvUtil.av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata,
1369                                                           "title", NULL, 0);
1370     if (titleTag)
1371       strChapterName = titleTag->value;
1372   }
1373 }
1374
1375 bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts)
1376 {
1377   if(chapter < 1)
1378     chapter = 1;
1379
1380   CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1381   if(ich)
1382   {
1383     CLog::Log(LOGDEBUG, "%s - chapter seeking using input stream", __FUNCTION__);
1384     if(!ich->SeekChapter(chapter))
1385       return false;
1386
1387     if(startpts)
1388       *startpts = DVD_NOPTS_VALUE;
1389
1390     Flush();
1391     return true;
1392   }
1393
1394   if(m_pFormatContext == NULL)
1395     return false;
1396
1397   if(chapter < 1 || chapter > (int)m_pFormatContext->nb_chapters)
1398     return false;
1399
1400   AVChapter *ch = m_pFormatContext->chapters[chapter-1];
1401   double dts = ConvertTimestamp(ch->start, ch->time_base.den, ch->time_base.num);
1402   return SeekTime(DVD_TIME_TO_MSEC(dts), true, startpts);
1403 }
1404
1405 void CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId, CStdString &strName)
1406 {
1407   CDemuxStream *stream = GetStream(iStreamId);
1408   if (stream)
1409   {
1410     unsigned int in = stream->codec_fourcc;
1411     // FourCC codes are only valid on video streams, audio codecs in AVI/WAV
1412     // are 2 bytes and audio codecs in transport streams have subtle variation
1413     // e.g AC-3 instead of ac3
1414     if (stream->type == STREAM_VIDEO && in != 0)
1415     {
1416       char fourcc[5];
1417 #if defined(__powerpc__)
1418       fourcc[0] = in & 0xff;
1419       fourcc[1] = (in >> 8) & 0xff;
1420       fourcc[2] = (in >> 16) & 0xff;
1421       fourcc[3] = (in >> 24) & 0xff;
1422 #else
1423       memcpy(fourcc, &in, 4);
1424 #endif
1425       fourcc[4] = 0;
1426       // fourccs have to be 4 characters
1427       if (strlen(fourcc) == 4)
1428       {
1429         strName = fourcc;
1430         strName.MakeLower();
1431         return;
1432       }
1433     }
1434
1435 #ifdef FF_PROFILE_DTS_HD_MA
1436     /* use profile to determine the DTS type */
1437     if (stream->codec == AV_CODEC_ID_DTS)
1438     {
1439       if (stream->profile == FF_PROFILE_DTS_HD_MA)
1440         strName = "dtshd_ma";
1441       else if (stream->profile == FF_PROFILE_DTS_HD_HRA)
1442         strName = "dtshd_hra";
1443       else
1444         strName = "dca";
1445       return;
1446     }
1447 #endif
1448
1449     AVCodec *codec = m_dllAvCodec.avcodec_find_decoder(stream->codec);
1450     if (codec)
1451       strName = codec->name;
1452   }
1453 }
1454
1455 bool CDVDDemuxFFmpeg::IsProgramChange()
1456 {
1457   if (m_program == UINT_MAX)
1458     return false;
1459
1460   if(m_pFormatContext->programs[m_program]->nb_stream_indexes != m_streams.size())
1461     return true;
1462
1463   if (m_program >= m_pFormatContext->nb_programs)
1464     return true;
1465
1466   for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
1467   {
1468     int idx = m_pFormatContext->programs[m_program]->stream_index[i];
1469     CDemuxStream *stream = GetStreamInternal(idx);
1470     if(!stream)
1471       return true;
1472     if(m_pFormatContext->streams[idx]->codec->codec_type != stream->orig_type)
1473       return true;
1474   }
1475   return false;
1476 }