Exemple #1
0
int qAnimationDlg::countFrames(size_t startIndex/*=0*/)
{
	//reset the interpolators and count the total number of frames
	int totalFrameCount = 0;
	{
		double fps = fpsSpinBox->value();

		size_t vp1 = startIndex;
		size_t vp2 = vp1+1;

		while (getNextSegment(vp1, vp2))
		{
			const Step& currentStep = m_videoSteps[vp1];
			int frameCount = static_cast<int>( fps * currentStep.duration_sec );
			totalFrameCount += frameCount;

			//take care of the 'loop' case
			if (vp2 == 0)
			{
				assert(loopCheckBox->isChecked());
				break;
			}
			vp1 = vp2;
		}
	}

	return totalFrameCount;
}
Exemple #2
0
void qAnimationDlg::onTotalTimeChanged(double newTime_sec)
{
	double previousTime_sec = computeTotalTime();
	if (previousTime_sec != newTime_sec)
	{
		assert(previousTime_sec != 0);
		double scale = newTime_sec / previousTime_sec;

		size_t vp1 = 0, vp2 = 0;
		while (getNextSegment(vp1, vp2))
		{
			assert(vp1 < stepSelectionList->count());
			m_videoSteps[vp1].duration_sec *= scale;

			if (vp2 == 0)
			{
				//loop case
				break;
			}
			vp1 = vp2;
		}

		//update current step
		updateCurrentStepDuration();
	}
}
void
FDL_algorithm_curvature::segment_FeatureMapBased_Recursive_SingleStreamline( FDL_streamline *streamline  )
{
	assert( streamline != NULL );
	
	// Get the trace and trace length of the streamline
	int totalTraceLength = streamline->getLength();
	VECTOR3* totalTrace = new VECTOR3[totalTraceLength];
	streamline->getTotalTrace( totalTrace );

	// Get pointer to the featuremap of the streamline
	FDL_featuremap featureMap = streamline->getFeatureMap();
	
	// This function assumes that the streamline already has a valid computed feature map
	//assert( featureMap != NULL );
	assert( featureMap.getNumSegments() > 0 );
	
	// Clear segment list
	streamline->featureBasedSegmentList.clear();

	// Sort all segments in feature map in increasing order of start point (and then decreasing order of score)
	list<SLSegment> tempList = featureMap.hierarchicalSegmentList;
	tempList.sort( Segment::compare_Segment_Start_Score2 ); 
	
	// Create a shorter list containing ONLY the highest scoring segment from each streamline
	list<SLSegment> highScoreSegmentsList;
	int laststart = -1;
	for( list<SLSegment>::const_iterator pcIter1 = tempList.begin(); pcIter1 != tempList.end(); pcIter1++ )
	{
		if( (*pcIter1).start != laststart ) 
		{
			highScoreSegmentsList.push_back( *pcIter1 );
			laststart = (*pcIter1).start;
		}
	}	
	
	#ifdef DEBUG_MODE
	fprintf( stderr, "printing highest scoring segment at each starting point of the feature map ...\n" );
	Segment::printSegmentList( highScoreSegmentsList );
	#endif	

	// Recursive call to include segments from start to end
	SLSegment matchFullStreamline = featureMap.filter_Segment_Start_Length( 0, totalTraceLength );
	getNextSegment( streamline, highScoreSegmentsList, matchFullStreamline, totalTraceLength );

	// Sort all segments of the output segment list based on start point 
	streamline->featureBasedSegmentList.sort( Segment::compare_Segment_Start_Score2 ); 

	#ifdef DEBUG_MODE
	fprintf( stderr, "printing results of segmentation based on feature map ...\n" );
	Segment::printSegmentList( streamline->featureBasedSegmentList );
	#endif

}// end function
Exemple #4
0
double qAnimationDlg::computeTotalTime()
{
	double totalDuration_sec = 0;
	size_t vp1 = 0, vp2 = 0;
	while (getNextSegment(vp1, vp2))
	{
		assert(vp1 < stepSelectionList->count());
		totalDuration_sec += m_videoSteps[static_cast<int>(vp1)].duration_sec;
		if (vp2 == 0)
		{
			//loop case
			break;
		}
		vp1 = vp2;
	}

	return totalDuration_sec;
}
Exemple #5
0
void
MHL7Compare::compareHL7()
{
  MString segExist, segNew;

  int rExist = getFirstSegment(mMsgExist, segExist);
  if (!rExist)
  {
    cout << "Cannot access the first segment of the existing message" << endl;
    return;
  }

  int rNew = getFirstSegment(mMsgNew, segNew);
  if (!rNew)
  {
    cout << "MHL7Compare: Cannot access the first segment of the new message" << endl;
    return;
  }

  if (mSegInfo.empty())
  {
    // no initialize file was provided.
    // Compare all the fields of all the segments
    do
    {
      if (segExist != segNew)
      {
        cout << "MHL7Compare: segments not in proper order" << endl;
        DIFF diff;
        diff.fldNum = 0;
        diff.existValue = segExist;
        diff.newValue = segNew;
        diff.comment = "Segment order does not match";
        mDiff.insert (MDiff::value_type (segExist, diff) );
        mCount++;
        break;
      } // endif

      //cout << "Comparing segments: " << segExist << " " << segNew << endl;
      char *name = segNew.strData();

      if (!strcmp(name, "MSH"))
        compareMesgHeaders();
      else if (!strcmp(name, "EVN"))
        compareEVNs();
      else
        compareFields(segExist);  // applies to any segment

      rExist = getNextSegment(mMsgExist, segExist);
      rNew = getNextSegment(mMsgNew, segNew);
      if (rExist != rNew)
      {
        cout << "MHL7Compare: One message is shorter than the other" << endl;
        DIFF diff;
        diff.fldNum = 0;
        diff.existValue = segExist;
        diff.newValue = segNew;
        diff.comment = "One message is shorter than the other";
        mDiff.insert (MDiff::value_type (segExist, diff) );
        mCount++;
      }
    }
    while (rExist && rNew);
  } // endif mSegInfo.empty()
  else
  {
    for (MSegmentInfo::iterator i = mSegInfo.begin(); i != mSegInfo.end(); i++)
    {
      segExist = (*i).first;

      // Go to beginning of message, and restart search.
      rNew = getFirstSegment(mMsgNew, segNew);
      rExist = getFirstSegment(mMsgExist, segNew);
      if (segNew != segExist) {
	segNew = segExist;
	rExist = findSegment(mMsgExist, segExist);
	rNew = findSegment(mMsgNew, segNew);
      }

      // Check all instances of segExist in mMsgExist and mMsgNew
      // Note: if a segment mentioned in the .ini file does not
      // exist in the existing file, there is no error. 
      while(rExist || rNew)
      {
	// If a segment is not found in the new message, that exists in the
        // existing file, generate a difference.
        if (rExist && !rNew)
        {
          DIFF diff;
          diff.fldNum = 0;
          diff.existValue = segExist;
          diff.newValue = segNew;
          diff.comment = "New message is missing this segment";
          mDiff.insert (MDiff::value_type (segExist, diff) );
          mCount++;
	  rNew = rExist = false;
          continue;
        }

	// If a segment exists in the new message, but not in the existing,
	// then generate an appropriate difference.
	if (!rExist && rNew)
	{
	  DIFF diff;
	  diff.fldNum = 0;
	  diff.existValue = segExist;
	  diff.newValue = segNew;
	  diff.comment = "New message has too many segments of this type";
	  mDiff.insert (MDiff::value_type (segExist, diff) );
	  mCount++;
	  rNew = rExist = false;
	  continue;
	}
	  
        // Find the difference(s) within existing segments
        compareFieldValues(segExist,
                         ((*i).second).fldNum,
                         ((*i).second).compNum,
                         ((*i).second).subCompNum
                        );

	rExist = findSegment(mMsgExist, segExist);
	rNew = findSegment(mMsgNew, segExist);

      } // endwhile

    } // endfor
  } // endelse mSegInfo.empty()
}
Exemple #6
0
/*
Name:tftp12ParseOACKPkt
function:Parse an OACK packet
input: pktDescriptor
output: option number
packet format:
    2       n      1     n      1                                n      1      n     1
+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+---------+---+---~~---+---+
|  opc  |  opt1  | 0 | value1 | 0 |          ......             optN  | 0 | valueN | 0 |
+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+---------+---+---~~---+---+
 6-OACK
*/
INT32 tftp12ParseOACKPkt(TFTP12Description *pktDescriptor)
{
	/*解析得到的option值会更新原始值,如果对端不支持option则清空相应字段的值*/
	INT32 preStringLength = 2;
    UINT8 argNum = 0;  /*在解析一个字段之前已解析的字段长度*/
	UINT8 *currentString = 0;	/*指向当前被分割出的字符串*/

	/*提取opcode:6,没必要再进行此操作,进此函数代表已知道opcode*/
	#if 0
    *((UINT8 *)pktDescriptor->buffer);
    *((UINT8 *)pktDescriptor->buffer+1);
	#endif

	currentString = (UINT8 *)pktDescriptor->recvBuffer;
	currentString = currentString + 2;	/*跳过opcode*/

	/*协商option过程中,收到对方的OACK数据包后更新值,更新前先清0,此处有问题*/
//	pktDescriptor->option.blockSize = 0;
//	pktDescriptor->option.timeout = 0;
//	pktDescriptor->option.tsize = 0;

	while (*(currentString) != '\0')   /*更改结束条件*/
	{
		argNum++;
		strlwr(currentString);		/*转化为小写*/

		#if DEBUG
		printf("tftp12ParseOACKPkt解析到的option为:%s\n", currentString);
		printf("strnicmp(currentString, \"blkSize\", strlen(\"blkSize\") = %d\n", strnicmp(currentString, "blkSize", strlen("blkSize")));
		#endif

		if (strnicmp(currentString, "blkSize", strlen("blkSize")) == 0)
		{
		    printf("匹配到blkSize!\n");
			getNextSegment(&currentString, &preStringLength);   /*第二个参数暂未使用*/
			pktDescriptor->option.blockSize = atoi(currentString);	/*最大为INT32,有问题,如果发过来为空、负数和0怎么处理*/

			#if DEBUG
			printf("tftp12ParseOACKPkt解析到的blocksize=%s\n", currentString);
			printf("tftp12ParseOACKPkt解析到的pktDescriptor->option.blocksize=%d\n", pktDescriptor->option.blockSize);
			#endif
		}
		else if (strnicmp(currentString, "timeout", strlen("timeout")) == 0)
		{
			getNextSegment(&currentString, &preStringLength);
			pktDescriptor->option.timeout = atoi(currentString);	/*最大为INT32*/

			#if DEBUG
			printf("tftp12ParseOACKPkt解析到的timeout=%s\n", currentString);
			printf("tftp12ParseOACKPkt解析到的pktDescriptor->option.timeout=%d\n", pktDescriptor->option.timeout);
			#endif
		}
		else if (strnicmp(currentString, "tSize", strlen("tSize")) == 0)
		{
			getNextSegment(&currentString, &preStringLength);
			pktDescriptor->option.tsize = atoi(currentString);	/*最大为INT32*/

			#if DEBUG
			printf("pktDescriptor->option.tsize的地址为:%x\n", &pktDescriptor->option.tsize);
			printf("tftp12ParseOACKPkt解析到的tsize=%s\n", currentString);
			printf("tftp12ParseOACKPkt解析到的pktDescriptor->option.tsize=%d\n", pktDescriptor->option.tsize);
			#endif
		}
		else
			;	/*不明字符串未做处理*/

		getNextSegment(&currentString, &preStringLength);
	}
	//getchar();

	return argNum;
}
Exemple #7
0
/*
Name:tftp12ParseREQPkt
function:Parse a request packet
input: pktDescriptor
output: packet length
packet format:
    2       n      1     n      1     n      1      n     1      n      1      n     1
+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+---------+---+---~~---+---+
|  opc  |filename| 0 |  mode  | 0 |  opt1  | 0 | value1 | 0 |   optN  | 0 | valueN | 0 |
+-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+---------+---+---~~---+---+
1-Read/2-Write   netascii/octet/mail  blockSize               timeout                  tsize
*/
INT32 tftp12ParseREQPkt(TFTP12Description *pktDescriptor)
{
	UINT8 *currentString = 0;
	INT32 preStringLength = 2;

    /*提取opcode,服务器根据此值取反,R->W,W->R*/
    pktDescriptor->opCode = *((UINT8 *)pktDescriptor->buffer);
    pktDescriptor->opCode = (pktDescriptor->opCode << 8) ^ *((UINT8 *)pktDescriptor->buffer+1);

	#if DEBUG
	printf("tftp12ParseREQPkt提取到的opCode=%d\n", pktDescriptor->opCode);
	#endif

	/*提取fileName,考虑到操作系统对大小写敏感性,文件名未进行大小写转换*/
	currentString = (UINT8 *)pktDescriptor->buffer + preStringLength;

    #if DEBUG
	printf("tftp12ParseREQPkt提取到的currentString=%s\n", currentString);
	#endif
	printf("length = %d\n", strlen(currentString));

	pktDescriptor->filename = (UINT8 *)malloc(strlen(currentString) + 1);
	memset(pktDescriptor->filename, 0, strlen(currentString) + 1);			/*清空*/
	strncpy(pktDescriptor->filename, currentString, strlen(currentString));		/*注意filename存储空间的申请和释放*/

	#if DEBUG
	printf("tftp12ParseREQPkt提取到的filename=%s\n", pktDescriptor->filename);
	#endif

	/*提取mode*/

    getNextSegment(&currentString, &preStringLength);       /*指向下一个字段*/
	pktDescriptor->mode = (UINT8 *)malloc(currentString + 1);
	memset(pktDescriptor->mode, 0, strlen(currentString) + 1);
	strncpy(pktDescriptor->mode, currentString, strlen(currentString));
	strlwr(pktDescriptor->mode);	/*转化为小写字符*/

	#if DEBUG
	printf("tftp12ParseREQPkt提取到的mode=%s\n", pktDescriptor->mode);
	#endif

    /*循环提取option选项*/
    getNextSegment(&currentString, &preStringLength);     /*指向下一个字段,字段之间只能一个\0分割,如果有多个会出现解析错误*/
	while (preStringLength < 511)   /*限制位置*/
	{
		strlwr(currentString);

		#if DEBUG
		if (strlen(currentString) >0)
            printf("tftp12ParseREQPkt提取到的option=%s\n", currentString);
		#endif

		if (strnicmp(currentString, "blocksize", strlen("blocksize")) == 0)
		{
		    /*
			preStringLength += strlen(currentString) + 1;
			currentString = (UINT8 *)pktDescriptor->buffer + preStringLength;
			*/
            getNextSegment(&currentString, &preStringLength);   /*使用getNextSegment来代替了上述操作*/
			pktDescriptor->option.blockSize = atoi(currentString);	/*最大为INT32,有问题,如果发过来为空、负数和0怎么处理*/


			#if DEBUG
			printf("tftp12ParseREQPkt提取到的blocksize=%s\n", currentString);
			printf("tftp12ParseREQPkt提取到的pktDescriptor->option.blocksize=%d\n", pktDescriptor->option.blockSize);
			#endif
		}
		else if (strnicmp(currentString, "timeout", strlen("timeout")) == 0)
		{
			getNextSegment(&currentString, &preStringLength);

			pktDescriptor->option.timeout = atoi(currentString);	/*最大为INT32*/

			#if DEBUG
			printf("tftp12ParseREQPkt提取到的timeout=%s\n", currentString);
			printf("tftp12ParseREQPkt提取到的pktDescriptor->option.timeout=%d\n", pktDescriptor->option.timeout);
			#endif
		}
		else if (strnicmp(currentString, "tsize", strlen("tsize")) == 0)
		{
			getNextSegment(&currentString, &preStringLength);

			pktDescriptor->option.tsize = atoi(currentString);	/*最大为INT32*/

			#if DEBUG
			printf("tftp12ParseREQPkt提取到的tsize=%s\n", currentString);
			printf("tftp12ParseREQPkt提取到的pktDescriptor->option.tsize=%d\n", pktDescriptor->option.tsize);
			#endif
		}
		else
			;	/*不明字符串未做处理*/
        getNextSegment(&currentString, &preStringLength);
	}

    return 0;	/*暂时未定义返回值*/
}
Exemple #8
0
/**
 * Media group segment downloader loop
 *
 * @param pSession - pointer to the HLS session
 * @param mediaGroupIdx - array index of the group in currentMediaGroup
 *
 * @return #hlsStatus_t
 */
