2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
22 #ifndef __STDC_CONSTANT_MACROS
23 #define __STDC_CONSTANT_MACROS
25 #ifndef __STDC_LIMIT_MACROS
26 #define __STDC_LIMIT_MACROS
31 #include "DVDDemuxFFmpeg.h"
32 #include "DVDInputStreams/DVDInputStream.h"
33 #include "DVDInputStreams/DVDInputStreamNavigator.h"
35 #include "DVDInputStreams/DVDInputStreamBluray.h"
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"
52 void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo)
56 m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
60 void CDemuxStreamAudioFFmpeg::GetStreamName(std::string& strInfo)
63 if(!m_description.empty())
64 strInfo = m_description;
66 CDemuxStream::GetStreamName(strInfo);
69 void CDemuxStreamSubtitleFFmpeg::GetStreamName(std::string& strInfo)
72 if(!m_description.empty())
73 strInfo = m_description;
75 CDemuxStream::GetStreamName(strInfo);
78 void CDemuxStreamVideoFFmpeg::GetStreamInfo(std::string& strInfo)
82 m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
86 void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo)
90 m_parent->m_dllAvCodec.avcodec_string(temp, 128, m_stream->codec, 0);
94 // these need to be put somewhere that are compiled, we should have some better place for it
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;
101 void ff_avutil_log(void* ptr, int level, const char* format, va_list va)
103 CSingleLock lock(m_logSection);
104 uintptr_t threadId = (uintptr_t)CThread::GetCurrentThreadId();
105 CStdString &buffer = g_logbuffer[threadId];
107 AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
109 if(level >= AV_LOG_DEBUG &&
110 (g_advancedSettings.m_extraLogLevels & LOGFFMPEG) == 0)
112 else if(g_advancedSettings.m_logLevel <= LOG_LEVEL_NORMAL)
118 case AV_LOG_INFO : type = LOGINFO; break;
119 case AV_LOG_ERROR : type = LOGERROR; break;
121 default : type = LOGDEBUG; break;
124 CStdString message, prefix;
125 message.FormatV(format, va);
127 prefix.Format("ffmpeg[%X]: ", threadId);
131 prefix += CStdString("[") + avc->item_name(ptr) + "] ";
132 else if(avc->class_name)
133 prefix += CStdString("[") + avc->class_name + "] ";
138 while( (pos = buffer.find_first_of('\n', start)) >= 0 )
141 CLog::Log(type, "%s%s", prefix.c_str(), buffer.substr(start, pos-start).c_str());
144 buffer.erase(0, start);
147 static void ff_flush_avutil_log_buffers(void)
149 CSingleLock lock(DllAvCodec::m_critSection);
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++);
162 static int interrupt_cb(void* ctx)
164 CDVDDemuxFFmpeg* demuxer = static_cast<CDVDDemuxFFmpeg*>(ctx);
165 if(demuxer && demuxer->Aborted())
170 ////////////////////////////////////////////////////////////////////////////////////////////////
171 ////////////////////////////////////////////////////////////////////////////////////////////////
173 static int dvd_file_open(URLContext *h, const char *filename, int flags)
179 static int dvd_file_read(void *h, uint8_t* buf, int size)
184 CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
185 return pInputStream->Read(buf, size);
188 static int dvd_file_write(URLContext *h, uint8_t* buf, int size)
193 static offset_t dvd_file_seek(void *h, offset_t pos, int whence)
198 CDVDInputStream* pInputStream = static_cast<CDVDDemuxFFmpeg*>(h)->m_pInput;
199 if(whence == AVSEEK_SIZE)
200 return pInputStream->GetLength();
202 return pInputStream->Seek(pos, whence & ~AVSEEK_FORCE);
205 ////////////////////////////////////////////////////////////////////////////////////////////////
206 ////////////////////////////////////////////////////////////////////////////////////////////////
208 CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux()
210 m_pFormatContext = NULL;
213 m_iCurrentPts = DVD_NOPTS_VALUE;
216 m_speed = DVD_PLAYSPEED_NORMAL;
217 m_program = UINT_MAX;
219 memset(&m_pkt.pkt, 0, sizeof(AVPacket));
222 CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg()
225 ff_flush_avutil_log_buffers();
228 bool CDVDDemuxFFmpeg::Aborted()
230 if(m_timeout.IsTimePast())
233 CDVDInputStreamFFmpeg * input = dynamic_cast<CDVDInputStreamFFmpeg*>(m_pInput);
234 if(input && input->Aborted())
240 bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput)
242 AVInputFormat* iformat = NULL;
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 };
249 if (!pInput) return false;
251 if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load()) {
252 CLog::Log(LOGERROR,"CDVDDemuxFFmpeg::Open - failed to load ffmpeg libraries");
257 m_dllAvFormat.av_register_all();
260 strFile = m_pInput->GetFileName();
262 bool streaminfo = true; /* set to true if we want to look for streams before playback*/
264 if( m_pInput->GetContent().length() > 0 )
266 std::string content = m_pInput->GetContent();
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");
280 m_pFormatContext = m_dllAvFormat.avformat_alloc_context();
281 m_pFormatContext->interrupt_callback = int_cb;
283 // try to abort after 30 seconds
284 m_timeout.Set(30000);
286 if( m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG) )
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();
293 AVDictionary *options = GetFFMpegOptionsFromURL(url);
296 if (protocol.Equals("mms"))
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);
304 url.SetProtocol("mmst");
308 if (result < 0 && m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 )
310 CLog::Log(LOGDEBUG, "Error, could not open file %s", strFile.c_str());
312 m_dllAvUtil.av_dict_free(&options);
315 m_dllAvUtil.av_dict_free(&options);
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;
325 if(m_pInput->Seek(0, SEEK_POSSIBLE) == 0)
326 m_ioContext->seekable = 0;
328 if( iformat == NULL )
330 // let ffmpeg decide which demuxer we have to open
332 bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed");
335 m_dllAvFormat.av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0);
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))
345 uint8_t probe_buffer[FFMPEG_FILE_BUFFER_SIZE + AVPROBE_PADDING_SIZE];
348 pd.buf = probe_buffer;
349 pd.filename = strFile.c_str();
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)
355 CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, strFile.c_str());
358 memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE);
360 // restore position again
361 m_dllAvFormat.avio_seek(m_ioContext , 0, SEEK_SET);
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))
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");
377 if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)
383 // not spdif or no spdif demuxer, try dts
384 iformat2 = m_dllAvFormat.av_find_input_format("dts");
386 if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)
390 else if (trySPDIFonly)
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__);
403 std::string content = m_pInput->GetContent();
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");
418 CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, strFile.c_str());
424 CLog::Log(LOGDEBUG, "%s - probing detected format [%s]", __FUNCTION__, iformat->name);
426 CLog::Log(LOGDEBUG, "%s - probing detected unnamed format", __FUNCTION__);
431 m_pFormatContext->pb = m_ioContext;
433 if (m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, NULL) < 0)
435 CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, strFile.c_str());
441 // Avoid detecting framerate if advancedsettings.xml says so
442 if (g_advancedSettings.m_videoFpsDetect == 0)
443 m_pFormatContext->fps_probe_size = 0;
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;
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;
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;
460 CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__);
461 int iErr = m_dllAvFormat.avformat_find_stream_info(m_pFormatContext, NULL);
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))
469 // special case, our codecs can still handle it.
477 CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__);
480 m_timeout.SetInfinite();
482 // if format can be nonblocking, let's use that
483 m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;
485 // print some extra information
486 m_dllAvFormat.av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0);
495 void CDVDDemuxFFmpeg::Dispose()
498 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
500 if (m_pFormatContext)
502 if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext)
504 CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak");
505 m_ioContext = m_pFormatContext->pb;
507 m_dllAvFormat.avformat_close_input(&m_pFormatContext);
512 m_dllAvUtil.av_free(m_ioContext->buffer);
513 m_dllAvUtil.av_free(m_ioContext);
517 m_pFormatContext = NULL;
518 m_speed = DVD_PLAYSPEED_NORMAL;
524 m_dllAvFormat.Unload();
525 m_dllAvCodec.Unload();
526 m_dllAvUtil.Unload();
529 void CDVDDemuxFFmpeg::Reset()
531 CDVDInputStream* pInputStream = m_pInput;
536 void CDVDDemuxFFmpeg::Flush()
538 // naughty usage of an internal ffmpeg function
539 if (m_pFormatContext)
540 m_dllAvFormat.av_read_frame_flush(m_pFormatContext);
542 m_iCurrentPts = DVD_NOPTS_VALUE;
545 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
548 void CDVDDemuxFFmpeg::Abort()
550 m_timeout.SetExpired();
553 void CDVDDemuxFFmpeg::SetSpeed(int iSpeed)
555 if(!m_pFormatContext)
558 if(m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE)
560 m_pInput->Pause((double)m_iCurrentPts);
561 m_dllAvFormat.av_read_pause(m_pFormatContext);
563 else if(m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE)
565 m_pInput->Pause((double)m_iCurrentPts);
566 m_dllAvFormat.av_read_play(m_pFormatContext);
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;
579 for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
581 if(m_pFormatContext->streams[i])
583 if(m_pFormatContext->streams[i]->discard != AVDISCARD_ALL)
584 m_pFormatContext->streams[i]->discard = discard;
589 AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url)
591 CStdString protocol = url.GetProtocol();
593 AVDictionary *options = NULL;
595 if (protocol.Equals("http") || protocol.Equals("https"))
597 std::map<CStdString, CStdString> protocolOptions;
598 url.GetProtocolOptions(protocolOptions);
600 bool hasUserAgent = false;
601 for(std::map<CStdString, CStdString>::const_iterator it = protocolOptions.begin(); it != protocolOptions.end(); ++it)
603 const CStdString &name = it->first;
604 const CStdString &value = it->second;
606 if (name.Equals("seekable"))
607 m_dllAvUtil.av_dict_set(&options, "seekable", value.c_str(), 0);
608 else if (name.Equals("User-Agent"))
610 m_dllAvUtil.av_dict_set(&options, "user-agent", value.c_str(), 0);
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");
618 // set default xbmc user-agent.
619 m_dllAvUtil.av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0);
621 if (!headers.empty())
622 m_dllAvUtil.av_dict_set(&options, "headers", headers.c_str(), 0);
627 double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num)
629 if (pts == (int64_t)AV_NOPTS_VALUE)
630 return DVD_NOPTS_VALUE;
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;
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;
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 )
649 return timestamp*DVD_TIME_BASE;
652 DemuxPacket* CDVDDemuxFFmpeg::Read()
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)
661 // assume we are not eof
662 if(m_pFormatContext->pb)
663 m_pFormatContext->pb->eof_reached = 0;
665 // check for saved packet after a program change
666 if (m_pkt.result < 0)
668 // keep track if ffmpeg doesn't always set these
670 m_pkt.pkt.data = NULL;
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();
678 if (m_pkt.result == AVERROR(EINTR) || m_pkt.result == AVERROR(EAGAIN))
680 // timeout, probably no real error, return empty packet
683 else if (m_pkt.result < 0)
687 else if (IsProgramChange())
690 CreateStreams(m_program);
692 pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
693 pPacket->iStreamId = DMX_SPECIALID_STREAMCHANGE;
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)
702 // XXX, in some cases ffmpeg returns a negative packet size
703 if(m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached)
705 CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() no valid packet");
710 CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached");
713 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
717 AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index];
719 if (m_program != UINT_MAX)
721 /* check so packet belongs to selected program */
722 for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
724 if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i])
726 pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
735 pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size);
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;
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;
757 m_pkt.pkt.pts = AV_NOPTS_VALUE;
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;
764 if(m_bAVI && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
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;
771 // copy contents into our own packet
772 pPacket->iSize = m_pkt.pkt.size;
774 // maybe we can avoid a memcpy here by detecting where pkt.destruct is pointing too?
776 memcpy(pPacket->pData, m_pkt.pkt.data, pPacket->iSize);
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);
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;
787 // check if stream has passed full duration, needed for live streams
788 if(m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE)
791 duration = m_pkt.pkt.dts;
792 if(stream->start_time != (int64_t)AV_NOPTS_VALUE)
793 duration -= stream->start_time;
795 if(duration > stream->duration)
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;
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;
810 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
813 } // end of lock scope
814 if (bReturnEmpty && !pPacket)
815 pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0);
817 if (!pPacket) return NULL;
819 // check streams, can we make this a bit more simple?
820 if (pPacket && pPacket->iStreamId >= 0)
822 CDemuxStream *stream = GetStreamInternal(pPacket->iStreamId);
824 stream->pPrivate != m_pFormatContext->streams[pPacket->iStreamId] ||
825 stream->codec != m_pFormatContext->streams[pPacket->iStreamId]->codec->codec_id)
827 // content has changed, or stream did not yet exist
828 stream = AddStream(pPacket->iStreamId);
830 // we already check for a valid m_streams[pPacket->iStreamId] above
831 else if (stream->type == STREAM_AUDIO)
833 if (((CDemuxStreamAudio*)stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codec->channels ||
834 ((CDemuxStreamAudio*)stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codec->sample_rate)
836 // content has changed
837 stream = AddStream(pPacket->iStreamId);
840 else if (stream->type == STREAM_VIDEO)
842 if (((CDemuxStreamVideo*)stream)->iWidth != m_pFormatContext->streams[pPacket->iStreamId]->codec->width ||
843 ((CDemuxStreamVideo*)stream)->iHeight != m_pFormatContext->streams[pPacket->iStreamId]->codec->height)
845 // content has changed
846 stream = AddStream(pPacket->iStreamId);
851 CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::AddStream - internal error, stream is null");
852 CDVDDemuxUtils::FreeDemuxPacket(pPacket);
855 // set continuous stream id for player
856 pPacket->iStreamId = stream->iId;
861 bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts)
867 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
869 CDVDInputStream::ISeekTime* ist = dynamic_cast<CDVDInputStream::ISeekTime*>(m_pInput);
872 if (!ist->SeekTime(time))
876 *startpts = DVD_NOPTS_VALUE;
880 // also empty the internal ffmpeg buffer
881 m_ioContext->buf_ptr = m_ioContext->buf_end;
886 if(!m_pInput->Seek(0, SEEK_POSSIBLE)
887 && !m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG))
889 CLog::Log(LOGDEBUG, "%s - input stream reports it is not seekable", __FUNCTION__);
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;
899 CSingleLock lock(m_critSection);
900 ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0);
906 if(m_iCurrentPts == DVD_NOPTS_VALUE)
907 CLog::Log(LOGDEBUG, "%s - unknown position after seek", __FUNCTION__);
909 CLog::Log(LOGDEBUG, "%s - seek ended up on time %d", __FUNCTION__, (int)(m_iCurrentPts / DVD_TIME_BASE * 1000));
911 // in this case the start time is requested time
913 *startpts = DVD_MSEC_TO_TIME(time);
915 // demuxer will return failure, if you seek to eof
916 if (m_pInput->IsEOF() && ret <= 0)
922 bool CDVDDemuxFFmpeg::SeekByte(int64_t pos)
924 CSingleLock lock(m_critSection);
925 int ret = m_dllAvFormat.av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE);
931 m_dllAvCodec.av_free_packet(&m_pkt.pkt);
936 void CDVDDemuxFFmpeg::UpdateCurrentPTS()
938 m_iCurrentPts = DVD_NOPTS_VALUE;
939 for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
941 AVStream *stream = m_pFormatContext->streams[i];
942 if(stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE)
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 )
951 int CDVDDemuxFFmpeg::GetStreamLength()
953 if (!m_pFormatContext)
956 if (m_pFormatContext->duration < 0)
959 return (int)(m_pFormatContext->duration / (AV_TIME_BASE / 1000));
963 * @brief Finds stream based on demuxer index
965 CDemuxStream* CDVDDemuxFFmpeg::GetStream(int iStreamId)
967 if(iStreamId >= 0 && (size_t)iStreamId < m_stream_index.size())
968 return m_stream_index[iStreamId]->second;
974 * @brief Finds stream based on ffmpeg index
976 CDemuxStream* CDVDDemuxFFmpeg::GetStreamInternal(int iId)
978 std::map<int, CDemuxStream*>::iterator it = m_streams.find(iId);
979 if (it == m_streams.end())
985 int CDVDDemuxFFmpeg::GetNrOfStreams()
987 return m_stream_index.size();
990 static double SelectAspect(AVStream* st, bool* forced)
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);
1000 if(st->sample_aspect_ratio.num != 0)
1001 return av_q2d(st->sample_aspect_ratio);
1006 void CDVDDemuxFFmpeg::CreateStreams(unsigned int program)
1010 // add the ffmpeg streams to our own stream map
1011 if (m_pFormatContext->nb_programs)
1013 // check if desired program is available
1014 if (program < m_pFormatContext->nb_programs && m_pFormatContext->programs[program]->nb_stream_indexes > 0)
1016 m_program = program;
1019 m_program = UINT_MAX;
1021 // look for first non empty stream and discard nonselected programs
1022 for (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++)
1024 if(m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0)
1030 m_pFormatContext->programs[i]->discard = AVDISCARD_ALL;
1032 if(m_program != UINT_MAX)
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]);
1040 m_program = UINT_MAX;
1042 // if there were no programs or they were all empty, add all streams
1043 if (m_program == UINT_MAX)
1045 for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++)
1050 void CDVDDemuxFFmpeg::DisposeStreams()
1052 std::map<int, CDemuxStream*>::iterator it;
1053 for(it = m_streams.begin(); it != m_streams.end(); ++it)
1056 m_stream_index.clear();
1059 CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId)
1061 AVStream* pStream = m_pFormatContext->streams[iId];
1064 CDemuxStream* stream = NULL;
1066 switch (pStream->codec->codec_type)
1068 case AVMEDIA_TYPE_AUDIO:
1070 CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(this, pStream);
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;
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;
1083 case AVMEDIA_TYPE_VIDEO:
1085 CDemuxStreamVideoFFmpeg* st = new CDemuxStreamVideoFFmpeg(this, pStream);
1087 if(strcmp(m_pFormatContext->iformat->name, "flv") == 0)
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;
1096 //average fps is more accurate for mkv files
1097 if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num)
1099 st->iFpsRate = pStream->avg_frame_rate.num;
1100 st->iFpsScale = pStream->avg_frame_rate.den;
1102 else if(pStream->r_frame_rate.den && pStream->r_frame_rate.num)
1104 st->iFpsRate = pStream->r_frame_rate.num;
1105 st->iFpsScale = pStream->r_frame_rate.den;
1113 // added for aml hw decoder, mkv frame-rate can be wrong.
1114 if (pStream->r_frame_rate.den && pStream->r_frame_rate.num)
1116 st->irFpsRate = pStream->r_frame_rate.num;
1117 st->irFpsScale = pStream->r_frame_rate.den;
1125 if (pStream->codec_info_nb_frames > 0
1126 && pStream->codec_info_nb_frames <= 2
1127 && m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD))
1129 CLog::Log(LOGDEBUG, "%s - fps may be unreliable since ffmpeg decoded only %d frame(s)", __FUNCTION__, pStream->codec_info_nb_frames);
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;
1140 AVDictionaryEntry *rtag = m_dllAvUtil.av_dict_get(pStream->metadata, "rotate", NULL, 0);
1142 st->iOrientation = atoi(rtag->value);
1144 if ( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) )
1146 if (pStream->codec->codec_id == AV_CODEC_ID_PROBE)
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)
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__);
1160 case AVMEDIA_TYPE_DATA:
1162 stream = new CDemuxStream();
1163 stream->type = STREAM_DATA;
1166 case AVMEDIA_TYPE_SUBTITLE:
1168 if (pStream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && CSettings::Get().GetBool("videoplayer.teletextenabled"))
1170 CDemuxStreamTeletext* st = new CDemuxStreamTeletext();
1172 stream->type = STREAM_TELETEXT;
1177 CDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream);
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;
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
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);
1198 CLog::Log(LOGERROR, "%s: TTF attachment has no name", __FUNCTION__);
1201 fileName += nameTag->value;
1203 if(pStream->codec->extradata && file.OpenForWrite(fileName))
1205 file.Write(pStream->codec->extradata, pStream->codec->extradata_size);
1209 stream = new CDemuxStream();
1210 stream->type = STREAM_NONE;
1215 stream = new CDemuxStream();
1216 stream->type = STREAM_NONE;
1222 stream->orig_type = pStream->codec->codec_type;
1225 if (pStream->duration != (int64_t)AV_NOPTS_VALUE)
1226 stream->iDuration = (int)((pStream->duration / AV_TIME_BASE) & 0xFFFFFFFF);
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;
1233 stream->source = STREAM_SOURCE_DEMUX;
1234 stream->pPrivate = pStream;
1235 stream->flags = (CDemuxStream::EFlags)pStream->disposition;
1237 AVDictionaryEntry *langTag = m_dllAvUtil.av_dict_get(pStream->metadata, "language", NULL, 0);
1239 strncpy(stream->language, langTag->value, 3);
1241 if( pStream->codec->extradata && pStream->codec->extradata_size > 0 )
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);
1248 #ifdef HAVE_LIBBLURAY
1249 if( m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) )
1250 static_cast<CDVDInputStreamBluray*>(m_pInput)->GetStreamInfo(pStream->id, stream->language);
1252 if( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) )
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)
1259 case AV_CODEC_ID_AC3:
1260 stream->iPhysicalId = pStream->id - 128;
1262 case AV_CODEC_ID_DTS:
1263 stream->iPhysicalId = pStream->id - 136;
1265 case AV_CODEC_ID_MP2:
1266 stream->iPhysicalId = pStream->id - 448;
1268 case AV_CODEC_ID_PCM_S16BE:
1269 stream->iPhysicalId = pStream->id - 160;
1271 case AV_CODEC_ID_DVD_SUBTITLE:
1272 stream->iPhysicalId = pStream->id - 0x20;
1275 stream->iPhysicalId = pStream->id & 0x1f;
1280 stream->iPhysicalId = pStream->id;
1282 AddStream(iId, stream);
1290 * @brief Adds or updates a demux stream based in ffmpeg id
1292 void CDVDDemuxFFmpeg::AddStream(int iId, CDemuxStream* stream)
1294 std::pair<std::map<int, CDemuxStream*>::iterator, bool> res;
1296 res = m_streams.insert(std::make_pair(iId, stream));
1299 /* was new stream */
1300 stream->iId = m_stream_index.size();
1301 m_stream_index.push_back(res.first);
1305 /* replace old stream, keeping old index */
1306 stream->iId = res.first->second->iId;
1308 delete res.first->second;
1309 res.first->second = stream;
1311 if(g_advancedSettings.m_logLevel > LOG_LEVEL_NORMAL)
1312 CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream(%d, ...) -> %d", iId, stream->iId);
1316 std::string CDVDDemuxFFmpeg::GetFileName()
1319 return m_pInput->GetFileName();
1324 int CDVDDemuxFFmpeg::GetChapterCount()
1326 CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1328 return ich->GetChapterCount();
1330 if(m_pFormatContext == NULL)
1333 return m_pFormatContext->nb_chapters;
1336 int CDVDDemuxFFmpeg::GetChapter()
1338 CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1340 return ich->GetChapter();
1342 if(m_pFormatContext == NULL
1343 || m_iCurrentPts == DVD_NOPTS_VALUE)
1346 for(unsigned i = 0; i < m_pFormatContext->nb_chapters; i++)
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))
1357 void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName)
1359 CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1361 ich->GetChapterName(strChapterName);
1364 int chapterIdx = GetChapter();
1368 AVDictionaryEntry *titleTag = m_dllAvUtil.av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata,
1371 strChapterName = titleTag->value;
1375 bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts)
1380 CDVDInputStream::IChapter* ich = dynamic_cast<CDVDInputStream::IChapter*>(m_pInput);
1383 CLog::Log(LOGDEBUG, "%s - chapter seeking using input stream", __FUNCTION__);
1384 if(!ich->SeekChapter(chapter))
1388 *startpts = DVD_NOPTS_VALUE;
1394 if(m_pFormatContext == NULL)
1397 if(chapter < 1 || chapter > (int)m_pFormatContext->nb_chapters)
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);
1405 void CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId, CStdString &strName)
1407 CDemuxStream *stream = GetStream(iStreamId);
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)
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;
1423 memcpy(fourcc, &in, 4);
1426 // fourccs have to be 4 characters
1427 if (strlen(fourcc) == 4)
1430 strName.MakeLower();
1435 #ifdef FF_PROFILE_DTS_HD_MA
1436 /* use profile to determine the DTS type */
1437 if (stream->codec == AV_CODEC_ID_DTS)
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";
1449 AVCodec *codec = m_dllAvCodec.avcodec_find_decoder(stream->codec);
1451 strName = codec->name;
1455 bool CDVDDemuxFFmpeg::IsProgramChange()
1457 if (m_program == UINT_MAX)
1460 if(m_pFormatContext->programs[m_program]->nb_stream_indexes != m_streams.size())
1463 if (m_program >= m_pFormatContext->nb_programs)
1466 for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++)
1468 int idx = m_pFormatContext->programs[m_program]->stream_index[i];
1469 CDemuxStream *stream = GetStreamInternal(idx);
1472 if(m_pFormatContext->streams[idx]->codec->codec_type != stream->orig_type)