bluetooth/gavdp/test/tavsrcStreamer.cpp
branchRCL_3
changeset 24 e9b924a62a66
parent 0 29b1cd4cb562
equal deleted inserted replaced
23:5b153be919d4 24:e9b924a62a66
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "tavsrcStreamer.h"
       
    17 #include "tavsrcUI.h"
       
    18 #include "tavsrcUtils.h"
       
    19 
       
    20 #include <bluetoothav.h>
       
    21 
       
    22 static const TSize KStreamerConsole(55,12);
       
    23 
       
    24 using namespace SymbianBluetoothAV;
       
    25 using namespace SymbianSBC;
       
    26 
       
    27 //
       
    28 // class CSbcTrackInfo
       
    29 //
       
    30 CSbcTrackInfo::~CSbcTrackInfo()
       
    31 	{
       
    32 	iFrameInfo.Close();
       
    33 	}
       
    34 
       
    35 TInt CSbcTrackInfo::GetLastFrameSize()
       
    36 	{
       
    37 	TInt frameSize = KErrNotFound;
       
    38 	TInt count = iFrameInfo.Count();
       
    39 	
       
    40 	if (count > 0)
       
    41 		{
       
    42 		frameSize = iFrameInfo[count - 1].iFrameSize;
       
    43 		}
       
    44 	return frameSize;
       
    45 	}
       
    46 
       
    47 TInt CSbcTrackInfo::AddNewFrame(TInt aFrameSize)
       
    48 	{
       
    49 	TInt rerr = KErrNone;
       
    50 	TInt count = iFrameInfo.Count();
       
    51 
       
    52 	if ((count > 0) && (iFrameInfo[count - 1].iFrameSize == aFrameSize))
       
    53 		{
       
    54 		// another frame of the same size
       
    55 		iFrameInfo[count - 1].iFrameCount++;
       
    56 		}
       
    57 	else
       
    58 		{
       
    59 		// add new frame info
       
    60 		rerr = iFrameInfo.Append(TSbcTrackFrameInfo());
       
    61 		if (rerr == KErrNone)
       
    62 			{
       
    63 			iFrameInfo[count].iFrameSize = aFrameSize;
       
    64 			iFrameInfo[count].iFrameCount = 1;
       
    65 			}
       
    66 		}
       
    67 	return rerr;
       
    68 	}
       
    69 
       
    70 TInt CSbcTrackInfo::RemoveLastFrame()
       
    71 	{
       
    72 	TInt rerr = KErrNotFound;
       
    73 	TInt count = iFrameInfo.Count();
       
    74 	
       
    75 	if (count > 0)
       
    76 		{
       
    77 		if (iFrameInfo[count - 1].iFrameCount > 1)
       
    78 			{
       
    79 			// remove one of the instances of the last frame size
       
    80 			iFrameInfo[count - 1].iFrameCount--;
       
    81 			}
       
    82 		else
       
    83 			{
       
    84 			// remove the last frame info
       
    85 			iFrameInfo.Remove(count - 1);
       
    86 			}
       
    87 		rerr = KErrNone;
       
    88 		}
       
    89 	return rerr;	
       
    90 	}
       
    91 
       
    92 void CSbcTrackInfo::Reset()
       
    93 	{
       
    94 	iFrameInfo.Reset();
       
    95 	}
       
    96 
       
    97 //
       
    98 // class CActiveStreamer
       
    99 //
       
   100 CActiveStreamer* CActiveStreamer::NewL(RSocketArray aSockets,
       
   101 									   CConsoleBase& aConsole,
       
   102 									   MActiveStreamerUser& aUser,
       
   103 									   TUint aDisplayMode,
       
   104 									   TBool aPreloadFile)
       
   105 	{
       
   106 	CActiveStreamer* self = new (ELeave) CActiveStreamer (aConsole, aUser, aDisplayMode, aPreloadFile);
       
   107 	CleanupStack::PushL(self);
       
   108 	self->ConstructL(aSockets);
       
   109 	CleanupStack::Pop();
       
   110 	return self;
       
   111 	}
       
   112 
       
   113 CActiveStreamer::CActiveStreamer(CConsoleBase& aConsole, MActiveStreamerUser& aUser, TUint aDisplayMode, TBool aPreloadFile)
       
   114 : iConsole(aConsole), iUser(aUser), iDisplayMode(aDisplayMode), iPreloadFile(aPreloadFile), iSbcFrameRate(1), iDirectionForward(ETrue)
       
   115 	{
       
   116 	iRTPCanSend = ETrue;
       
   117 	}
       
   118 
       
   119 CActiveStreamer::~CActiveStreamer()
       
   120 	{
       
   121 	delete iTimer;
       
   122 
       
   123 	iSendSource.Close();
       
   124 	iSession.Close();
       
   125 	iSockets[0].Close();
       
   126 	delete iFiles;
       
   127 	iFile.Close();
       
   128 	iRFs.Close();
       
   129 	
       
   130 	delete iProgressBar;
       
   131 	DestroyBucket();
       
   132 	delete iStreamingInfoConsole;	
       
   133 
       
   134 	delete iFileBuf;
       
   135 	iFileBuf = NULL;
       
   136 	
       
   137 	delete iStreamerUI;
       
   138 	iStreamerUI = NULL;	
       
   139 	}
       
   140 
       
   141 void CActiveStreamer::Stream(TBool aIsSink)
       
   142 	{
       
   143 
       
   144 	if (!aIsSink)
       
   145 		{
       
   146 		iStartedTime.UniversalTime();
       
   147 		iTimer->Start(iNominalSendClockInterval);
       
   148 		Drip();		
       
   149 		}
       
   150 	else
       
   151 		{
       
   152 		//as sink, we do want to start up rtp and await its notification of a NewSource
       
   153 		//Nothing to do at the moment, because when INT is a SNK, 
       
   154 		//it just needs to get the RTP packets running and wait for notification.
       
   155 		//This has already been done in constructor of the class.		
       
   156 		}
       
   157 	iStreamerUI->Play();
       
   158 	}
       
   159 
       
   160 void CActiveStreamer::Suspend()
       
   161 	{
       
   162 	iTimer->Cancel(); // stop callbacks to send
       
   163 	iStreamerUI->Pause();
       
   164 	}
       
   165 	
       
   166 void CActiveStreamer::ReStream()
       
   167 	{
       
   168 
       
   169 
       
   170 	iTimer->Start(iNominalSendClockInterval);
       
   171 	Drip();
       
   172 	iStreamerUI->Play();
       
   173 	}
       
   174 
       
   175 	
       
   176 void CActiveStreamer::Stop()
       
   177 	{
       
   178 	iTimer->Cancel();
       
   179 	iStreamerUI->Stop();
       
   180 
       
   181 	iFillLevel = 0;
       
   182 	iPos = 0;
       
   183 	}
       
   184 
       
   185 void CActiveStreamer::Pause()
       
   186 	{
       
   187 	iTimer->Cancel();
       
   188 	iStreamerUI->Pause();
       
   189 	}
       
   190 
       
   191 	
       
   192 void CActiveStreamer::NextTrack()
       
   193 	{
       
   194 	iPos=0;
       
   195 	if (iCurrentFile < iFiles->Count() - 1)
       
   196 		{
       
   197 		iCurrentFile++;
       
   198 		iStreamerUI->Next();
       
   199 		}
       
   200 	else
       
   201 		{
       
   202 		iCurrentFile = 0;
       
   203 		iStreamerUI->First();
       
   204 		}
       
   205 	TRAPD(err, InitL());		
       
   206 	if (err)
       
   207 		{
       
   208 		iConsole.Printf(_L("InitL failed with error: %d"),err);
       
   209 		}
       
   210 	}
       
   211 
       
   212 void CActiveStreamer::PrevTrack()
       
   213 	{
       
   214 	iPos=0;
       
   215 	if (iCurrentFile>0)
       
   216 		{
       
   217 		iCurrentFile--;
       
   218 		iStreamerUI->Prev();
       
   219 		}
       
   220 	TRAPD(err, InitL());		
       
   221 	if (err)
       
   222 		{
       
   223 		iConsole.Printf(_L("InitL failed with error: %d"),err);
       
   224 		}
       
   225 	}
       
   226 
       
   227 void CActiveStreamer::InitL()
       
   228 	{
       
   229 	// close current file
       
   230 	iFile.Close();
       
   231 	delete iProgressBar;
       
   232 	iProgressBar = NULL;
       
   233 
       
   234 	// get file details
       
   235 	RBuf filename;
       
   236 	filename.Create(100);
       
   237 	filename.Append(KSBCFileRoot);
       
   238 	filename.Append(iFiles->operator[](iCurrentFile).iName);
       
   239 	
       
   240 	User::LeaveIfError(iFile.Open(iRFs,filename,EFileRead | EFileShareReadersOnly));
       
   241 	
       
   242 	TInt numChannels, chMode, numSubbands, blkLen, bitPool, freq, allocMethod;
       
   243 	User::LeaveIfError(TTavsrcUtils::GetCodecSettingsFromSBCFile(filename, chMode, numChannels, numSubbands, blkLen, bitPool, freq, allocMethod));
       
   244 	
       
   245 	if (iStreamingInfoConsole)
       
   246 		{
       
   247 		iStreamingInfoConsole->Printf(_L("\nFirst SBC frame info for: %S...\n"), &filename);
       
   248 		}
       
   249 
       
   250 	filename.Close();
       
   251 
       
   252 	// determine if a re-configuration is required
       
   253 	if ((iNumChannels != numChannels) || (iFreq != freq) ||
       
   254 		(iChMode != chMode) || (iBitPool != bitPool) ||
       
   255 		(iBlkLen != blkLen) || (iNumSubbands != numSubbands) ||
       
   256 		(iAllocMethod != allocMethod))
       
   257 		{		
       
   258 		iNumChannels = numChannels;
       
   259 		iChMode = chMode;
       
   260 		iNumSubbands = numSubbands;
       
   261 		iBlkLen = blkLen;
       
   262 		iBitPool = bitPool;
       
   263 		iFreq = freq;
       
   264 		iAllocMethod = allocMethod;
       
   265 		
       
   266 		// configuration is set first time around
       
   267 		if (iSBCFrameSize != 0)
       
   268 			{
       
   269 			TSBCCodecCapabilities cfg;
       
   270 
       
   271 			TSBCSubbandsBitmask subbands = numSubbands == 8 ? EEightSubbands : EFourSubbands;
       
   272 			TSBCAllocationMethodBitmask alloc = allocMethod == 0 ? ELoudness : ESNR;
       
   273 			
       
   274 			TSBCSamplingFrequencyBitmask freqs(0);
       
   275 			if (freq == 48000) freqs = E48kHz;
       
   276 			else if (freq == 44100) freqs = E44100Hz; // note else if now as only select one
       
   277 			else if (freq == 32000) freqs = E32kHz;
       
   278 			else if (freq == 16000) freqs = E16kHz;
       
   279 			
       
   280 			TSBCChannelModeBitmask chs(0); // set it to anything to prevent warning
       
   281 			if (chMode == 0) chs=EMono; 
       
   282 			else if (chMode == 1) chs=EDualChannel; 
       
   283 			else if (chMode == 2) chs=EStereo; 
       
   284 			else if (chMode == 3) chs=EJointStereo; 
       
   285 			
       
   286 			TSBCBlockLengthBitmask blkLens(0); // set it to anything to prevent warning
       
   287 			if (blkLen == 4) blkLens = EBlockLenFour;
       
   288 			else if (blkLen == 8) blkLens = EBlockLenEight;
       
   289 			else if (blkLen == 12) blkLens = EBlockLenTwelve;
       
   290 			else if (blkLen == 16) blkLens = EBlockLenSixteen;
       
   291 				
       
   292 			cfg.SetSamplingFrequencies(freqs);
       
   293 			cfg.SetChannelModes(chs);
       
   294 			cfg.SetBlockLengths(blkLens);
       
   295 			cfg.SetSubbands(subbands);
       
   296 			cfg.SetAllocationMethods(alloc);
       
   297 		
       
   298 			// reconfig required
       
   299 			iUser.MediaCodecConfigurationRequired(cfg);
       
   300 			
       
   301 			// ensure no more timer events until we have finished reconfiguring
       
   302 			iTimer->Cancel();
       
   303 			}
       
   304 
       
   305 		if (chMode == 0 || chMode == 1)
       
   306 			{
       
   307 			iSBCFrameSize = 4+TReal((4*numSubbands*numChannels))/8+TTavsrcUtils::CEIL(TReal(blkLen*numChannels*bitPool)/8);
       
   308 			}
       
   309 		else
       
   310 			{
       
   311 			TBool join = chMode == 0x03;
       
   312 			
       
   313 			iSBCFrameSize = 4+TReal((4*numSubbands*numChannels))/8+TTavsrcUtils::CEIL(TReal((join*numSubbands+blkLen*bitPool))/8);
       
   314 			}
       
   315 
       
   316 		iSBCBitrate = 8*iSBCFrameSize*freq/(numSubbands*blkLen);
       
   317 		TUint64 numerator = TUint64(8000000)*iSBCFrameSize;
       
   318 		iSBCFrameInterval = (numerator)/iSBCBitrate; //microsecs
       
   319 		}
       
   320 	
       
   321 	iSbcTrackInfo.Reset();
       
   322 	iSbcTrackInfo.AddNewFrame(iSBCFrameSize);
       
   323 	
       
   324 	iDirectionForward = ETrue;
       
   325 	iSbcFrameRate = 1;
       
   326 	
       
   327 	User::LeaveIfError(iFile.Size(iFileSize));
       
   328 
       
   329 	if (iStreamingInfoConsole)
       
   330 		{
       
   331 		iStreamingInfoConsole->Printf(_L("Sampling Frequency: %d Hz\n"), iFreq);
       
   332 		iStreamingInfoConsole->Printf(_L("Subbands: %d\n"), iNumSubbands);
       
   333 		iStreamingInfoConsole->Printf(_L("BlkLen: %d\n"), iBlkLen);
       
   334 		iStreamingInfoConsole->Printf(_L("ChannelMode: %d\n"), iChMode);
       
   335 		iStreamingInfoConsole->Printf(_L("AllocMethod: %d\n"), iAllocMethod);
       
   336 		iStreamingInfoConsole->Printf(_L("Bitpool: %d\n"), iBitPool);
       
   337 		iStreamingInfoConsole->Printf(_L("SBC Frame size: %d bytes\n"), iSBCFrameSize);
       
   338 		iStreamingInfoConsole->Printf(_L("Bitrate: %d bps\n"), iSBCBitrate);
       
   339 		}
       
   340 	
       
   341 	TInt err = LoadFile();
       
   342 	if(err==KErrNone)
       
   343 		{
       
   344 		if (iDisplayMode & EProgressBarWindow)
       
   345 			{
       
   346 			iProgressBar = CProgressBar::NewL(iFileSize);
       
   347 			}
       
   348 		FillBucket();
       
   349 		}
       
   350 	else
       
   351 		{
       
   352 		User::Leave(err);
       
   353 		}
       
   354 	// start the timer for this file
       
   355 	iStartTime.UniversalTime();
       
   356 	}
       
   357 
       
   358 void CActiveStreamer::UpdateFrameInfo()
       
   359 	{
       
   360 	TInt numChannels, chMode, numSubbands, blkLen, bitPool, freq, allocMethod;
       
   361 	User::LeaveIfError(TTavsrcUtils::GetCodecSettingsFromSBCFile(iFile, iPos, chMode, numChannels, numSubbands, blkLen, bitPool, freq, allocMethod));
       
   362 
       
   363 	// determine if a re-configuration is required
       
   364 	if ((iNumChannels != numChannels)|| (iFreq != freq) ||
       
   365 		(iChMode != chMode) || (iBitPool != bitPool) ||
       
   366 		(iBlkLen != blkLen) || (iNumSubbands != numSubbands) ||
       
   367 		(iAllocMethod != allocMethod))
       
   368 		{		
       
   369 		iNumChannels = numChannels;
       
   370 		iChMode = chMode;
       
   371 		iNumSubbands = numSubbands;
       
   372 		iBlkLen = blkLen;
       
   373 		iBitPool = bitPool;
       
   374 		iFreq = freq;
       
   375 		iAllocMethod = allocMethod;
       
   376 					
       
   377 		TInt newFrameSize = 0;
       
   378 		if (chMode == 0 || chMode == 1)
       
   379 			{
       
   380 			newFrameSize = 4+TReal((4*numSubbands*numChannels))/8+TTavsrcUtils::CEIL(TReal(blkLen*numChannels*bitPool)/8);
       
   381 			}
       
   382 		else
       
   383 			{
       
   384 			TBool join = chMode == 0x03;
       
   385 			
       
   386 			newFrameSize = 4+TReal((4*numSubbands*numChannels))/8+TTavsrcUtils::CEIL(TReal((join*numSubbands+blkLen*bitPool))/8);
       
   387 			}
       
   388 
       
   389 		if (newFrameSize != iSBCFrameSize)
       
   390 			{
       
   391 			// work out timer for SBC frame
       
   392 			iSBCBitrate = 8*newFrameSize*freq/(numSubbands*blkLen);
       
   393 
       
   394 			TUint64 numerator = TUint64(8000000)*iSBCFrameSize;
       
   395 			iSBCFrameInterval = (numerator)/iSBCBitrate; //microsecs
       
   396 			}
       
   397 		iSBCFrameSize = newFrameSize;
       
   398 		}	
       
   399 	}
       
   400 
       
   401 void CActiveStreamer::TimerEvent(CAdaptiveHighResPeriodic& /*aTimer*/)
       
   402 	{
       
   403 	if (iRTPCanSend)
       
   404 		{
       
   405 		iSent++;
       
   406 		}
       
   407 	else
       
   408 		{
       
   409 		// move iPos on anyway?
       
   410 		iFailedSend++;
       
   411 		}
       
   412 	DoTimerEvent();
       
   413 	}
       
   414 
       
   415 void CActiveStreamer::TimerError(CAdaptiveHighResPeriodic& /*aTimer*/, TInt aError)
       
   416 	{
       
   417 	iConsole.Printf(_L("*ERROR %d*\n"), aError);
       
   418 	__DEBUGGER();
       
   419 	}
       
   420 	
       
   421 
       
   422 void CActiveStreamer::DoTimerEvent()
       
   423 	{
       
   424 	FillBucket();
       
   425 	Drip();
       
   426 	CheckJammed();	
       
   427 	}
       
   428 
       
   429 void CActiveStreamer::FillBucket()
       
   430 	{
       
   431 	// fill up bucket - it may be fully empty or partially full, but top it up in all cases	
       
   432 	if (iFillLevel < KLowTidemark)
       
   433 		{
       
   434 		for (/*iFillLevel*/; iFillLevel < KSendBucketSize; iFillLevel++)
       
   435 			{
       
   436 			// get the next RTP packet to send
       
   437 			RRtpSendPacket& sendPacket = iSendPackets[iFillLevel];
       
   438 			TDes8& payload = sendPacket.WritePayload();
       
   439 			payload.Zero();
       
   440 			payload.Append(0); // update this later with number of frames in packet.
       
   441 			
       
   442 			TInt spaceInRtpPacket = iSBCFrameBytesPerRTP;
       
   443 			TInt framesAdded = 0;
       
   444 			TInt packetInterval = 0;
       
   445 			
       
   446 			TInt nextFrameSize = iDirectionForward ? iSBCFrameSize : iSbcTrackInfo.GetLastFrameSize();
       
   447 			
       
   448 			TBool moreFrames = ETrue;
       
   449 			while ((nextFrameSize > 0) && (nextFrameSize <= spaceInRtpPacket) && (framesAdded <= 15) && moreFrames)
       
   450 				{
       
   451 				// add frame
       
   452 				if (iPreloadFile)
       
   453 					{
       
   454 					TPtrC8 ptr(iFileBuf->Des().Ptr()+iPos, nextFrameSize);
       
   455 					payload.Append(ptr);
       
   456 					}
       
   457 				else
       
   458 					{
       
   459 					TPtr8 ptr(const_cast<TUint8*>(iFileBuf->Des().Ptr()), 0, nextFrameSize);
       
   460 					iFile.Read(iPos, ptr);
       
   461 					payload.Append(ptr);
       
   462 					}
       
   463 				framesAdded++;
       
   464 				packetInterval+=iSBCFrameInterval;			
       
   465 				spaceInRtpPacket-=nextFrameSize;
       
   466 
       
   467 				// get next frame information
       
   468 				for (TInt count = 0; (count != iSbcFrameRate) && moreFrames; count++)
       
   469 					{
       
   470 					iPos = iDirectionForward ? iPos + nextFrameSize : iPos - nextFrameSize;
       
   471 
       
   472 					// determine if we are done with the current file
       
   473 					if ((iPos >= iFileSize) || (iPos < 0))
       
   474 						{
       
   475 						moreFrames = EFalse;
       
   476 						}
       
   477 					else 
       
   478 						{
       
   479 						TInt err = KErrNone;
       
   480 						if (iDirectionForward)
       
   481 							{
       
   482 							// keep track of the frame sizes as we go, this is used to rewind,
       
   483 							// i.e. iDirectionForward = EFalse
       
   484 							if ((err = iSbcTrackInfo.AddNewFrame(iSBCFrameSize)) != KErrNone)
       
   485 								{
       
   486 								iConsole.Printf(_L("Error adding SBC frame information: %d\n"), err);
       
   487 								__DEBUGGER();
       
   488 								}
       
   489 							}
       
   490 						else
       
   491 							{
       
   492 							if ((err = iSbcTrackInfo.RemoveLastFrame()) != KErrNone)
       
   493 								{
       
   494 								// this should never happen as we always check the length first
       
   495 								iConsole.Printf(_L("Error removing SBC frame information: %d\n"), err);
       
   496 								__DEBUGGER();
       
   497 								}
       
   498 							}
       
   499 						UpdateFrameInfo();
       
   500 						nextFrameSize = iDirectionForward ? iSBCFrameSize : iSbcTrackInfo.GetLastFrameSize();
       
   501 						}
       
   502 					}				
       
   503 				}
       
   504 
       
   505 			// has the interval changed since last time we set the timer
       
   506 			if ((iNominalSendClockInterval != packetInterval) && moreFrames)
       
   507 				{
       
   508 				// adjust timer
       
   509 				if (iStreamingInfoConsole)
       
   510 					{
       
   511 					iStreamingInfoConsole->Printf(_L("Interval change from: %d to %d\n"), iNominalSendClockInterval, packetInterval);
       
   512 					}
       
   513 				iNominalSendClockInterval = packetInterval;
       
   514 				iTimer->SetInterval(iNominalSendClockInterval);
       
   515 				}
       
   516 				
       
   517 			// write number of SBC frames into packet
       
   518 			payload[0] = TChar(framesAdded);
       
   519 						
       
   520 			//DrawBucket();	//<--- to animate the display
       
   521 			
       
   522 			if (iPos > iFileSize)
       
   523 				{
       
   524 				// time to do some metrics, and loop back to beginning
       
   525 				TTime finTime;
       
   526 				finTime.UniversalTime();
       
   527 				
       
   528 				TInt64 secs;
       
   529 				secs = (finTime.MicroSecondsFrom(iStartTime)).Int64();
       
   530 				
       
   531 				TInt bps = (iFileSize*8LL*1000000LL)/secs;
       
   532 				iConsole.Printf(_L("Looping. fail=%d, sent=%d, bytes=%d, secs=%Ld"), iFailedSend, iSent, iFileSize, secs);
       
   533 				iConsole.Printf(_L(" bps=%d\n"), bps);
       
   534 
       
   535 				iFailedSend=0;
       
   536 				iSent=0;
       
   537 				iPos=0; // loop
       
   538 				
       
   539 				RDebug::Printf("Looping");
       
   540 				NextTrack();
       
   541 				
       
   542 				// restart the timer
       
   543 				iTimer->Start(iNominalSendClockInterval);
       
   544 				}
       
   545 			else if (iPos <= 0)
       
   546 				{
       
   547 				PrevTrack();
       
   548 				}
       
   549 			else if (iProgressBar)
       
   550 				{
       
   551 				iProgressBar->Increment(iPos-iProgressBarPos);
       
   552 				iProgressBarPos = iPos;
       
   553 				}
       
   554 			}
       
   555 		iPreviousFillLevel = iFillLevel;
       
   556 		}
       
   557 	}
       
   558 
       
   559 void CActiveStreamer::DrawBucket()
       
   560 	{
       
   561 	if (iStreamingInfoConsole)
       
   562 		{
       
   563 		iStreamingInfoConsole->SetPos(1,1);
       
   564 
       
   565 		TBuf<KSendBucketSize> bar;
       
   566 		bar.AppendFill('#',iFillLevel);
       
   567 		bar.AppendFill('.',KSendBucketSize-iFillLevel);
       
   568 	
       
   569 		iStreamingInfoConsole->Printf(bar);
       
   570 		}
       
   571 	}
       
   572 	
       
   573 void CActiveStreamer::Drip()
       
   574 	{
       
   575 	// take head packet
       
   576 	RRtpSendPacket& packet = iSendPackets[0]; //packet=oldpacket
       
   577 
       
   578 	// move previous packet to back - it is reusable, so we don't close
       
   579 	// instead just move to back so that the packet to send is at head
       
   580 	iSendPackets.Remove(0);
       
   581 	iSendPackets.Append(packet);
       
   582 
       
   583 	if (iRTPCanSend && iFillLevel > 0)
       
   584 		{
       
   585 		// take oldest packet and give to RTP
       
   586 		packet.Send();
       
   587 		iRTPCanSend = EFalse;
       
   588 		iFillLevel--;
       
   589 		//DrawBucket();	//<--- to animate the display
       
   590 		}
       
   591 	else
       
   592 		{
       
   593 		// not ready to send yet but when we are send straight away
       
   594 		iBonusDrip = ETrue;
       
   595 		
       
   596 		// remember this as a fail to measure
       
   597 		// let code beneath recycle packet
       
   598 		iFailedSend++;
       
   599 		}		
       
   600 	}
       
   601 	
       
   602 void CActiveStreamer::ConstructL(RSocketArray aSockets)
       
   603 	{
       
   604 	iTimer = CAdaptiveHighResPeriodic::NewL(*this);
       
   605 	
       
   606 	if (iDisplayMode & EStreamerInfoWindow)
       
   607 		{
       
   608 		iStreamingInfoConsole = Console::NewL(_L("Streamer"), KStreamerConsole);
       
   609 		}
       
   610 	
       
   611 	User::LeaveIfError(iRFs.Connect());
       
   612 	
       
   613 	iSockets = aSockets;
       
   614 
       
   615 	TPckgBuf<TInt> mruBuf;
       
   616 	iSockets[0].GetOpt(EAvdtpMediaGetMaximumReceivePacketSize, KSolBtAVDTPMedia, mruBuf);
       
   617 	
       
   618 	// donate media socket to rtp
       
   619 	iSession.OpenL(iSockets[0], mruBuf());
       
   620 	
       
   621 	// we get all RTP events in one place (could have them separately)
       
   622 	iSession.RegisterEventCallbackL(ERtpAnyEvent,
       
   623 									RTPCallbackL,
       
   624 									this);
       
   625 									
       
   626 	iSendSource = iSession.NewSendSourceL();
       
   627 
       
   628 	iSendSource.RegisterEventCallbackL(ERtpAnyEvent,
       
   629 									RTPCallbackL,
       
   630 									this);
       
   631 
       
   632 	iStreamerUI = CStreamerUI::NewL((iDisplayMode & EPlaylistWindow), (iDisplayMode & EChunkyIconWindow));
       
   633 
       
   634 	TInt err = iRFs.GetDir(KSBCFiles, KEntryAttNormal, ESortByName, iFiles);	
       
   635 
       
   636 	// set playlist
       
   637 	for (TInt i=0; i<iFiles->Count(); i++)
       
   638 		{
       
   639 		iStreamerUI->AddTitle(iFiles->operator[](i).iName);
       
   640 		}
       
   641 	
       
   642 	err = aSockets[0].GetOpt(EAvdtpMediaGetMaximumPacketSize, KSolBtAVDTPMedia, iMTU);
       
   643 
       
   644 	iSBCFrameBytesPerRTP = iMTU - 12 - 1;
       
   645 	iSendSource.SetDefaultPayloadSize(iSBCFrameBytesPerRTP+1);
       
   646 
       
   647 	CreateBucketL();
       
   648 	InitL();
       
   649 	}
       
   650 	
       
   651 void CActiveStreamer::CreateBucketL()
       
   652 	{
       
   653 	if (iSendPackets.Count() == KSendBucketSize)
       
   654 		{
       
   655 		RDebug::Printf("Bucket already created");
       
   656 		}
       
   657 	else
       
   658 		{
       
   659 		RDebug::Printf("Creating bucket");
       
   660 		// create all the RTP send packets now
       
   661 		for (TInt i=0; i<KSendBucketSize ; i++)
       
   662 			{
       
   663 			User::LeaveIfError(iSendPackets.Append(iSendSource.NewSendPacketL()));
       
   664 			RDebug::Printf("Adding Sendpacket 0x%08x in bucket", &iSendPackets[i]);
       
   665 			}
       
   666 		}
       
   667 	}
       
   668 	
       
   669 void CActiveStreamer::DestroyBucket()
       
   670 	{
       
   671 	RDebug::Printf("Destroying bucket");
       
   672 
       
   673 	// rtp bug closing these packets?
       
   674 	iSendPackets.Reset();
       
   675 	}
       
   676 	
       
   677 /*static*/ void CActiveStreamer::RTPCallbackL(CActiveStreamer* aStreamer, const TRtpEvent& aEvent)
       
   678 	{
       
   679 	switch (aEvent.Type())
       
   680 		{
       
   681 	case ERtpSendFail:
       
   682 		if (aStreamer->iStreamingInfoConsole)
       
   683 			{
       
   684 			aStreamer->iStreamingInfoConsole->Printf(_L("\n**RTP SEND FAILURE**"));			
       
   685 			}
       
   686 		break;
       
   687 		
       
   688 	case ERtpSendSucceeded:
       
   689 		aStreamer->iRTPCanSend = ETrue;	
       
   690 		if (aStreamer->iBonusDrip)
       
   691 			{
       
   692 			aStreamer->Drip();
       
   693 			aStreamer->iBonusDrip = EFalse;
       
   694 			}
       
   695 		break;
       
   696 		
       
   697 	case ERtpSourceFail:
       
   698 		if (aStreamer->iStreamingInfoConsole)
       
   699 			{
       
   700 			aStreamer->iStreamingInfoConsole->Printf(_L("\n**RTP SOURCE FAILURE**"));			
       
   701 			}
       
   702 		break;
       
   703 		
       
   704 
       
   705 	case ERtpNewSource:
       
   706 		if (aStreamer->iStreamingInfoConsole)
       
   707 			{
       
   708 			aStreamer->iStreamingInfoConsole->Printf(_L("\n**NEW SOURCE!\n"));
       
   709 			}
       
   710 		aStreamer->StartSinkL();
       
   711 		break;
       
   712 		
       
   713 	case ERtpPacketReceived:
       
   714 		RRtpPacket packet = aStreamer->iReceiveSource.Packet();
       
   715 		if (aStreamer->iStreamingInfoConsole)
       
   716 			{
       
   717 			aStreamer->iStreamingInfoConsole->Printf(_L("SNK Rxd packet "));
       
   718 			aStreamer->iStreamingInfoConsole->Printf(_L("SeqNo %d\n"),packet.SequenceNumber());
       
   719 			}
       
   720 		break;
       
   721 		}
       
   722 	}
       
   723 	
       
   724 void CActiveStreamer::StartSinkL()
       
   725 	{
       
   726 	iReceiveSource = iSession.NewReceiveSourceL();
       
   727 	iReceiveSource.RegisterEventCallbackL(ERtpAnyEvent,
       
   728 										RTPCallbackL,
       
   729 										this);
       
   730 	}
       
   731 	
       
   732 TInt CActiveStreamer::LoadFile()
       
   733 	{
       
   734 	RDebug::Printf("Loading file");
       
   735 	delete iFileBuf;
       
   736 	iFileBuf = NULL;
       
   737 	
       
   738 	TInt err = KErrNone;
       
   739 
       
   740 	if (iPreloadFile)
       
   741 		{
       
   742 		if (iStreamingInfoConsole)
       
   743 			{
       
   744 			iStreamingInfoConsole->Printf(_L("Preloading SBC file\n"));
       
   745 			}
       
   746 
       
   747 		// max heap is something or other	
       
   748 		const TInt KMaxHeap = 4000000;
       
   749 		TInt size = iFileSize;
       
   750 		size = Min(iFileSize, KMaxHeap);
       
   751 		TRAP(err, iFileBuf = HBufC8::NewL(size));	
       
   752 		if (err)
       
   753 			{
       
   754 			return err;
       
   755 			}
       
   756 		iFileSize = Min(KMaxHeap, iFileSize);
       
   757 	
       
   758 		TPtr8 ptr(const_cast<TUint8*>(iFileBuf->Des().Ptr()), 0, iFileSize);	
       
   759 	
       
   760 		const TEntry& entry = iFiles->operator[](iCurrentFile);
       
   761 		RFile test;
       
   762 		test.Open(iRFs, entry.iName, EFileRead);
       
   763 		
       
   764 		ptr.Zero();
       
   765 		err=iFile.Read(ptr);
       
   766 		}
       
   767 	else
       
   768 		{
       
   769 		if (iStreamingInfoConsole)
       
   770 			{
       
   771 			iStreamingInfoConsole->Printf(_L("Streaming from file\n"));
       
   772 			}
       
   773 		
       
   774 		// read from file to be more "streaming"-like
       
   775 		TRAP(err, iFileBuf = HBufC8::NewL(Min(iFileSize, iSBCFrameBytesPerRTP)));
       
   776 		}
       
   777 	return err;
       
   778 	}
       
   779 
       
   780 void CActiveStreamer::Faster()
       
   781 	{
       
   782 	// limit the speed
       
   783 	if (iSbcFrameRate < 5)
       
   784 		{
       
   785 		iSbcFrameRate++;
       
   786 		}
       
   787 	}
       
   788 	
       
   789 void CActiveStreamer::Slower()
       
   790 	{
       
   791 	if (iSbcFrameRate > 1)
       
   792 		{
       
   793 		iSbcFrameRate--;		
       
   794 		}
       
   795 	}
       
   796 
       
   797 void CActiveStreamer::Backward()
       
   798 	{
       
   799 	iDirectionForward=EFalse;
       
   800 	}
       
   801 
       
   802 void CActiveStreamer::Forward()
       
   803 	{
       
   804 	iDirectionForward=ETrue;
       
   805 	}
       
   806 
       
   807 void CActiveStreamer::CheckJammed()
       
   808 	{
       
   809 	if (iFillLevel==iPreviousFillLevel)
       
   810 		{
       
   811 		if ((iBucketAppearsJammed++ > 500) && iStreamingInfoConsole)
       
   812 			{
       
   813 			iStreamingInfoConsole->Printf(_L("BUCKET JAMMED\n"));
       
   814 			iStreamingInfoConsole->Printf(_L("iFillLevel %d "),iFillLevel);
       
   815 			iStreamingInfoConsole->Printf(_L("iRTPCanSend %d "),iRTPCanSend);
       
   816 			iStreamingInfoConsole->Printf(_L("iFailedSend %d "),iFailedSend);
       
   817 			iStreamingInfoConsole->Printf(_L("iPos %d "),iPos);
       
   818 	
       
   819 			TTime now;
       
   820 			now.UniversalTime();
       
   821 			
       
   822 			TInt millisecs = now.MicroSecondsFrom(iLastPacketSentTime).Int64()/1000;
       
   823 			iStreamingInfoConsole->Printf(_L("time since last send %d ms "),millisecs);
       
   824 			}
       
   825 		}
       
   826 	else
       
   827 		{
       
   828 		iBucketAppearsJammed = 0;
       
   829 		}
       
   830 	}