1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "pvmf_protocol_engine_node.h"
19 #include "pvmf_protocol_engine_node_progressive_download.h"
20 #include "pvmf_protocolengine_node_tunables.h"
21 #include "pvmf_protocol_engine_progressive_download.h"
22
23
24 #define GET_10_PERCENT(x) ( ((x)>>3)-((x)>>6) ) // 1/8 - 1/64 = 0.109
25
26
27 ////////////////////////////////////////////////////////////////////////////////////
28 ////// ProgessiveDownloadContainer implementation
29 ////////////////////////////////////////////////////////////////////////////////////
ProgressiveDownloadContainer(PVMFProtocolEngineNode * aNode)30 OSCL_EXPORT_REF ProgressiveDownloadContainer::ProgressiveDownloadContainer(PVMFProtocolEngineNode *aNode) :
31 DownloadContainer(aNode),
32 iNumCheckExtraDataComeIn(0),
33 iNumCheckEOSAfterDisconnectSocket(0)
34 {
35 ;
36 }
37
createProtocolObjects()38 OSCL_EXPORT_REF bool ProgressiveDownloadContainer::createProtocolObjects()
39 {
40 if (!ProtocolContainer::createProtocolObjects()) return false;
41
42 iProtocol = OSCL_NEW(ProgressiveDownload, ());
43 iNodeOutput = OSCL_NEW(pvHttpDownloadOutput, (iNode));
44 iDownloadControl = OSCL_NEW(progressiveDownloadControl, ());
45 iDownloadProgess = OSCL_NEW(ProgressiveDownloadProgress, ());
46 iEventReport = OSCL_NEW(downloadEventReporter, (iNode));
47 iCfgFileContainer = OSCL_NEW(PVProgressiveDownloadCfgFileContainer, (iDownloadSource));
48 iUserAgentField = OSCL_NEW(UserAgentFieldForProgDownload, ());
49 iDownloadSource = OSCL_NEW(PVMFDownloadDataSourceContainer, ());
50
51 if (!iProtocol || !iNodeOutput || !iDownloadControl ||
52 !iDownloadProgess || !iEventReport || !iCfgFileContainer ||
53 !iUserAgentField || !iDownloadSource) return false;
54
55 DownloadContainer::setEventReporterSupportObjects();
56 return true;
57 }
58
needSocketReconnect()59 OSCL_EXPORT_REF bool ProgressiveDownloadContainer::needSocketReconnect()
60 {
61 // currently, only disallow socket reconnect for head request disabled during prepare->start
62 if (iObserver->GetObserverState() == (uint32)EPVMFNodePrepared &&
63 iInterfacingObjectContainer->getHttpHeadRequestDisabled() &&
64 !iForceSocketReconnect) return false;
65 return true;
66 }
67
initImpl()68 OSCL_EXPORT_REF PVMFStatus ProgressiveDownloadContainer::initImpl()
69 {
70 if (!iInterfacingObjectContainer->getHttpHeadRequestDisabled()) return ProtocolContainer::initImpl();
71
72 if (!isObjectsReady())
73 {
74 return PVMFErrNotReady;
75 }
76
77 // initialize output object
78 int32 status = initNodeOutput();
79 if (status != PVMFSuccess) return status;
80
81 // initialize protocol object
82 if (!initProtocol()) return PVMFFailure;
83
84 // initialize download control object
85 initDownloadControl();
86
87 return PVMFSuccess;
88 }
89
initProtocol_SetConfigInfo()90 OSCL_EXPORT_REF bool ProgressiveDownloadContainer::initProtocol_SetConfigInfo()
91 {
92 OsclSharedPtr<PVDlCfgFile> aCfgFile = iCfgFileContainer->getCfgFile();
93 if (aCfgFile.GetRep() == NULL) return false;
94 aCfgFile->setHttpHeadRequestDisabled(iInterfacingObjectContainer->getHttpHeadRequestDisabled());
95 return DownloadContainer::initProtocol_SetConfigInfo();
96 }
97
98
99 ////////////////////////////////////////////////////////////////////////////////////
100 ////// progressiveDownloadControl implementation
101 ////////////////////////////////////////////////////////////////////////////////////
isDlAlgoPreConditionMet(const uint32 aDownloadRate,const uint32 aDurationMsec,const uint32 aCurrDownloadSize,const uint32 aFileSize)102 OSCL_EXPORT_REF bool progressiveDownloadControl::isDlAlgoPreConditionMet(const uint32 aDownloadRate,
103 const uint32 aDurationMsec,
104 const uint32 aCurrDownloadSize,
105 const uint32 aFileSize)
106 {
107 // first make sure initial download pre-conditions should be met
108 if (!pvDownloadControl::isDlAlgoPreConditionMet(aDownloadRate, aDurationMsec, aCurrDownloadSize, aFileSize)) return false;
109
110 // then heck the parser consuming rate is close to clip bitrate
111 int32 status = isPlaybackRateCloseToClipBitrate(aDurationMsec, aCurrDownloadSize, aFileSize);
112 if (status == 0) return true; // parser node data consumption rate is close to clip bitrate
113 if (status == -1) return true; // duration is not available, then don't wait and kicks off algo running
114
115 return false; // parser node data consumption rate is not close to clip bitrate
116 }
117
118 // ret_val: 0, success,
119 // 1, playback rate is not close to clip bitrate, but the information is all available
120 // -1, related information, e.g. duration=0, size2time conversion is not available, is not available
isPlaybackRateCloseToClipBitrate(const uint32 aDurationMsec,const uint32 aCurrDownloadSize,const uint32 aFileSize)121 OSCL_EXPORT_REF int32 progressiveDownloadControl::isPlaybackRateCloseToClipBitrate(const uint32 aDurationMsec,
122 const uint32 aCurrDownloadSize,
123 const uint32 aFileSize)
124 {
125 if (aFileSize == 0 || aDurationMsec == 0 || iProgDownloadSI == NULL) return -1;
126
127 uint32 aNPTInMS = 0;
128
129 if (iProgDownloadSI->convertSizeToTime(aCurrDownloadSize, aNPTInMS) == 0)
130 {
131
132 if (aNPTInMS == 0) return 1;
133 if (iClipByterate == 0) iClipByterate = divisionInMilliSec(aFileSize, aDurationMsec); // aFileSize*1000/aDurationMsec
134 uint32 aInstantByterate = divisionInMilliSec(aCurrDownloadSize, aNPTInMS); // aCurrDownloadSize*1000/aNPTInMS
135 LOGINFODATAPATH((0, "progressiveDownloadControl::isPlaybackRateCloseToClipBitrate, check Instant rate=%d(currDLSize=%d, NPTTimeMs=%d), clip bitrate=%d",
136 (aInstantByterate << 3), aCurrDownloadSize, aNPTInMS, (iClipByterate << 3)));
137 uint32 diffByterate = (aInstantByterate >= iClipByterate ? aInstantByterate - iClipByterate : iClipByterate - aInstantByterate);
138 if (diffByterate < GET_10_PERCENT(iClipByterate) || // OSCL_ABS(aInstantByterate-iClipByterate)/iClipByterate < 1/8-1/64=0.109
139 isBufferingEnoughTime(aCurrDownloadSize, PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_TIME, aNPTInMS))
140 {
141 if (isBufferingEnoughTime(aCurrDownloadSize, PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_TIME, aNPTInMS))
142 {
143 return 0;
144 }
145 return 1;
146 }
147 }
148 else
149 {
150 // in case of convertSizeToTime() not supported in parser node, but duration can be estimated and provided
151 if (iClipByterate == 0) iClipByterate = divisionInMilliSec(aFileSize, aDurationMsec);
152 if (isBufferingEnoughTime(aCurrDownloadSize, PVPROTOCOLENGINE_INIT_DOWNLOAD_TIME_THRESHOLD_WITH_CLIPBITRATE)) return 0;
153 }
154
155 return 1;
156 }
157
isBufferingEnoughTime(const uint32 aCurrDownloadSize,const uint32 aBufferTimeLimitInSec,const uint32 aNPTInMS)158 OSCL_EXPORT_REF bool progressiveDownloadControl::isBufferingEnoughTime(const uint32 aCurrDownloadSize,
159 const uint32 aBufferTimeLimitInSec,
160 const uint32 aNPTInMS)
161 {
162 if (aNPTInMS == 0xFFFFFFFF)
163 {
164 // use clip bitrate to calculate buffering time, instead of using convertSizeToTime()
165 uint32 deltaSizeLimit = iClipByterate * aBufferTimeLimitInSec;
166 return (aCurrDownloadSize >= iPrevDownloadSize + deltaSizeLimit);
167 }
168 else if (aNPTInMS > 0)
169 {
170 // convertSizeToTime() should be available
171 if (iPrevDownloadSize == 0)
172 {
173 return (aNPTInMS >= aBufferTimeLimitInSec*1000);
174 }
175 else
176 {
177 uint32 aPrevNPTInMS = 0;
178 if (iProgDownloadSI->convertSizeToTime(iPrevDownloadSize, aPrevNPTInMS) == 0)
179 {
180 return (aNPTInMS > aPrevNPTInMS && (aNPTInMS - aPrevNPTInMS) >= aBufferTimeLimitInSec*1000);
181 }
182 }
183 }
184 return false;
185 }
186
checkNewDuration(const uint32 aCurrDurationMsec,uint32 & aNewDurationMsec)187 OSCL_EXPORT_REF bool progressiveDownloadControl::checkNewDuration(const uint32 aCurrDurationMsec, uint32 &aNewDurationMsec)
188 {
189 aNewDurationMsec = aCurrDurationMsec;
190 if (aCurrDurationMsec > 0 && iClipByterate == 0)
191 {
192 if (iFileSize > 0) iClipByterate = divisionInMilliSec(iFileSize, aCurrDurationMsec);
193 }
194
195 if (iPlaybackByteRate > 0)
196 {
197 if (iPlaybackByteRate > iClipByterate)
198 {
199 uint32 averPlaybackRate = (iClipByterate + iPlaybackByteRate) / 2;
200 aNewDurationMsec = divisionInMilliSec(iFileSize, averPlaybackRate); // aFileSize/averPlaybackRate*1000
201 }
202 }
203 return true;
204 }
205
approveAutoResumeDecisionShortCut(const uint32 aCurrDownloadSize,const uint32 aDurationMsec,const uint32 aPlaybackTimeMsec,uint32 & aPlaybackRemainingTimeMsec)206 OSCL_EXPORT_REF bool progressiveDownloadControl::approveAutoResumeDecisionShortCut(const uint32 aCurrDownloadSize,
207 const uint32 aDurationMsec,
208 const uint32 aPlaybackTimeMsec,
209 uint32 &aPlaybackRemainingTimeMsec)
210 {
211 if (!iProgDownloadSI || aDurationMsec == 0) return false;
212
213 uint32 aNPTInMS = 0;
214 if (iProgDownloadSI->convertSizeToTime(aCurrDownloadSize, aNPTInMS) == 0)
215 {
216 aPlaybackRemainingTimeMsec = aDurationMsec - aNPTInMS;
217 if (aNPTInMS > PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_TIME*2000 + aPlaybackTimeMsec)
218 return true;
219 }
220 return false;
221 }
222
223 // No constraint: for file size/clip duration/clip bitrate(i.e. playback rate), one of them must be unavailable, except
224 // file size and clip duration are available, but clip bitrate is unavailable
checkAutoResumeAlgoNoConstraint(const uint32 aCurrDownloadSize,const uint32 aFileSize,uint32 & aDurationMsec)225 OSCL_EXPORT_REF bool progressiveDownloadControl::checkAutoResumeAlgoNoConstraint(const uint32 aCurrDownloadSize,
226 const uint32 aFileSize,
227 uint32 &aDurationMsec)
228 {
229 // first check one exception: file size>0, duration=0, playbackRate>0, then we need to estimate the clip duration
230 if (checkEstDurationAvailable(aFileSize, aDurationMsec)) return false;
231
232 uint32 currDownloadSizeOfInterest = aCurrDownloadSize - iPrevDownloadSize; // use download size as the jitter buffer size
233 if (iPlaybackByteRate > 0) currDownloadSizeOfInterest /= iPlaybackByteRate; // use playback time as the jitter buffer size
234 else if (aFileSize > 0) currDownloadSizeOfInterest /= (aFileSize / PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_CONVERTION_100); // use download percentage as the jitter buffer size
235
236 uint32 aJitterBufferSize = (iPlaybackByteRate > 0 ? PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_TIME :
237 (aFileSize > 0 ? PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_DLPERCENTAGE :
238 PVPROTOCOLENGINE_JITTER_BUFFER_SIZE_BYTES));
239 bool resumeOK = (currDownloadSizeOfInterest >= aJitterBufferSize);
240 LOGINFODATAPATH((0, "progressiveDownloadControl::isResumePlayback()->checkAutoResumeAlgoNoConstraint(), resumeOK=%d, currDownloadSize=%d, prevDownloadSize=%d, currDownloadSizeOfInterest=%d, aJitterBufferSize=%d, file size=%d",
241 (uint32)resumeOK, aCurrDownloadSize, iPrevDownloadSize, currDownloadSizeOfInterest, aJitterBufferSize, aFileSize));
242
243 return resumeOK;
244 }
245
checkEstDurationAvailable(const uint32 aFileSize,uint32 & aDurationMsec)246 OSCL_EXPORT_REF bool progressiveDownloadControl::checkEstDurationAvailable(const uint32 aFileSize, uint32 &aDurationMsec)
247 {
248 // check file size>0, duration=0, playbackRate>0, then we need to estimate the clip duration
249 // and use the original algorithm
250 if (iPlaybackByteRate > 0 && aFileSize > 0 && aDurationMsec == 0)
251 {
252 // calculate estimated duration
253 aDurationMsec = divisionInMilliSec(aFileSize, iPlaybackByteRate);
254 LOGINFODATAPATH((0, "progressiveDownloadControl::isResumePlayback()->checkEstDurationAvailable(), aFileSize=%d, aPlaybackByteRate=%d, estDurationMsec=%d",
255 aFileSize, iPlaybackByteRate, aDurationMsec));
256 return true;
257 }
258 return false;
259 }
260
261
updateDownloadClock()262 OSCL_EXPORT_REF bool progressiveDownloadControl::updateDownloadClock()
263 {
264 if (!iProgDownloadSI || !iProtocol) return false;
265
266 // using size2time conversion to update download clock in PDL only applies to the case where
267 // old algorithm gets running without engine clock input
268 if (!iCurrentPlaybackClock)
269 {
270 uint32 aDownloadNPTTime = 0;
271 // get download size from output object instead of protocol engine.
272 // The download size from output object is the actual size for the data written to the file, and is exposed to user,
273 // while the download size time from protocol engine is internally counted from socket and most likely
274 // larger than that from output object
275
276 if (iProgDownloadSI->convertSizeToTime(iNodeOutput->getCurrentOutputSize(), aDownloadNPTTime) != 0) return false;
277 bool bOverflowFlag = false;
278 iDlProgressClock->SetStartTime32(aDownloadNPTTime, PVMF_MEDIA_CLOCK_MSEC, bOverflowFlag);
279 }
280 return true;
281 }
282
283
284 ////////////////////////////////////////////////////////////////////////////////////
285 ////// ProgressiveDownloadProgress implementation
286 ////////////////////////////////////////////////////////////////////////////////////
setSupportObject(OsclAny * aDLSupportObject,DownloadControlSupportObjectType aType)287 OSCL_EXPORT_REF void ProgressiveDownloadProgress::setSupportObject(OsclAny *aDLSupportObject, DownloadControlSupportObjectType aType)
288 {
289 switch (aType)
290 {
291 case DownloadControlSupportObjectType_ConfigFileContainer:
292 iCfgFileContainer = (PVDlCfgFileContainer *)aDLSupportObject;
293 break;
294
295 case DownloadControlSupportObjectType_SupportInterface:
296 iProgDownloadSI = (PVMFFormatProgDownloadSupportInterface*)aDLSupportObject;
297 break;
298
299 default:
300 break;
301 }
302
303 DownloadProgress::setSupportObject(aDLSupportObject, aType);
304 }
305
updateDownloadClock(const bool aDownloadComplete)306 OSCL_EXPORT_REF bool ProgressiveDownloadProgress::updateDownloadClock(const bool aDownloadComplete)
307 {
308 OSCL_UNUSED_ARG(aDownloadComplete);
309 if (iProtocol) iDownloadSize = iNodeOutput->getCurrentOutputSize();
310 if (iDownloadSize == 0) return false;
311 return checkDownloadPercentModeAndUpdateDLClock();
312 }
313
checkDownloadPercentModeAndUpdateDLClock()314 OSCL_EXPORT_REF bool ProgressiveDownloadProgress::checkDownloadPercentModeAndUpdateDLClock()
315 {
316 // (1) if user specifies byte-based download percentage or no content length case,
317 // no need to update download clock and download time
318 if (iDownloadProgressMode > 0 ||
319 iProtocol->getContentLength() == 0)
320 {
321 iTimeBasedDownloadPercent = false;
322 return true;
323 }
324
325 // (2) if download and playback mode is not asap mode, i.e. download and play or download only,
326 // then use byte-based download percent
327 if (!iProgDownloadSI && iCfgFileContainer)
328 {
329 if (iCfgFileContainer->getPlaybackMode() != PVMFDownloadDataSourceHTTP::EAsap) iTimeBasedDownloadPercent = false;
330 return true;
331 }
332
333 // (3) if parser node is not ready to do conversion from size to time,
334 // then choose byte-based download percent
335 if (iProgDownloadSI->convertSizeToTime(iDownloadSize, iDownloadNPTTime) != 0)
336 {
337 iTimeBasedDownloadPercent = false;
338 return true;
339 }
340 return true;
341 }
342
calculateDownloadPercent(uint32 & aDownloadProgressPercent)343 OSCL_EXPORT_REF bool ProgressiveDownloadProgress::calculateDownloadPercent(uint32 &aDownloadProgressPercent)
344 {
345 return calculateDownloadPercentBody(aDownloadProgressPercent, iProtocol->getContentLength());
346 }
347
calculateDownloadPercentBody(uint32 & aDownloadProgressPercent,const uint32 aFileSize)348 OSCL_EXPORT_REF bool ProgressiveDownloadProgress::calculateDownloadPercentBody(uint32 &aDownloadProgressPercent, const uint32 aFileSize)
349 {
350 if (iTimeBasedDownloadPercent)
351 {
352 return DownloadProgress::calculateDownloadPercent(aDownloadProgressPercent);
353 }
354 else
355 {
356 // byte-based download percentage
357 aDownloadProgressPercent = iDownloadSize;
358 if (aFileSize > 0)
359 {
360 aDownloadProgressPercent = getDownloadBytePercent(iDownloadSize, aFileSize);
361 if (aDownloadProgressPercent > 100) aDownloadProgressPercent = 100;
362 if (aDownloadProgressPercent == 100) iDownloadSize = aFileSize;
363 }
364 else
365 {
366 uint32 aMaxFileSize = iCfgFileContainer->getCfgFile()->GetMaxAllowedFileSize();
367 if (aDownloadProgressPercent > aMaxFileSize) aDownloadProgressPercent = aMaxFileSize;
368 }
369 }
370 return true;
371 }
372
373 // handle overflow issue for integer multiplication: downloadSize*100/fileSize
getDownloadBytePercent(const uint32 aDownloadSize,const uint32 aFileSize)374 OSCL_EXPORT_REF uint32 ProgressiveDownloadProgress::getDownloadBytePercent(const uint32 aDownloadSize, const uint32 aFileSize)
375 {
376 uint32 aDownloadProgressPercent = aDownloadSize * PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_CONVERTION_100 / aFileSize; // 100
377 if ((aDownloadSize >> PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_DLSIZE_LIMIT_RIGHT_SHIFT_FACTOR) > 0) // right shift 25 bits => larger than 2^25, then *100 may cause overflow
378 {
379 aDownloadProgressPercent = (aDownloadSize >> PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_DLSIZE_RIGHTSHIFT_FACTOR)* // right shift 7 bits, 2^7>100 to avoid overflow
380 PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_CONVERTION_100 /
381 (aFileSize >> PVPROTOCOLENGINE_DOWNLOAD_BYTE_PERCENTAGE_DLSIZE_RIGHTSHIFT_FACTOR);
382 }
383 return aDownloadProgressPercent;
384 }
385
reset()386 OSCL_EXPORT_REF void ProgressiveDownloadProgress::reset()
387 {
388 DownloadProgress::reset();
389
390 iCfgFileContainer = NULL;
391 iProgDownloadSI = NULL;
392 iTimeBasedDownloadPercent = false;
393 iDownloadProgressMode = (uint32)DownloadProgressMode_ByteBased;
394 }
395
396 ////////////////////////////////////////////////////////////////////////////////////
397 ////// UserAgentField implementation
398 ////////////////////////////////////////////////////////////////////////////////////
UserAgentFieldForProgDownload(OSCL_wString & aUserAgent,const bool isOverwritable)399 OSCL_EXPORT_REF UserAgentFieldForProgDownload::UserAgentFieldForProgDownload(OSCL_wString &aUserAgent, const bool isOverwritable) :
400 UserAgentField(aUserAgent, isOverwritable)
401 {
402 ;
403 }
404
UserAgentFieldForProgDownload(OSCL_String & aUserAgent,const bool isOverwritable)405 OSCL_EXPORT_REF UserAgentFieldForProgDownload::UserAgentFieldForProgDownload(OSCL_String &aUserAgent, const bool isOverwritable) :
406 UserAgentField(aUserAgent, isOverwritable)
407 {
408 ;
409 }
410
getDefaultUserAgent(OSCL_String & aUserAgent)411 OSCL_EXPORT_REF void UserAgentFieldForProgDownload::getDefaultUserAgent(OSCL_String &aUserAgent)
412 {
413 OSCL_HeapString<OsclMemAllocator> defaultUserAgent(PDL_HTTP_USER_AGENT); // defined in pvmf_protocolengine_node_tunables.h
414 aUserAgent = defaultUserAgent;
415 }
416
417
418 ////////////////////////////////////////////////////////////////////////////////////
419 ////// PVProgressiveDownloadCfgFileContainer implementation
420 ////////////////////////////////////////////////////////////////////////////////////
421
configCfgFile(OSCL_String & aUrl)422 OSCL_EXPORT_REF PVMFStatus PVProgressiveDownloadCfgFileContainer::configCfgFile(OSCL_String &aUrl)
423 {
424 // playback mode and proxy
425 iPlaybackMode = (PVMFDownloadDataSourceHTTP::TPVPlaybackControl)iDataSource->iPlaybackControl;
426 iCfgFileObj->SetPlaybackMode(convertToConfigFilePlaybackMode(iPlaybackMode));
427 iCfgFileObj->SetProxyName(iDataSource->iProxyName);
428 iCfgFileObj->SetProxyPort(iDataSource->iProxyPort);
429
430 // user agent
431 OSCL_FastString user_agent(PDL_HTTP_USER_AGENT); // defined in pvmf_protocolengine_node_tunables.h
432 iCfgFileObj->SetUserAgent(user_agent);
433
434 // user-id and password
435 if (iDataSource->iUserID.get_size() > 0) iCfgFileObj->SetUserId(iDataSource->iUserID);
436 if (iDataSource->iUserPasswd.get_size() > 0) iCfgFileObj->SetUserAuth(iDataSource->iUserPasswd);
437
438 iCfgFileObj->SetDownloadType(false);//not fasttrack
439 return PVDlCfgFileContainer::configCfgFile(aUrl);
440 }
441
convertToConfigFilePlaybackMode(PVMFDownloadDataSourceHTTP::TPVPlaybackControl aPlaybackMode)442 OSCL_EXPORT_REF PVDlCfgFile::TPVDLPlaybackMode PVProgressiveDownloadCfgFileContainer::convertToConfigFilePlaybackMode(PVMFDownloadDataSourceHTTP::TPVPlaybackControl aPlaybackMode)
443 {
444 OSCL_UNUSED_ARG(aPlaybackMode);
445
446 PVDlCfgFile::TPVDLPlaybackMode mode = PVDlCfgFile::EPVDL_ASAP;
447 switch (iPlaybackMode)
448 {
449 case PVMFDownloadDataSourceHTTP::EAsap:
450 mode = PVDlCfgFile::EPVDL_ASAP;
451 break;
452 case PVMFDownloadDataSourceHTTP::EAfterDownload:
453 mode = PVDlCfgFile::EPVDL_PLAYBACK_AFTER_DOWNLOAD;
454 break;
455 case PVMFDownloadDataSourceHTTP::ENoPlayback:
456 mode = PVDlCfgFile::EPVDL_DOWNLOAD_ONLY;
457 break;
458 default:
459 break;
460 }
461 return mode;
462 }
463
464