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; }
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
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; }
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() }
/* 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(¤tString, &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(¤tString, &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(¤tString, &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(¤tString, &preStringLength); } //getchar(); return argNum; }
/* 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(¤tString, &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(¤tString, &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(¤tString, &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(¤tString, &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(¤tString, &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(¤tString, &preStringLength); } return 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; }
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; }
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 ( ¤t_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); }
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 ( ¤tParams ); 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