Skip to content
This repository was archived by the owner on Dec 24, 2024. It is now read-only.

Commit 2300fae

Browse files
committed
BACKPORT: Adaptive Smoothstreaming
1 parent 56617c8 commit 2300fae

30 files changed

Lines changed: 1488 additions & 637 deletions

XBMC.files

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9845,25 +9845,6 @@ xbmc/interfaces/builtins/WeatherBuiltins.h
98459845
tools/android/packaging/xbmc/src/org/xbmc/kodi/XBMCProperties.java.in
98469846
xbmc/android/jni/AudioDeviceInfo.cpp
98479847
xbmc/android/jni/AudioDeviceInfo.h
9848-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHByteStream.cpp
9849-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHByteStream.h
9850-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHCodecHandler.cpp
9851-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHCodecHandler.h
9852-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHFragmentedSampleReader.cpp
9853-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHFragmentedSampleReader.h
9854-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHFragmentObserver.h
9855-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHSession.cpp
9856-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHSession.h
9857-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHStream.cpp
9858-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHStream.h
9859-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHTree.cpp
9860-
xbmc/cores/dvdplayer/DVDDemuxers/dash/DASHTree.h
9861-
xbmc/cores/dvdplayer/DVDDemuxers/dash/helpers.cpp
9862-
xbmc/cores/dvdplayer/DVDDemuxers/dash/helpers.h
9863-
xbmc/cores/dvdplayer/DVDDemuxers/dash/oscompat.cpp
9864-
xbmc/cores/dvdplayer/DVDDemuxers/dash/oscompat.h
9865-
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxMPD.cpp
9866-
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxMPD.h
98679848
xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNULL.h
98689849
xbmc/cores/dvdplayer/Makefile.in
98699850
xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in
@@ -9974,3 +9955,28 @@ xbmc/android/jni/PlaybackState.h
99749955
xbmc/android/jni/PlaybackState.cpp
99759956
xbmc/android/jni/BitmapFactory.h
99769957
xbmc/android/jni/BitmapFactory.cpp
9958+
xbmc/cores/dvdplayer/DVDDemuxers/dash/SmoothTree.cpp
9959+
xbmc/cores/dvdplayer/DVDDemuxers/dash/SmoothTree.h
9960+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/common/AdaptiveTree.cpp
9961+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/common/AdaptiveTree.h
9962+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/parsers/DASHTree.cpp
9963+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/parsers/DASHTree.h
9964+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/parsers/SmoothTree.cpp
9965+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/parsers/SmoothTree.h
9966+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHByteStream.cpp
9967+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHByteStream.h
9968+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHCodecHandler.cpp
9969+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHCodecHandler.h
9970+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHFragmentedSampleReader.cpp
9971+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHFragmentedSampleReader.h
9972+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHFragmentObserver.h
9973+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHSession.cpp
9974+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHSession.h
9975+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHStream.cpp
9976+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/DASHStream.h
9977+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/helpers.cpp
9978+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/helpers.h
9979+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/oscompat.cpp
9980+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/oscompat.h
9981+
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxAdaptive.cpp
9982+
xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxAdaptive.h

XBMC.includes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2866,7 +2866,6 @@ xbmc/video/jobs
28662866
xbmc/video/videosync
28672867
tools/android/packaging/xbmc/src/org/xbmc/kodi
28682868
system/shaders
2869-
xbmc/cores/dvdplayer/DVDInputStreams/dash
28702869
tools/android/packaging/xbmc/res/layout
28712870
tools/android/packaging/xbmc/res/values
28722871
.
@@ -2882,3 +2881,6 @@ lib/libUPnP
28822881
xbmc/network/android
28832882
xbmc/listproviders
28842883
tools/android/packaging/xbmc/src/org/xbmc/kodi/interfaces
2884+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/common
2885+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive/parsers
2886+
xbmc/cores/dvdplayer/DVDDemuxers/adaptive

tools/depends/target/bento4/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ DEPS= ../../Makefile.include Makefile
33