hlsStatus_t hlsGrpSegDwnldLoop(hlsSession_t* pSession,
                               int mediaGroupIdx)
{
   hlsStatus_t status = HLS_OK;

   int pthread_status = 0;

   hlsPlaylist_t* pMediaPlaylist = NULL;

   hlsSegment_t* pSegment = NULL;
   hlsSegment_t* pSegmentCopy = NULL;

   int proposedBitrateIndex = 0;
   struct timespec wakeTime;
   llStatus_t llerror = LL_OK;
   playbackControllerSignal_t* pSignal = NULL;
   struct timespec oldLastBitrateChange;
   srcPlayerMode_t playerMode;

   TIMESTAMP(DBG_INFO, "Starting %s - Media group: %s",
         __FUNCTION__, pSession->pCurrentGroup[mediaGroupIdx]->groupID);

   if(pSession == NULL)
   {
      ERROR("invalid parameter: psession");
      return HLS_INVALID_PARAMETER;
   }
   if(mediaGroupIdx >= pSession->currentGroupCount)
   {
      ERROR("invalid parameter: mediaGroupIdx");
      return HLS_INVALID_PARAMETER;
   }

   do
   {
      pMediaPlaylist = pSession->pCurrentGroup[mediaGroupIdx]->pPlaylist;

      /* Allocate a segment to keep a local copy of segment information */
      pSegmentCopy = newHlsSegment();
      if(pSegmentCopy == NULL)
      {
         ERROR("newHlsSegment() failed");
         status = HLS_MEMORY_ERROR;
         break;
      }

      while(status == HLS_OK)
      {
         /* If the downloader was signalled to exit, return HLS_CANCELLED */
         if(pSession->bKillDownloader)
         {
            DEBUG(DBG_WARN, "downloader signalled to stop");
            status = HLS_CANCELLED;
            break;
         }

         /* Get current time */
         if(clock_gettime(CLOCK_MONOTONIC, &wakeTime) != 0)
         {
            ERROR("failed to get current time");
            status = HLS_ERROR;
            break;
         }

         /* Get playlist READ lock */
         pthread_rwlock_rdlock(&(pSession->playlistRWLock));

         /* Get the next segment */
         status = getNextSegment(pMediaPlaylist, &pSegment);
         if(status != HLS_OK)
         {
            ERROR("failed to find next segment");
            /* Release playlist lock */
            pthread_rwlock_unlock(&(pSession->playlistRWLock));
            break;
         }

         /* Did we get a valid segment? */
         if(pSegment != NULL)
         {
            /* Make a local copy of the segment */
            status = copyHlsSegment(pSegment, pSegmentCopy);
            if(status != HLS_OK)
            {
               ERROR("failed to make local segment copy");
               /* Release playlist lock */
               pthread_rwlock_unlock(&(pSession->playlistRWLock));
               break;
            }

            /* Prepend the playlist's baseURL, if necessary */
            status = createFullURL(&(pSegmentCopy->URL), pMediaPlaylist->baseURL);
            if(status != HLS_OK)
            {
               ERROR("error creating full URL");
               /* Release playlist lock */
               pthread_rwlock_unlock(&(pSession->playlistRWLock));
               break;
            }

            /* We no longer need a reference to the parsed segment */
            pSegment = NULL;

            /* Release playlist lock */
            pthread_rwlock_unlock(&(pSession->playlistRWLock));

            /* Determine the player mode based on speed */
            if(pSession->speed == 0.0)
            {
               playerMode = SRC_PLAYER_MODE_PAUSE;
            }
            else
            {
               playerMode = SRC_PLAYER_MODE_NORMAL;
            }

            status = hlsDwnldThreadsSync(pSession, mediaGroupIdx, pMediaPlaylist, pSegmentCopy);
            if(HLS_OK != status)
            {
               break;
            }

            status = downloadAndPushSegment(pSession, pSegmentCopy, wakeTime, playerMode,
                                            SRC_STREAM_NUM_MAIN + mediaGroupIdx + 1);
            if(status != HLS_OK)
            {
               if(status == HLS_CANCELLED)
               {
                  DEBUG(DBG_WARN, "downloader signalled to stop");
                  break;
               }
               else
               {
                  ERROR("Failed to download segment");
                  break;
               }
            }
         }
         else
         {
            /* If we aren't playing then we never even got the first segment, so quit */
            if(pSession->state != HLS_PLAYING)
            {
               ERROR("failed to get first segment");
               status = HLS_ERROR;
               /* Release playlist lock */
               pthread_rwlock_unlock(&(pSession->playlistRWLock));
               break;
            }

            if(!pMediaPlaylist->pMediaData->bHaveCompletePlaylist) /* Live stream */
            {
               /* Release playlist lock */
               pthread_rwlock_unlock(&(pSession->playlistRWLock));

               /* If we didn't get a segment we've hit EOS */
               DEBUG(DBG_NOISE,"EOS -- no more segments in live playlist");

               /* If we have hit EOS on a live stream, then we just need
                  to wait for the playlist to update with new segments */

               /* Lock the downloader wake mutex */
               if(pthread_mutex_lock(&(pSession->downloaderWakeMutex)) != 0)
               {
                  ERROR("failed to lock downloader wake mutex");
                  status = HLS_ERROR;
                  break;
               }

               /* Wait for LOOP_SECS before going again */
               wakeTime.tv_sec += DOWNLOADER_LOOP_SECS;

               DEBUG(DBG_NOISE,"sleeping %d seconds until %d", (int)DOWNLOADER_LOOP_SECS, (int)wakeTime.tv_sec);

               /* Wait until wakeTime */
               pthread_status = PTHREAD_COND_TIMEDWAIT(&(pSession->downloaderWakeCond), &(pSession->downloaderWakeMutex), &wakeTime);

               /* Unlock the downloader wake mutex */
               if(pthread_mutex_unlock(&(pSession->downloaderWakeMutex)) != 0)
               {
                  ERROR("failed to unlock downloader wake mutex");
                  status = HLS_ERROR;
                  break;
               }

               /* If the timedwait call failed we need to bail */
               if((pthread_status != ETIMEDOUT) && (pthread_status != 0))
               {
                  ERROR("failed to timedwait on the downloader wake condition");
                  status = HLS_ERROR;
                  break;
               }
            }
            else /* VOD stream */
            {
               /* Release playlist lock */
               pthread_rwlock_unlock(&(pSession->playlistRWLock));

               DEBUG(DBG_INFO,"EOF(VOD) - Media Group %s download loop", pSession->pCurrentGroup[mediaGroupIdx]->groupID);

               /* Allocate a new playback controller signal */
               pSignal = malloc(sizeof(playbackControllerSignal_t));
               if(pSignal == NULL)
               {
                   ERROR("malloc error");
                   status = HLS_MEMORY_ERROR;
                   break;
               }

               *pSignal = PBC_DOWNLOAD_COMPLETE;

               /* Push the message to the playback controller message queue */
               llerror = pushMsg(pSession->playbackControllerMsgQueue, (void*)pSignal);
               if(llerror != LL_OK)
               {
                  ERROR("failed to signal the playback controller");
                  free(pSignal);
                  status = HLS_ERROR;
                  break;
               }

               /* Release reference to signal -- playback controller will free */
               pSignal = NULL;

               break;
            }
         }

         /* Make sure we're still in a valid state */
         if(pSession->state == HLS_INVALID_STATE)
         {
            status = HLS_STATE_ERROR;
            break;
         }
      }
      if(status != HLS_OK)
      {
         break;
      }

   } while (0);

   /* Clean up */
   freeSegment(pSegmentCopy);

   return status;
}
Exemple #9
0
hlsStatus_t hlsSegmentDownloadLoop(hlsSession_t* pSession)
{
    hlsStatus_t status = HLS_OK;

    int pthread_status = 0;

    hlsPlaylist_t* pMediaPlaylist = NULL;
    hlsSegment_t* pSegment = NULL;

    hlsSegment_t* pSegmentCopy = NULL;

    int proposedBitrateIndex = 0;
    struct timespec wakeTime;
    llStatus_t llerror = LL_OK;
    playbackControllerSignal_t* pSignal = NULL;
    struct timespec oldLastBitrateChange;
    srcPlayerMode_t playerMode;



    if(pSession == NULL)
    {
        ERROR("invalid parameter");
        return HLS_INVALID_PARAMETER;
    }

    TIMESTAMP(DBG_INFO, "Starting %s", __FUNCTION__);

    do
    {
        /* Allocate a segment to keep a local copy of segment information */
        pSegmentCopy = newHlsSegment();
        if(pSegmentCopy == NULL)
        {
            ERROR("newHlsSegment() failed");
            status = HLS_MEMORY_ERROR;
            break;
        }

        while(status == HLS_OK)
        {
            /* If the downloader was signalled to exit, return HLS_CANCELLED */
            if(pSession->bKillDownloader)
            {
                DEBUG(DBG_WARN, "downloader signalled to stop");
                status = HLS_CANCELLED;
                break;
            }

            /* Get current time */
            if(clock_gettime(CLOCK_MONOTONIC, &wakeTime) != 0)
            {
                ERROR("failed to get current time");
                status = HLS_ERROR;
                break;
            }

            /* Get playlist READ lock */
            pthread_rwlock_rdlock(&(pSession->playlistRWLock));

            /* Get the current playlist */
            pMediaPlaylist = pSession->pCurrentPlaylist;
            if((pMediaPlaylist == NULL) ||
               (pMediaPlaylist->type != PL_MEDIA) ||
               (pMediaPlaylist->pMediaData == NULL))
            {
                ERROR("invalid playlist for playback");
                status = HLS_ERROR;
                /* Release playlist lock */
                pthread_rwlock_unlock(&(pSession->playlistRWLock));
                break;
            }

            /* Get the next segment */
            // GET NEXT SEGMENT SHOULD LOAD UP THE DECRYPTION INFOMATION RMS
            status = getNextSegment(pMediaPlaylist, &pSegment);
            if(status != HLS_OK)
            {
                ERROR("failed to find next segment");
                /* Release playlist lock */
                pthread_rwlock_unlock(&(pSession->playlistRWLock));
                break;
            }

            /* Did we get a valid segment? */
            if(pSegment != NULL)
            {
                /* Make a local copy of the segment */
                status = copyHlsSegment(pSegment, pSegmentCopy);
                if(status != HLS_OK)
                {
                    ERROR("failed to make local segment copy");
                    /* Release playlist lock */
                    pthread_rwlock_unlock(&(pSession->playlistRWLock));
                    break;
                }

                /* Prepend the playlist's baseURL, if necessary */
                status = createFullURL(&(pSegmentCopy->URL), pMediaPlaylist->baseURL);
                if(status != HLS_OK)
                {
                    ERROR("error creating full URL");
                    /* Release playlist lock */
                    pthread_rwlock_unlock(&(pSession->playlistRWLock));
                    break;
                }
                // here is the segment, if it's encrypted we need to attach
                // some decryption infomation here.

                //
                // RMS RETARDED!!!! Key information was in the original pSegment structure
                // but instead of sending that the original author sends a copy.  WTF???
                //

                /* We no longer need a reference to the parsed segment */
                pSegment = NULL;

                /* Release playlist lock */
                pthread_rwlock_unlock(&(pSession->playlistRWLock));

                /* Determine the player mode based on speed */
                if(pSession->speed == 0.0)
                {
                   playerMode = SRC_PLAYER_MODE_PAUSE;
                }
                else
                {
                   playerMode = SRC_PLAYER_MODE_NORMAL;
                }
                status = downloadAndPushSegment(pSession, pSegmentCopy, wakeTime, playerMode,
                                                SRC_STREAM_NUM_MAIN);
                if(status != HLS_OK)
                {
                    if(status == HLS_CANCELLED)
                    {
                        DEBUG(DBG_WARN, "downloader signalled to stop");
                        break;
                    }
                    else
                    {
                        ERROR("Failed to download segment");
                        break;
                    }
                }

                /* timeBuffered is also updated whenever we process a PTS
                   in the playerEvtCallback -- block those callbacks while
                   we update it here */
                pthread_mutex_lock(&(pSession->playerEvtMutex));

                /* Increment our buffer count */
                pSession->timeBuffered += pSegmentCopy->duration;

                /* Unblock the playerEvtCallback */
                pthread_mutex_unlock(&(pSession->playerEvtMutex));

                /* Get playlist WRITE lock */
                pthread_rwlock_wrlock(&(pSession->playlistRWLock));

                // Check if we want to switch bitrate, if we have > 1 variant
                if(pSession->pPlaylist->type == PL_VARIANT)
                {
                    if((pSession->pCurrentProgram != NULL) &&
                       (pSession->pCurrentProgram->pAvailableBitrates != NULL) &&
                       (pSession->pCurrentProgram->pStreams != NULL))
                    {
                        /* Save off pSession->lastBitrateChange in case we fail to shift and need to revert to old values */
                        oldLastBitrateChange.tv_sec = pSession->lastBitrateChange.tv_sec;
                        oldLastBitrateChange.tv_nsec = pSession->lastBitrateChange.tv_nsec;

                        proposedBitrateIndex = abrClientGetNewBitrate(pSession->lastSegmentDldRate, pSession->avgSegmentDldRate, (float)(pSession->timeBuffered),
                                                                      pSession->pCurrentProgram->pStreams->numElements, pSession->pCurrentProgram->pAvailableBitrates,
                                                                      pMediaPlaylist->pMediaData->bitrate, pSession->minBitrate, pSession->maxBitrate,
                                                                      &(pSession->lastBitrateChange), &(pSession->playbackStart));
                        if((proposedBitrateIndex < 0) || (proposedBitrateIndex >= pSession->pCurrentProgram->pStreams->numElements))
                        {
                            // TODO: ??? Anything else?
                            ERROR("Problem with bitrate window (rateMin/rateMax) prevented bitrate switching!");
                        }
                        else
                        {
                            status = changeBitrate(pSession, pSession->pCurrentProgram->pAvailableBitrates[proposedBitrateIndex]);
                            if(status != HLS_OK)
                            {
                                if(status == HLS_DL_ERROR)
                                {
                                    /* If we failed to switch because of a network error, keep going for now and
                                       try switching again on the next go-around. */
                                    DEBUG(DBG_WARN, "problem downloading new playlist for bitrate switch attempt -- will retry");

                                    /* Since we didn't shift bitrates, revert lastBitrateChange to old value (which was overwritten by abrClientGetNewBitrate() */

                                    // TODO: have the plugin update lastBitrateChange instead of the adaptec code?
                                    pSession->lastBitrateChange.tv_sec = oldLastBitrateChange.tv_sec;
                                    pSession->lastBitrateChange.tv_nsec = oldLastBitrateChange.tv_nsec;

                                    status = HLS_OK;
                                }
                                else
                                {
                                    ERROR("failed to change bitrate");
                                    /* Release playlist lock */
                                    pthread_rwlock_unlock(&(pSession->playlistRWLock));
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        ERROR("current program malformed or invalid");
                        status = HLS_ERROR;
                        /* Release playlist lock */
                        pthread_rwlock_unlock(&(pSession->playlistRWLock));
                        break;
                    }
                }
                else
                {
                    DEBUG(DBG_INFO, "Skipped bitrate-switching logic (playlist type is not PL_VARIANT)");
                }

                /* Release playlist lock */
                pthread_rwlock_unlock(&(pSession->playlistRWLock));
            }
            else
            {
                /* If we aren't playing then we never even got the first segment, so quit */
                if(pSession->state != HLS_PLAYING)
                {
                    ERROR("failed to get first segment");
                    status = HLS_ERROR;
                    /* Release playlist lock */
                    pthread_rwlock_unlock(&(pSession->playlistRWLock));
                    break;
                }

                /* Did this happen on a live or a VoD stream? */
                if(pSession->pCurrentPlaylist->pMediaData->bHaveCompletePlaylist) /* VoD stream */
                {
                    /* Release playlist lock */
                    pthread_rwlock_unlock(&(pSession->playlistRWLock));

                    /* If we didn't get a segment we've hit EOF */
                    DEBUG(DBG_NOISE,"EOF -- no more segments in VoD playlist");

                    if(1 != pSession->bKillDownloader)
                    {
                       /* If we've hit EOF on a VoD stream, then the downloader needs to signal the
                          playback controller and exit. The playback controller will monitor the
                          buffer level and signal EOF to the player once timeBuffered reaches 0. */

                       /* Allocate a new playback controller signal */
                       pSignal = malloc(sizeof(playbackControllerSignal_t));
                       if(pSignal == NULL)
                       {
                          ERROR("malloc error");
                          status = HLS_MEMORY_ERROR;
                          break;
                       }

                       *pSignal = PBC_DOWNLOAD_COMPLETE;

                       /* Push the message to the playback controller message queue */
                       llerror = pushMsg(pSession->playbackControllerMsgQueue, (void*)pSignal);
                       if(llerror != LL_OK)
                       {
                          ERROR("failed to signal the playback controller");
                          free(pSignal);
                          status = HLS_ERROR;
                          break;
                       }

                       /* Release reference to signal -- playback controller will free */
                       pSignal = NULL;

                       /* Stop the downloader thread */
                       pSession->bKillDownloader = 1;
                    }
                }
                else /* LIVE stream */
                {
                    /* Release playlist lock */
                    pthread_rwlock_unlock(&(pSession->playlistRWLock));

                    /* If we didn't get a segment we've hit EOS */
                    DEBUG(DBG_NOISE,"EOS -- no more segments in live playlist");

                    /* If we have hit EOS on a live stream, then we just need
                       to wait for the playlist to update with new segments */

                    /* Lock the downloader wake mutex */
                    if(pthread_mutex_lock(&(pSession->downloaderWakeMutex)) != 0)
                    {
                        ERROR("failed to lock downloader wake mutex");
                        status = HLS_ERROR;
                        break;
                    }

                    /* Wait for LOOP_SECS before going again */
                    wakeTime.tv_sec += DOWNLOADER_LOOP_SECS;

                    DEBUG(DBG_NOISE,"sleeping %d seconds until %d", (int)DOWNLOADER_LOOP_SECS, (int)wakeTime.tv_sec);

                    /* Wait until wakeTime */
                    pthread_status = PTHREAD_COND_TIMEDWAIT(&(pSession->downloaderWakeCond), &(pSession->downloaderWakeMutex), &wakeTime);

                    /* Unlock the downloader wake mutex */
                    if(pthread_mutex_unlock(&(pSession->downloaderWakeMutex)) != 0)
                    {
                        ERROR("failed to unlock downloader wake mutex");
                        status = HLS_ERROR;
                        break;
                    }

                    /* If the timedwait call failed we need to bail */
                    if((pthread_status != ETIMEDOUT) && (pthread_status != 0))
                    {
                        ERROR("failed to timedwait on the downloader wake condition");
                        status = HLS_ERROR;
                        break;
                    }
                }
            }

            /* Make sure we're still in a valid state */
            if(pSession->state == HLS_INVALID_STATE)
            {
                status = HLS_STATE_ERROR;
                break;
            }
        }
        if(status != HLS_OK)
        {
            break;
        }

    } while (0);

    /* Clean up */
    freeSegment(pSegmentCopy);

    return status;
}
Exemple #10
0
void qAnimationDlg::render()
{
	if (!m_view3d)
	{
		assert(false);
		return;
	}
	QString outputFilename = outputFileLineEdit->text();

	//save to persistent settings
	{
		QSettings settings;
		settings.beginGroup("qAnimation");
		settings.setValue("filename", outputFilename);
		settings.endGroup();
	}

	setEnabled(false);

	//count the total number of frames
	int frameCount = countFrames(0);
	int fps = fpsSpinBox->value();
	int superRes = superResolutionSpinBox->value();

	//show progress dialog
	QProgressDialog progressDialog(QString("Frames: %1").arg(frameCount), "Cancel", 0, frameCount, this);
	progressDialog.setWindowTitle("Render");
	progressDialog.show();
	QApplication::processEvents();

#ifdef QFFMPEG_SUPPORT
	//get original viewport size
	QSize originalViewSize = m_view3d->size();

	//hack: as the encoder requires that the video dimensions are multiples of 8, we resize the window a little bit...
	{
		//find the nearest multiples of 8
		QSize customSize = originalViewSize;
		if (originalViewSize.width() % 8 || originalViewSize.height() % 8)
		{
			if (originalViewSize.width() % 8)
				customSize.setWidth((originalViewSize.width() / 8 + 1) * 8);
			if (originalViewSize.height() % 8)
				customSize.setHeight((originalViewSize.height() / 8 + 1) * 8);
			m_view3d->resize(customSize);
			QApplication::processEvents();
		}
	}

	int bitrate = bitrateSpinBox->value() * 1024;
	int gop = fps;
	QVideoEncoder encoder(outputFilename, m_view3d->width(), m_view3d->height(), bitrate, gop, static_cast<unsigned>(fpsSpinBox->value()));
	QString errorString;
	if (!encoder.open(&errorString))
	{
		QMessageBox::critical(this, "Error", QString("Failed to open file for output: %1").arg(errorString));
		setEnabled(true);
		return;
	}
#endif

	bool lodWasEnabled = m_view3d->isLODEnabled();
	m_view3d->setLODEnabled(false);

	int frameIndex = 0;
	bool success = true;
	size_t vp1 = 0, vp2 = 0;
	while (getNextSegment(vp1, vp2))
	{
		Step& step1 = m_videoSteps[vp1];
		Step& step2 = m_videoSteps[vp2];

		ViewInterpolate interpolator(step1.viewport, step2.viewport);
		int frameCount = static_cast<int>( fps * step1.duration_sec );
		interpolator.setMaxStep(frameCount);

		cc2DViewportObject current_params;
		while ( interpolator.nextView( current_params ) )
		{
			applyViewport ( &current_params );

			//render to image
			QImage image = m_view3d->renderToImage(superRes, false, false, true );

			if (image.isNull())
			{
				QMessageBox::critical(this, "Error", "Failed to grab the screen!");
				success = false;
				break;
			}

			if (superRes > 1)
			{
				image = image.scaled(image.width()/superRes, image.height()/superRes, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
			}

#ifdef QFFMPEG_SUPPORT
			if (!encoder.encodeImage(image, frameIndex, &errorString))
			{
				QMessageBox::critical(this, "Error", QString("Failed to encode frame #%1: %2").arg(frameIndex+1).arg(errorString));
				success = false;
				break;
			}
#else
			QString filename = QString("frame_%1.png").arg(frameIndex, 6, 10, QChar('0'));
			QString fullPath = QDir(outputFilename).filePath(filename);
			if (!image.save(fullPath))
			{
				QMessageBox::critical(this, "Error", QString("Failed to save frame #%1").arg(frameIndex+1));
				success = false;
				break;
			}
#endif
			++frameIndex;
			progressDialog.setValue(frameIndex);
			QApplication::processEvents();
			if (progressDialog.wasCanceled())
			{
				QMessageBox::warning(this, "Warning", QString("Process has been cancelled"));
				success = false;
				break;
			}
		}

		if (!success)
		{
			break;
		}

		if (vp2 == 0)
		{
			//stop loop here!
			break;
		}
		vp1 = vp2;
	}

	m_view3d->setLODEnabled(lodWasEnabled);

#ifdef QFFMPEG_SUPPORT
	encoder.close();

	//hack: restore original size
	m_view3d->resize(originalViewSize);
	QApplication::processEvents();
#endif
	
	progressDialog.hide();
	QApplication::processEvents();

	if (success)
	{
		QMessageBox::information(this, "Job done", "The animation has been saved successfully");
	}

	setEnabled(true);
}
Exemple #11
0
void qAnimationDlg::preview()
{
	//we'll take the rendering time into account!
	QElapsedTimer timer;
	timer.start();

	setEnabled(false);

	size_t vp1 = previewFromSelectedCheckBox->isChecked() ? static_cast<size_t>(getCurrentStepIndex()) : 0;

	//count the total number of frames
	int frameCount = countFrames(loopCheckBox->isChecked() ? 0 : vp1);
	int fps = fpsSpinBox->value();

	//show progress dialog
	QProgressDialog progressDialog(QString("Frames: %1").arg(frameCount), "Cancel", 0, frameCount, this);
	progressDialog.setWindowTitle("Preview");
	progressDialog.show();
	progressDialog.setModal(true);
	progressDialog.setAutoClose(false);
	QApplication::processEvents();

	assert(stepSelectionList->count() >= m_videoSteps.size());

	int frameIndex = 0;
	size_t vp2 = 0;
	while (getNextSegment(vp1, vp2))
	{
		Step& step1 = m_videoSteps[vp1];
		Step& step2 = m_videoSteps[vp2];

		//theoretical waiting time per frame
		qint64 delay_ms = static_cast<int>(1000 * step1.duration_sec / fps);
		int frameCount = static_cast<int>( fps * step1.duration_sec );

		ViewInterpolate interpolator(step1.viewport, step2.viewport);
		interpolator.setMaxStep(frameCount);
		cc2DViewportObject currentParams;
		while ( interpolator.nextView( currentParams ) )
		{
			timer.restart();
			applyViewport ( &currentParams );
			qint64 dt_ms = timer.elapsed();

			progressDialog.setValue(++frameIndex);
			QApplication::processEvents();
			if (progressDialog.wasCanceled())
			{
				break;
			}

			//remaining time
			if (dt_ms < delay_ms)
			{
				int wait_ms = static_cast<int>(delay_ms - dt_ms);
#if defined(CC_WINDOWS)
				::Sleep( wait_ms );
#else
				usleep( wait_ms * 1000 );
#endif
			}
		}
		if (progressDialog.wasCanceled())
		{
			break;
		}

		if (vp2 == 0)
		{
			assert(loopCheckBox->isChecked());
			frameIndex = 0;
		}
		vp1 = vp2;
	}

	//reset view
	onCurrentStepChanged(getCurrentStepIndex());

	setEnabled(true);
}
int
FDL_algorithm_curvature::getNextSegment( FDL_streamline *streamline,
											   list<SLSegment> tempList, SLSegment segment,
											   int totalLength )
{
	// Get the trace and trace length of the streamline
	int totalTraceLength = streamline->getLength();
	VECTOR3* totalTrace = new VECTOR3[totalTraceLength];
	streamline->getTotalTrace( totalTrace );

	// Pointers to feature map and destination list
	FDL_featuremap featureMap = streamline->getFeatureMap();
	list<SLSegment> *destList = &streamline->featureBasedSegmentList;
	
	//fprintf( stderr, "Recursive call with <start: %d, end: %d, score:%f>\n", segment.start, segment.start+segment.length-1, segment.bcd );
	if( segment.start >= totalLength-1 )
		return ( segment.start + segment.length - 1 );
	
	list<SLSegment>::const_iterator pcIter = tempList.begin();
	int nextstart = 0;
	for(; pcIter != tempList.end(); pcIter++ )
	{
		//fprintf( stderr, "In for loop with <start: %d, end: %d, score:%f>\n", (*pcIter).start, (*pcIter).start+(*pcIter).length-1, (*pcIter).bcd );
		//std::cin.get();
		
		// Skip if the segment in the list has its start point before the segment being examined 
		if( (*pcIter).start < segment.start )
			continue;
		
		// Skip if the segment in the list is same as the segment being examined
		if( (*pcIter).start == segment.start || (*pcIter).length == segment.length  )
			continue;
		
		// If the segment in the list has its start point after the end point of the segment being examined,
		// No more segment in the list needs to be compared with. Return.
		if( (*pcIter).start >= segment.start+segment.length-1 )
		{
			// No sub-segment with higher score was found
			// Add this full segment to the final list
			destList->push_back( segment );
	
			// Return the last point of this segment
			return ( segment.start + segment.length - 1 );
		}
				
		// If a sub-segment has a higher score than the current one, exit the loop and make a recursive call		
		if( (*pcIter).score > segment.score ) 
			break;
	}
		
	if( pcIter == tempList.end() )
	{
		destList->push_back( segment );

		// Return the last point of this segment
		return ( segment.start + segment.length - 1 );		
	}
		
	nextstart = (*pcIter).start;
	
	// Subdivide the segment under study into two 
	// Add the first part which has already been traversed to the final list
	if( nextstart != segment.start )
	{
		SLSegment firstPart = { 0,  segment.start, (*pcIter).start - segment.start + 1,
							curvatureComputer->computeCurvature_SingleStreamline_SingleWindow( &totalTrace[segment.start], (*pcIter).start - segment.start + 1 )  							};
	
		destList->push_back( firstPart );
	}
	
	while( nextstart < segment.start + segment.length - 1 )
	{		
		//fprintf( stderr, "Looking for the highest score segment with <start: %d>\n", nextstart );
		list<SLSegment>::const_iterator pcIter2;
		struct  Segment match;
		for( pcIter2 = tempList.begin(); pcIter2 != tempList.end(); pcIter2++ )
		{
			if( (*pcIter2).start == nextstart )
			{
				match = (*pcIter2);
				break;
			}
			
		}
							
		// Recursive call with remaining portion of the segment
		// Returns the last point upto which the recursion covers
		nextstart = getNextSegment( streamline, tempList, match, totalLength );
		//fprintf( stderr, "returned new start point: %d\n", nextstart );
	}

	// Clear
	delete [] totalTrace;

	// Return the last point of this segment
	return nextstart;
	
}// end function