forked from rdkcmf/rdk-aamp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
admanager_mpd.h
424 lines (370 loc) · 13.6 KB
/
admanager_mpd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*
* If not stated otherwise in this file or this component's license file the
* following copyright and licenses apply:
*
* Copyright 2018 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file admanager_mpd.h
* @brief Client side DAI manger for MPEG DASH
*/
#ifndef ADMANAGER_MPD_H_
#define ADMANAGER_MPD_H_
#include "AdManagerBase.h"
#include <string>
#include "libdash/INode.h"
#include "libdash/IDASHManager.h"
#include "libdash/xml/Node.h"
#include "libdash/IMPD.h"
using namespace dash;
using namespace std;
using namespace dash::mpd;
/**
* @class CDAIObjectMPD
*
* @brief Client Side DAI object implementation for DASH
*/
class CDAIObjectMPD: public CDAIObject
{
class PrivateCDAIObjectMPD* mPrivObj; /**< Private instance of Client Side DAI object for DASH */
public:
/**
* @brief CDAIObjectMPD Constructor
*
* @param[in] aamp - Pointer to PrivateInstanceAAMP
*/
CDAIObjectMPD(PrivateInstanceAAMP* aamp);
/**
* @brief CDAIObjectMPD destructor.
*/
virtual ~CDAIObjectMPD();
/**
* @brief CDAIObject Copy Constructor
*/
CDAIObjectMPD(const CDAIObjectMPD&) = delete;
/**
* @brief CDAIObject assignment operator overloading
*/
CDAIObjectMPD& operator= (const CDAIObjectMPD&) = delete;
/**
* @brief Getter for the PrivateCDAIObjectMPD instance
*
* @return PrivateCDAIObjectMPD object pointer
*/
PrivateCDAIObjectMPD* GetPrivateCDAIObjectMPD()
{
return mPrivObj;
}
/**
* @brief Setting the alternate contents' (Ads/blackouts) URL
*
* @param[in] periodId - Adbreak's unique identifier; the first period id
* @param[in] adId - Individual Ad's id
* @param[in] url - Ad URL
* @param[in] startMS - Ad start time in milliseconds
* @param[in] breakdur - Adbreak's duration in MS
*/
virtual void SetAlternateContents(const std::string &periodId, const std::string &adId, const std::string &url, uint64_t startMS=0, uint32_t breakdur=0) override;
};
/**
* @brief Events to the Ad manager's state machine
*/
enum class AdEvent
{
INIT, /**< Playback initialization */
BASE_OFFSET_CHANGE, /**< Base period's offset change */
AD_FINISHED, /**< Ad playback finished */
AD_FAILED, /**< Ad playback failed */
PERIOD_CHANGE, /**< Period changed */
DEFAULT = PERIOD_CHANGE /**< Default event */
};
#define OFFSET_ALIGN_FACTOR 2000 /**< Observed minor slacks in the ad durations. Align factor used to place the ads correctly. */
/**
* @struct AdNode
* @brief Individual Ad's meta info
*/
struct AdNode {
bool invalid; /**< Failed to playback failed once, no need to attempt later */
bool placed; /**< Ad completely placed on the period */
std::string adId; /**< Ad's identifier */
std::string url; /**< Ad's manifest URL */
uint64_t duration; /**< Duration of the Ad */
std::string basePeriodId; /**< Id of the base period at the beginning of the Ad */
int basePeriodOffset; /**< Offset of the base period at the beginning of the Ad */
MPD* mpd; /**< Pointer to the MPD object */
/**
* @brief AdNode default constructor
*/
AdNode() : invalid(false), placed(false), adId(), url(), duration(0), basePeriodId(), basePeriodOffset(0), mpd(nullptr)
{
}
/**
* @brief AdNode constructor
*
* @param[in] invalid - Is Ad valid
* @param[in] placed - Is Ad completed placed over underlying period
* @param[in] adId - Ad identifier
* @param[in] url - Ad's manifest URL
* @param[in] duration - Duration of the Ad
* @param[in] basePeriodId - Base period id of the Ad
* @param[in] basePeriodOffset - Base period offset of the Ad
* @param[in] mpd - Pointer to the MPD object
*/
AdNode(bool invalid, bool placed, std::string adId, std::string url, uint64_t duration,
std::string basePeriodId, int basePeriodOffset, MPD* mpd)
: invalid(invalid), placed(placed), adId(adId), url(url), duration(duration), basePeriodId(basePeriodId),
basePeriodOffset(basePeriodOffset), mpd(mpd)
{
}
/**
* @brief AdNode Copy Constructor
*
* @param[in] adNode - Reference to the source AdNode
*/
AdNode(const AdNode& adNode) : invalid(adNode.invalid), placed(adNode.placed), adId(adNode.adId),
url(adNode.url), duration(adNode.duration), basePeriodId(adNode.basePeriodId),
basePeriodOffset(adNode.basePeriodOffset), mpd(adNode.mpd)
{
}
/**
* @brief AdNode assignment operator overloading
*/
AdNode& operator=(const AdNode&) = delete;
};
/**
* @struct AdBreakObject
*
* @brief AdBreak's metadata object
*/
struct AdBreakObject{
uint32_t brkDuration; /**< Adbreak's duration */
std::shared_ptr<std::vector<AdNode>> ads; /**< Ads in the Adbreak in sequential order */
std::string endPeriodId; /**< Base period's id after the adbreak playback */
uint64_t endPeriodOffset; /**< Base period's offset after the adbreak playback */
uint32_t adsDuration; /**< Ads' duration in the Adbreak */
bool adjustEndPeriodOffset; /**< endPeriodOffset needs be re-adjusted or not */
/**
* @brief AdBreakObject default constructor
*/
AdBreakObject() : brkDuration(0), ads(), endPeriodId(), endPeriodOffset(0), adsDuration(0), adjustEndPeriodOffset(false)
{
}
/**
* @brief AdBreakObject constructor
*
* @param[in] _duration - Adbreak's duration
* @param[in] _ads - Ads in the Adbreak
* @param[in] _endPeriodId - Base period's id after the adbreak playback
* @param[in] _endPeriodOffset - Base period's offset after the adbreak playback
* @param[in] _adsDuration - Ads' duration in the Adbreak
*/
AdBreakObject(uint32_t _duration, std::shared_ptr<std::vector<AdNode>> _ads, std::string _endPeriodId,
uint64_t _endPeriodOffset, uint32_t _adsDuration)
: brkDuration(_duration), ads(_ads), endPeriodId(_endPeriodId), endPeriodOffset(_endPeriodOffset), adsDuration(_adsDuration), adjustEndPeriodOffset(false)
{
}
};
/**
* @struct AdOnPeriod
*
* @brief Individual Ad's object placed over the period
*/
struct AdOnPeriod
{
int32_t adIdx; /**< Ad's idx (of vector) */
uint32_t adStartOffset; /**< Ad's start offset */
};
/**
* @struct Period2AdData
* @brief Meta info corresponding to each period.
*/
struct Period2AdData {
bool filled; /**< Period filled with ads or not */
std::string adBreakId; /**< Parent Adbreak */
uint64_t duration; /**< Period's Duration */
std::map<int, AdOnPeriod> offset2Ad; /**< Mapping period's offset to individual Ads */
/**
* @brief Period2AdData constructor
*/
Period2AdData() : filled(false), adBreakId(), duration(0), offset2Ad()
{
}
};
/**
* @struct AdFulfillObj
*
* @brief Temporary object representing currently fulfilling ad (given by setAlternateContent).
*/
struct AdFulfillObj {
std::string periodId; /**< Currently fulfilling adbreak id */
std::string adId; /**< Currently placing Ad id */
std::string url; /**< Current Ad's URL */
/**
* @brief AdFulfillObj constructor
*/
AdFulfillObj() : periodId(), adId(), url()
{
}
};
/**
* @struct PlacementObj
*
* @brief Currently placing Ad's object
*/
struct PlacementObj {
std::string pendingAdbrkId; /**< Only one Adbreak will be pending for replacement */
std::string openPeriodId; /**< The period in the adbreak that is progressing */
uint64_t curEndNumber; /**< Current periods last fragment number */
int curAdIdx; /**< Currently placing ad, during MPD progression */
uint32_t adNextOffset; /**< Current Ad's offset to be placed in the next iteration of PlaceAds */
/**
* @brief PlacementObj constructor
*/
PlacementObj(): pendingAdbrkId(), openPeriodId(), curEndNumber(0), curAdIdx(-1), adNextOffset(0)
{
}
};
/**
* @class PrivateCDAIObjectMPD
*
* @brief Private Client Side DAI object for DASH
*/
class PrivateCDAIObjectMPD
{
public:
PrivateInstanceAAMP* mAamp; /**< AAMP player's private instance */
std::mutex mDaiMtx; /**< Mutex protecting DAI critical section */
bool mIsFogTSB; /**< Channel playing from TSB or not */
std::unordered_map<std::string, AdBreakObject> mAdBreaks; /**< Periodid to adbreakobject map*/
std::unordered_map<std::string, Period2AdData> mPeriodMap; /**< periodId to Ad map */
std::string mCurPlayingBreakId; /**< Currently playing Ad */
pthread_t mAdObjThreadID; /**< ThreadId of Ad fulfillment */
bool mAdFailed; /**< Current Ad playback failed flag */
std::shared_ptr<std::vector<AdNode>> mCurAds; /**< Vector of ads from the current Adbreak */
int mCurAdIdx; /**< Currently playing Ad index */
AdFulfillObj mAdFulfillObj; /**< Temporary object for Ad fulfillment (to pass to the fulfillment thread) */
PlacementObj mPlacementObj; /**< Temporary object for Ad placement over period */
double mContentSeekOffset; /**< Seek offset after the Ad playback */
AdState mAdState; /**< Current state of the CDAI state machine */
/**
* @brief PrivateCDAIObjectMPD constructor
*
* @param[in] aamp - Pointer to PrivateInstanceAAMP
*/
PrivateCDAIObjectMPD(PrivateInstanceAAMP* aamp);
/**
* @brief PrivateCDAIObjectMPD destructor
*/
~PrivateCDAIObjectMPD();
/**
* @brief PrivateCDAIObjectMPD copy constructor
*/
PrivateCDAIObjectMPD(const PrivateCDAIObjectMPD&) = delete;
/**
* @brief PrivateCDAIObjectMPD assignment operator
*/
PrivateCDAIObjectMPD& operator= (const PrivateCDAIObjectMPD&) = delete;
/**
* @brief Setting the alternate contents' (Ads/blackouts) URL
*
* @param[in] adBreakId - Adbreak's unique identifier.
* @param[in] adId - Individual Ad's id
* @param[in] url - Ad URL
* @param[in] startMS - Ad start time in milliseconds
* @param[in] breakdur - Adbreak's duration in MS
*/
void SetAlternateContents(const std::string &periodId, const std::string &adId, const std::string &url, uint64_t startMS, uint32_t breakdur=0);
/**
* @brief Method for fullfilling the Ad
*/
void FulFillAdObject();
/**
* @brief Method for downloading and parsing Ad's MPD
*
* @param[in] url - Ad manifest's URL
* @param[out] finalManifest - Is final MPD or the final MPD should be downloaded later
* @param[in] tryFog - Attempt to download from FOG or not
*
* @return Pointer to the MPD object
*/
MPD* GetAdMPD(std::string &url, bool &finalManifest, bool tryFog = false);
/**
* @brief Method to insert period into period map
*
* @param[in] period - Pointer of the period to be inserted
*/
void InsertToPeriodMap(IPeriod *period);
/**
* @brief Method to check the existence of period in the period map
*
* @param[in] periodId - Period id to be checked.
* @return true or false
*/
bool isPeriodExist(const std::string &periodId);
/**
* @brief Method to check the existence of Adbreak object in the AdbreakObject map
*
* @param[in] adBrkId - Adbreak id to be checked.
* @return true or false
*/
inline bool isAdBreakObjectExist(const std::string &adBrkId);
/**
* @brief Method to remove expired periods from the period map
*
* @param[in] newPeriodIds - Period ids from the latest manifest
*/
void PrunePeriodMaps(std::vector<std::string> &newPeriodIds);
/**
* @brief Method to reset the state of the CDAI state machine
*/
void ResetState();
/**
* @brief Method to clear the maps in the CDAI object
*/
void ClearMaps();
/**
* @brief Method to create a bidirectional between the ads and the underlying content periods
*/
void PlaceAds(dash::mpd::IMPD *mpd);
/**
* @brief Checking to see if a period is the begining of the Adbreak or not.
*
* @param[in] rate - Playback rate
* @param[in] periodId - Period id to be checked
* @param[in] offSet - Period offset to be checked
* @param[out] breakId - Id of the Adbreak, if the period & offset falls in an Adbreak
* @param[out] adOffset - Offset of the Ad for that point of the period
*
* @return Ad index, if the period has an ad over it. Else -1
*/
int CheckForAdStart(const float &rate, bool init, const std::string &periodId, double offSet, std::string &breakId, double &adOffset);
/**
* @brief Checking to see if the position in a period corresponds to an end of Ad playback or not
*
* @param[in] fragmentTime - Current offset in the period
*
* @return True or false
*/
bool CheckForAdTerminate(double fragmentTime);
/**
* @brief Checking to see if a period has Adbreak
*
* @param[in] periodId - Period id
*
* @return True or false
*/
inline bool isPeriodInAdbreak(const std::string &periodId);
};
#endif /* ADMANAGER_MPD_H_ */