44
# lib name, version
55
LIBNAME=Bento4
6-
VERSION=HEAD
6+
VERSION=inputstream
77
SOURCE=archive
88
ARCHIVE=$(VERSION).tar.gz
99
GIT_BASE_URL=https://github.com/koying
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
/*
2+
* Copyright (C) 2016 Christian Browet
3+
* Copyright (C) 2016-2016 peak3d
4+
* http://xbmc.org
5+
*
6+
* This Program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2, or (at your option)
9+
* any later version.
10+
*
11+
* This Program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with XBMC; see the file COPYING. If not, see
18+
* <http://www.gnu.org/licenses/>.
19+
*
20+
*/
21+
22+
#include "DVDDemuxAdaptive.h"
23+
24+
#include "DVDDemuxPacket.h"
25+
#include "DVDDemuxUtils.h"
26+
#include "DVDInputStreams/DVDInputStream.h"
27+
28+
#include "adaptive/DASHByteStream.h"
29+
30+
#ifdef TARGET_ANDROID
31+
#include "android/jni/SystemProperties.h"
32+
#endif
33+
#ifdef TARGET_WINDOWS
34+
#pragma comment(lib, "libexpat.lib")
35+
#pragma comment(lib, "ap4.lib")
36+
#endif
37+
38+
#include "utils/StringUtils.h"
39+
#include "utils/log.h"
40+
41+
CDVDDemuxAdaptive::CDVDDemuxAdaptive()
42+
: CDVDDemux()
43+
{
44+
CLog::Log(LOGDEBUG, "CDVDDemuxAdaptive::%s", __FUNCTION__);
45+
}
46+
47+
CDVDDemuxAdaptive::~CDVDDemuxAdaptive()
48+
{
49+
CLog::Log(LOGDEBUG, "CDVDDemuxAdaptive::%s", __FUNCTION__);
50+
}
51+
52+
bool CDVDDemuxAdaptive::Open(CDVDInputStream* pInput, uint32_t maxWidth, uint32_t maxHeight)
53+
{
54+
CLog::Log(LOGINFO, "CDVDDemuxAdaptive - matching against %d x %d", maxWidth, maxHeight);
55+
56+
CDASHSession::MANIFEST_TYPE type = CDASHSession::MANIFEST_TYPE_UNKNOWN;
57+
58+
if (pInput->GetFileItem().GetMimeType() == "video/vnd.mpeg.dash.mpd" || pInput->GetFileItem().IsType(".mpd")) //MPD
59+
type = CDASHSession::MANIFEST_TYPE_MPD;
60+
else if (pInput->GetFileItem().GetMimeType() == "application/vnd.ms-sstr+xml" || pInput->GetFileItem().IsType(".ismc") || pInput->GetFileItem().IsType(".ism")) //ISM
61+
type = CDASHSession::MANIFEST_TYPE_ISM;
62+
63+
if (type == CDASHSession::MANIFEST_TYPE_UNKNOWN)
64+
return false;
65+
66+
m_session.reset(new CDASHSession(type, pInput->GetFileName(), maxWidth, maxHeight, "", "", "special://profile/"));
67+
68+
if (!m_session->initialize())
69+
{
70+
m_session = nullptr;
71+
return false;
72+
}
73+
return true;
74+
}
75+
76+
void CDVDDemuxAdaptive::Dispose()
77+
{
78+
}
79+
80+
void CDVDDemuxAdaptive::Reset()
81+
{
82+
}
83+
84+
void CDVDDemuxAdaptive::Abort()
85+
{
86+
}
87+
88+
void CDVDDemuxAdaptive::Flush()
89+
{
90+
}
91+
92+
DemuxPacket*CDVDDemuxAdaptive::Read()
93+
{
94+
if (!m_session)
95+
return NULL;
96+
97+
CDASHFragmentedSampleReader *sr(m_session->GetNextSample());
98+
99+
if (m_session->CheckChange())
100+
{
101+
DemuxPacket *p = CDVDDemuxUtils::AllocateDemuxPacket(0);
102+
p->iStreamId = DMX_SPECIALID_STREAMCHANGE;
103+
CLog::Log(LOGDEBUG, "DMX_SPECIALID_STREAMCHANGE");
104+
return p;
105+
}
106+
107+
if (sr)
108+
{
109+
DemuxPacket *p = CDVDDemuxUtils::AllocateDemuxPacket(sr->GetSampleDataSize());
110+
p->dts = sr->DTS() * 1000000;
111+
p->pts = sr->PTS() * 1000000;
112+
p->duration = sr->GetDuration() * 1000000;
113+
p->iStreamId = sr->GetStreamId();
114+
p->iGroupId = 0;
115+
p->iSize = sr->GetSampleDataSize();
116+
memcpy(p->pData, sr->GetSampleData(), p->iSize);
117+
118+
CLog::Log(LOGDEBUG, "DTS: %0.4f, PTS:%0.4f, ID: %u SZ: %d", p->dts, p->pts, p->iStreamId, p->iSize);
119+
120+
sr->ReadSample();
121+
return p;
122+
}
123+
return NULL;
124+
}
125+
126+
bool CDVDDemuxAdaptive::SeekTime(int time, bool backwards, double* startpts)
127+
{
128+
if (!m_session)
129+
return false;
130+
131+
return m_session->SeekTime(static_cast<double>(time)*0.001f, 0, !backwards);
132+
}
133+
134+
void CDVDDemuxAdaptive::SetSpeed(int speed)
135+
{
136+
}
137+
138+
int CDVDDemuxAdaptive::GetNrOfStreams()
139+
{
140+
int n = 0;
141+
if (m_session)
142+
n = m_session->GetStreamCount();
143+
144+
return n;
145+
}
146+
147+
CDemuxStream* CDVDDemuxAdaptive::GetStream(int streamid)
148+
{
149+
CDASHSession::STREAM *stream(m_session->GetStream(streamid));
150+
if (!stream)
151+
{
152+
CLog::Log(LOGERROR, "CDVDDemuxAdaptive::GetStream(%d): error getting stream", streamid);
153+
return nullptr;
154+
}
155+
156+
return stream->dmuxstrm;
157+
}
158+
159+
void CDVDDemuxAdaptive::EnableStream(int streamid, bool enable)
160+
{
161+
CLog::Log(LOGDEBUG, "EnableStream(%d: %s)", streamid, enable?"true":"false");
162+
163+
if (!m_session)
164+
return;
165+
166+
CDASHSession::STREAM *stream(m_session->GetStream(streamid));
167+
if (!stream)
168+
return;
169+
170+
if (enable)
171+
{
172+
if (stream->enabled)
173+
return;
174+
175+
stream->enabled = true;
176+
177+
stream->stream_.start_stream(~0, m_session->GetWidth(), m_session->GetHeight());
178+
const adaptive::AdaptiveTree::Representation *rep(stream->stream_.getRepresentation());
179+
CLog::Log(LOGDEBUG, "Selecting stream with conditions: w: %u, h: %u, bw: %u",
180+
stream->stream_.getWidth(), stream->stream_.getHeight(), stream->stream_.getBandwidth());
181+
182+
if (!stream->stream_.select_stream(true, false, stream->dmuxstrm->iPhysicalId >> 16))
183+
{
184+
CLog::Log(LOGERROR, "Unable to select stream!");
185+
return stream->disable();
186+
}
187+
188+
if(rep != stream->stream_.getRepresentation())
189+
{
190+
m_session->UpdateStream(*stream);
191+
m_session->CheckChange(true);
192+
}
193+
194+
stream->input_ = new CDASHByteStream(&stream->stream_);
195+
static const AP4_Track::Type TIDC[adaptive::AdaptiveTree::STREAM_TYPE_COUNT] = {
196+
AP4_Track::TYPE_UNKNOWN,
197+
AP4_Track::TYPE_VIDEO,
198+
AP4_Track::TYPE_AUDIO,
199+
AP4_Track::TYPE_TEXT };
200+
201+
AP4_Movie* movie = nullptr;
202+
if (m_session->GetManifestType() == CDASHSession::MANIFEST_TYPE_ISM && stream->stream_.getRepresentation()->get_initialization() == nullptr)
203+
{
204+
//We'll create a Movie out of the things we got from manifest file
205+
//note: movie will be deleted in destructor of stream->input_file_
206+
movie = new AP4_Movie();
207+
208+
AP4_SyntheticSampleTable* sample_table = new AP4_SyntheticSampleTable();
209+
AP4_SampleDescription *sample_descryption = new AP4_SampleDescription(AP4_SampleDescription::TYPE_UNKNOWN, 0, 0);
210+
if (stream->stream_.getAdaptationSet()->encrypted)
211+
{
212+
static const AP4_UI08 default_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
213+
AP4_ContainerAtom schi(AP4_ATOM_TYPE_SCHI);
214+
schi.AddChild(new AP4_TencAtom(AP4_CENC_ALGORITHM_ID_CTR, 8, default_key));
215+
sample_descryption = new AP4_ProtectedSampleDescription(0, sample_descryption, 0, AP4_PROTECTION_SCHEME_TYPE_PIFF, 0, "", &schi);
216+
}
217+
sample_table->AddSampleDescription(sample_descryption);
218+
219+
movie->AddTrack(new AP4_Track(TIDC[stream->stream_.get_type()], sample_table, ~0, stream->stream_.getRepresentation()->timescale_, 0, stream->stream_.getRepresentation()->timescale_, 0, "", 0, 0));
220+
//Create a dumy MOOV Atom to tell Bento4 its a fragmented stream
221+
AP4_MoovAtom *moov = new AP4_MoovAtom();
222+
moov->AddChild(new AP4_ContainerAtom(AP4_ATOM_TYPE_MVEX));
223+
movie->SetMoovAtom(moov);
224+
}
225+
226+
stream->input_file_ = new AP4_File(*stream->input_, AP4_DefaultAtomFactory::Instance_, true, movie);
227+
movie = stream->input_file_->GetMovie();
228+
if (movie == NULL)
229+
{
230+
CLog::Log(LOGERROR, "No MOOV in stream!");
231+
return stream->disable();
232+
}
233+
234+
AP4_Track *track = movie->GetTrack(TIDC[stream->stream_.get_type()]);
235+
if (!track)
236+
{
237+
CLog::Log(LOGERROR, "No suitable track found in stream");
238+
return stream->disable();
239+
}
240+
241+
stream->reader_ = new CDASHFragmentedSampleReader(stream->input_, movie, track, streamid, m_session->GetSingleSampleDecryptor(), m_session->GetPresentationTimeOffset());
242+
stream->reader_->SetObserver(dynamic_cast<IDASHFragmentObserver*>(m_session.get()));
243+
244+
if (!stream->dmuxstrm->ExtraSize && stream->reader_->GetExtraDataSize())
245+
{
246+
// ExtraData is now available......
247+
stream->dmuxstrm->ExtraSize = stream->reader_->GetExtraDataSize();
248+
stream->dmuxstrm->ExtraData = (uint8_t*)malloc(stream->dmuxstrm->ExtraSize);
249+
memcpy((void*)stream->dmuxstrm->ExtraData, stream->reader_->GetExtraData(), stream->dmuxstrm->ExtraSize);
250+
// Set the session Changed to force new GetStreamInfo call from kodi -> addon
251+
m_session->CheckChange(true);
252+
}
253+
return;
254+
}
255+
CLog::Log(LOGDEBUG, ">>>> ERROR");
256+
return stream->disable();
257+
}
258+
259+
int CDVDDemuxAdaptive::GetStreamLength()
260+
{
261+
if (!m_session)
262+
return 0;
263+
264+
return static_cast<int>(m_session->GetTotalTime()*1000);
265+
}
266+
267+
std::string CDVDDemuxAdaptive::GetFileName()
268+
{
269+
if (!m_session)
270+
return "";
271+
272+
return m_session->GetUrl();
273+
}
274+
275+
void CDVDDemuxAdaptive::GetStreamCodecName(int iStreamId, std::string& strName)
276+
{
277+
strName = "";
278+
279+
CDASHSession::STREAM *stream(m_session->GetStream(iStreamId));
280+
if (stream)
281+
strName = stream->codecName;
282+
}

xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxMPD.h renamed to xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxAdaptive.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525

2626
#include <memory>
2727

28-
#include "dash/DASHSession.h"
28+
#include "adaptive/DASHSession.h"
2929

30-
class CDVDDemuxMPD : public CDVDDemux
30+
class CDVDDemuxAdaptive : public CDVDDemux
3131
{
3232
public:
33-
CDVDDemuxMPD();
34-
virtual ~CDVDDemuxMPD();
33+
CDVDDemuxAdaptive();
34+
virtual ~CDVDDemuxAdaptive();
3535

3636
bool Open(CDVDInputStream* pInput, uint32_t maxWidth, uint32_t maxHeight);
3737
void Dispose();
@@ -50,5 +50,5 @@ class CDVDDemuxMPD : public CDVDDemux
5050
virtual void GetStreamCodecName(int iStreamId, std::string &strName);
5151

5252
protected:
53-
std::shared_ptr<CDASHSession> m_MPDsession;
53+
std::shared_ptr<CDASHSession> m_session;
5454
};

0 commit comments

Comments
 (0)