void FileAccessNetworkClient::_thread_func() { client->set_nodelay(true); while (!quit) { DEBUG_PRINT("SEM WAIT - " + itos(sem->get())); Error err = sem->wait(); DEBUG_TIME("sem_unlock"); //DEBUG_PRINT("semwait returned "+itos(werr)); DEBUG_PRINT("MUTEX LOCK " + itos(lockcount)); DEBUG_PRINT("POPO"); DEBUG_PRINT("PEPE"); lock_mutex(); DEBUG_PRINT("MUTEX PASS"); blockrequest_mutex->lock(); while (block_requests.size()) { put_32(block_requests.front()->get().id); put_32(FileAccessNetwork::COMMAND_READ_BLOCK); put_64(block_requests.front()->get().offset); put_32(block_requests.front()->get().size); block_requests.pop_front(); } blockrequest_mutex->unlock(); DEBUG_PRINT("THREAD ITER"); DEBUG_TIME("sem_read"); int id = get_32(); int response = get_32(); DEBUG_PRINT("GET RESPONSE: " + itos(response)); FileAccessNetwork *fa = NULL; if (response != FileAccessNetwork::RESPONSE_DATA) { ERR_FAIL_COND(!accesses.has(id)); } if (accesses.has(id)) fa = accesses[id]; switch (response) { case FileAccessNetwork::RESPONSE_OPEN: { DEBUG_TIME("sem_open"); int status = get_32(); if (status != OK) { fa->_respond(0, Error(status)); } else { uint64_t len = get_64(); fa->_respond(len, Error(status)); } fa->sem->post(); } break; case FileAccessNetwork::RESPONSE_DATA: { int64_t offset = get_64(); uint32_t len = get_32(); Vector<uint8_t> block; block.resize(len); client->get_data(block.ptr(), len); if (fa) //may have been queued fa->_set_block(offset, block); } break; case FileAccessNetwork::RESPONSE_FILE_EXISTS: { int status = get_32(); fa->exists_modtime = status != 0; fa->sem->post(); } break; case FileAccessNetwork::RESPONSE_GET_MODTIME: { uint64_t status = get_64(); fa->exists_modtime = status; fa->sem->post(); } break; } unlock_mutex(); } }
void wait_mutex() { lock_mutex(); release_mutex(); }
void process_lock(void) { lock_mutex(&thread_mutex); }
/// \brief For add message info, this function is thread safe void DebugEngine::addDebugInformation(const DebugLevel_custom &level,const QString& function,const QString& text,QString file,const int& ligne,const QString& location) { //Remove the compiler extra patch generated file=file.remove(QRegularExpression("\\.\\.?[/\\\\]([^/]+[/\\\\])?")); QString addDebugInformation_lignestring=QString::number(ligne); QString addDebugInformation_fileString=file; if(ligne!=-1) addDebugInformation_fileString+=":"+addDebugInformation_lignestring; //Load the time from start QString addDebugInformation_time = QString::number(startTime.elapsed()); QString addDebugInformation_htmlFormat; switch(level) { case DebugLevel_custom_Information: addDebugInformation_htmlFormat="<tr class=\"Information\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Critical: addDebugInformation_htmlFormat="<tr class=\"Critical\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Warning: addDebugInformation_htmlFormat="<tr class=\"Warning\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Notice: addDebugInformation_htmlFormat="<tr class=\"Notice\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_UserNote: addDebugInformation_htmlFormat="<tr class=\"Note\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; } //To prevent access of string in multi-thread { //Show the text in console QString addDebugInformation_textFormat; addDebugInformation_textFormat = "("+addDebugInformation_time.rightJustified(8,' ')+") "; if(file!="" && ligne!=-1) addDebugInformation_textFormat += file+":"+addDebugInformation_lignestring+":"; addDebugInformation_textFormat += function+"(), (location: "+location+"): "+text; puts(qPrintable(addDebugInformation_textFormat)); QMutexLocker lock_mutex(&mutex); if(currentBackend==File) { if(logFile.size()>64*1024*1024) // greater than 64MB puts("File log greater than 64MB, stop to record it!"); else logFile.write(addDebugInformation_htmlFormat.toUtf8()); } else { if(debugHtmlContent.size()<64*1024*1024) debugHtmlContent+=addDebugInformation_htmlFormat; else puts("String greater than 64MB, stop to record it!"); } ItemOfDebug newItem; newItem.time=addDebugInformation_time; newItem.level=level; newItem.function=function; if(addDebugInformation_lignestring!="-1") newItem.file=file+":"+addDebugInformation_lignestring; else newItem.file=file; newItem.location=location; newItem.text=text; listItemOfDebug << newItem; } //Send the new line if(addDebugInformationCallNumber<ULTRACOPIER_DEBUG_MAX_GUI_LINE) { addDebugInformationCallNumber++; emit newDebugInformation(); } }
void setup_mutex() { hLuaMutex = CreateMutex(NULL,FALSE,NULL); hMutex = CreateMutex(NULL,FALSE,NULL); lock_mutex(); }
static void vlogger(const char *message, va_list args) { FILE *log; # ifdef _NTSERVICE if (!IsNTService && logstdout) log = stdout; # else if (logstdout) log = stdout; # endif else { if (fn_log == NULL) return; # ifndef _WIN32 if (!strcmp(fn_log, "syslog")) { openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER); ////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it vsyslog(LOG_INFO, message, args); closelog(); return; } # endif // _WIN32 log = fopen(fn_log, "a"); if (!log) return; } time_t now = time(0); # ifdef USE_THREADS char mbstr[2048]; # else char mbstr[24]; # endif if (LogDateAndTime) strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X: ", localtime(&now)); else *mbstr = 0; # ifndef USE_THREADS fprintf(log, "%s", mbstr); vfprintf(log, message, args); fflush(log); # else // USE_THREADS // We write everything to a string before we really log inside the critical section // so formatting the output can be concurrent int len = (int)strlen(mbstr); //# if !_MSC_VER vlmcsd_vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args); //# else // wvsprintf(mbstr + len, message, args); //# endif lock_mutex(&logmutex); fprintf(log, "%s", mbstr); fflush(log); unlock_mutex(&logmutex); # endif // USE_THREADS if (log != stdout) fclose(log); }
static void users_lock(void) { lock_mutex(&user_count_mutex); }
bool WriteThread::write(const QByteArray &data) { if(stopIt) return false; bool atMax; if(sequential) { if(stopIt) return false; { QMutexLocker lock_mutex(&accessList); theBlockList.append(data); atMax=(theBlockList.size()>=numberOfBlock); } if(atMax) emit internalStartWrite(); } else { if(stopIt) return false; { QMutexLocker lock_mutex(&accessList); theBlockList.append(data); atMax=(theBlockList.size()>=numberOfBlock); } emit internalStartWrite(); } if(atMax) { writeFullBlocked=true; writeFull.acquire(); writeFullBlocked=false; } if(stopIt) return false; #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT //wait for limitation speed if stop not query if(multiForBigSpeed>0) { if(sequential) { numberOfBlockCopied++; if(numberOfBlockCopied>=(multiForBigSpeed*2)) { numberOfBlockCopied=0; waitNewClockForSpeed.acquire(); } } else { numberOfBlockCopied2++; if(numberOfBlockCopied2>=multiForBigSpeed) { numberOfBlockCopied2=0; waitNewClockForSpeed2.acquire(); } } } #endif if(stopIt) return false; return true; }
void WriteThread::internalWrite() { #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT if(sequential) { multiForBigSpeed=0; QMutexLocker lock_mutex(&accessList); if(theBlockList.size()<numberOfBlock && !endDetected) return; } #endif bool haveBlock; do { if(putInPause) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("[")+QString::number(id)+QStringLiteral("] write put in pause")); if(stopIt) return; pauseMutex.acquire(); if(stopIt) return; } if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] stopIt")); return; } if(stopIt) return; //read one block { QMutexLocker lock_mutex(&accessList); if(theBlockList.isEmpty()) haveBlock=false; else { blockArray=theBlockList.first(); if(multiForBigSpeed>0) { if(blockArray.size()==blockSize) { theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); } else { blockArray.clear(); while(blockArray.size()!=blockSize) { //if larger if(theBlockList.first().size()>blockSize) { blockArray+=theBlockList.first().mid(0,blockSize); theBlockList.first().remove(0,blockSize); if(!sequential) { //do write in loop to finish the actual block emit internalStartWrite(); } break; } //if smaller else { blockArray+=theBlockList.first(); theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); if(theBlockList.isEmpty()) break; } } } haveBlock=!blockArray.isEmpty(); } else { theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); } haveBlock=true; } } if(stopIt) return; if(!haveBlock) { if(sequential) { if(endDetected) internalEndOfFile(); else writeFull.release(); return; } ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] End detected of the file")); return; } #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT //wait for limitation speed if stop not query if(multiForBigSpeed>0) { numberOfBlockCopied++; if(sequential || (!sequential && writeFullBlocked)) { if(numberOfBlockCopied>=(multiForBigSpeed*2)) { numberOfBlockCopied=0; waitNewClockForSpeed.acquire(); if(stopIt) break; } } else { if(numberOfBlockCopied>=multiForBigSpeed) { numberOfBlockCopied=0; waitNewClockForSpeed.acquire(); if(stopIt) break; } } } #endif if(stopIt) return; #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Write; #endif bytesWriten=file.write(blockArray); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif //mutex for stream this data if(lastGoodPosition==0) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] emit writeIsStarted()")); emit writeIsStarted(); } if(stopIt) return; if(file.error()!=QFile::NoError) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error())); errorString_internal=QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error()); stopIt=true; emit error(); return; } if(bytesWriten!=blockArray.size()) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size())); errorString_internal=QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size()); stopIt=true; emit error(); return; } lastGoodPosition+=bytesWriten; } while(sequential); }
CP_HIDDEN void cpi_lock_mutex(cpi_mutex_t *mutex) { assert(mutex != NULL); lock_mutex(mutex->os_mutex); lock_mutex_holding(mutex); unlock_mutex(mutex->os_mutex); }
bool WriteThread::internalOpen() { //do a bug ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] internalOpen destination: ")+file.fileName()); if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); emit closed(); return false; } if(file.isOpen()) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] already open! destination: ")+file.fileName()); return false; } if(file.fileName().isEmpty()) { errorString_internal=tr("Path resolution error (Empty path)"); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Unable to open: %1, error: %2").arg(file.fileName()).arg(errorString_internal)); emit error(); return false; } ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] before the mutex")); //set to LISTBLOCKSIZE if(sequential) { while(writeFull.available()<1) writeFull.release(); if(writeFull.available()>1) writeFull.acquire(writeFull.available()-1); } else { while(writeFull.available()<numberOfBlock) writeFull.release(); if(writeFull.available()>numberOfBlock) writeFull.acquire(writeFull.available()-numberOfBlock); } ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] after the mutex")); stopIt=false; endDetected=false; #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=InodeOperation; #endif //mkpath check if exists and return true if already exists QFileInfo destinationInfo(file); QDir destinationFolder; { mkpathTransfer->acquire(); if(!destinationFolder.exists(destinationInfo.absolutePath())) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Try create the path: %1") .arg(destinationInfo.absolutePath())); if(!destinationFolder.mkpath(destinationInfo.absolutePath())) { if(!destinationFolder.exists(destinationInfo.absolutePath())) { /// \todo do real folder error here errorString_internal="mkpath error on destination"; ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Unable create the folder: %1, error: %2") .arg(destinationInfo.absolutePath()) .arg(errorString_internal)); emit error(); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif mkpathTransfer->release(); return false; } } } mkpathTransfer->release(); } ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] after the mkpath")); if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); emit closed(); return false; } //try open it QIODevice::OpenMode flags=QIODevice::ReadWrite; if(!buffer) flags|=QIODevice::Unbuffered; { QMutexLocker lock_mutex(&writeFileListMutex); if(writeFileList.count(file.fileName(),this)==0) { writeFileList.insert(file.fileName(),this); if(writeFileList.count(file.fileName())>1) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] in waiting because same file is found")); return false; } } } bool fileWasExists=file.exists(); if(file.open(flags)) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] after the open")); { QMutexLocker lock_mutex(&accessList); if(!theBlockList.isEmpty()) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("General file corruption detected")); stopIt=true; file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); return false; } } pauseMutex.tryAcquire(pauseMutex.available()); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] after the pause mutex")); if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); emit closed(); return false; } if(!file.seek(0)) { file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); errorString_internal=file.errorString(); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Unable to seek after open: %1, error: %2").arg(file.fileName()).arg(errorString_internal)); emit error(); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif return false; } if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); emit closed(); return false; } if(!file.resize(startSize)) { file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); errorString_internal=file.errorString(); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Unable to resize to %1 after open: %2, error: %3").arg(startSize).arg(file.fileName()).arg(errorString_internal)); emit error(); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif return false; } if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); file.close(); resumeNotStarted(); file.setFileName(QStringLiteral("")); emit closed(); return false; } isOpen.acquire(); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] emit opened()")); emit opened(); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif needRemoveTheFile=false; postOperationRequested=false; return true; } else { if(!fileWasExists && file.exists()) if(!file.remove()) ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] file created but can't be removed")); if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] close because stopIt is at true")); resumeNotStarted(); file.setFileName(QStringLiteral("")); emit closed(); return false; } errorString_internal=file.errorString(); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Unable to open: %1, error: %2").arg(file.fileName()).arg(errorString_internal)); emit error(); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif return false; } }
static int test_logininfo(void) { syslogin_info_t* info = 0; thread_t* thr = 0; uid_t uid; gid_t gid; int fd[2] = { -1, -1 }; uint8_t buffer[16]; // prepare TEST(0 == pipe2(fd, O_CLOEXEC|O_NONBLOCK)); // == lifetime == for (unsigned entrypos = 0; true; ++entrypos) { setpwent(); for (unsigned i = 0; i < entrypos; ++i) { TEST(0 != getpwent()); } struct passwd* pwd = getpwent(); if (pwd == 0) { TEST(entrypos > 2); // tested at least 2 entries break; } uid = pwd->pw_uid; gid = pwd->pw_gid; // TEST new_syslogininfo: read entries TEST(0 == new_syslogininfo(&info, uid)); TEST(0 != info); TEST(0 < info->size); TEST(uid == info->uid); TEST(1 <= info->nrgroups); TEST(info->nrgroups > info->gmain); TEST(gid == info->gid[info->gmain]); // check memory addr TEST(info->gname == (const char**)(&info[1])); TEST(info->gid == (sys_groupid_t*)((uint8_t*)info->gname + info->nrgroups * sizeof(char*))); TEST(info->uname == (const char*)((uint8_t*)info->gid + info->nrgroups * sizeof(sys_groupid_t))); TEST(info->gname[0] == info->uname + strlen(info->uname) + 1); TEST((uint8_t*)info + info->size == (const uint8_t*)info->gname[info->nrgroups-1] + strlen(info->gname[info->nrgroups-1]) + 1); for (size_t i = 1; i < info->nrgroups; ++i) { TEST(info->gname[i-1] + strlen(info->gname[i-1]) + 1 == info->gname[i]); } // DEBUG printf("user %s(%d) groups ", info->uname, info->uid); // DEBUG for (size_t i = 0; i < info->nrgroups; ++i) { // DEBUG if (i == info->gmain) printf("*"); // DEBUG printf("%s(%d),", info->gname[i], info->gid[i]); // DEBUG } // DEBUG printf("\n"); // TEST delete_syslogininfo TEST(0 != info); TEST(0 == delete_syslogininfo(&info)); TEST(0 == info); TEST(0 == delete_syslogininfo(&info)); TEST(0 == info); } // TEST new_syslogininfo: lock TEST(0 == new_thread(&thr, &thread_initinfo, (void*)(intptr_t)fd[1])); TEST(0 == lock_mutex(&s_syslogininfo_lock)); struct pollfd pfd = { .fd = fd[0], .events = POLLIN }; TEST(1 == poll(&pfd, 1, 10000)); TEST(1 == read(fd[0], buffer, sizeof(buffer))); TEST(EBUSY == tryjoin_thread(thr)); TEST(-1 == read(fd[0], buffer, sizeof(buffer))); TEST(EAGAIN == errno); TEST(0 == unlock_mutex(&s_syslogininfo_lock)); TEST(0 == join_thread(thr)); TEST(0 == returncode_thread(thr)); TEST(0 == delete_thread(&thr)); // TEST new_syslogininfo: ENOENT info = (void*)1; TEST(ENOENT == new_syslogininfo(&info, (uid_t)-2)); TEST((void*)1 == info); info = 0; // == query == // TEST username_syslogininfo syslogin_info_t info2; info2.uname = 0; TEST(0 == username_syslogininfo(&info2)); for (uintptr_t i = 1; i; i <<= 1) { info2.uname = (const char*)i; TEST((const char*)i == username_syslogininfo(&info2)); } // unprepare TEST(0 == close(fd[0])); TEST(0 == close(fd[1])); return 0; ONERR: if (info != (void*)1) { delete_syslogininfo(&info); } close(fd[0]); close(fd[1]); return EINVAL; }
int start_server(const char *url, const char *rtspport) { int mediafd = -1, listenfd, tempfd, maxfd; int videofd; struct addrinfo *info; struct sockaddr_storage remoteaddr; socklen_t addrlen = sizeof remoteaddr; fd_set readfds, masterfds; struct timeval *timeout, *timeind = NULL, timenow; int nready, i; int videosize, videoleft; int recvd, sent; char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE]; unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE]; char *temp; unsigned char *sps = NULL, *pps = NULL; size_t spslen, ppslen; RTSPMsg rtspmsg; Client streamclient; pthread_t threadid; ThreadInfo *tinfo = NULL; uint16_t rtpseqno_video = (rand() % 1000000); uint16_t rtpseqno_audio = (rand() % 1000000); TimeoutEvent *event; /* The current state of the protocol */ int mediastate = IDLE; int quit = 0; int media_downloaded = 0; timeout = (struct timeval *)malloc(sizeof(struct timeval)); init_client(&streamclient); /* Open the a file where the video is to be stored */ if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) { fatal_error("Error opening the temporary videofile"); } /* Create the RTSP listening socket */ resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info); listenfd = server_socket(info); maxfd = listenfd; FD_ZERO(&readfds); FD_ZERO(&masterfds); FD_SET(listenfd, &masterfds); while (!quit) { readfds = masterfds; if ((nready = Select(maxfd + 1, &readfds, timeind)) == -1) { printf("Select interrupted by a signal\n"); } /* Timeout handling, used for packet pacing and other timeouts */ else if (nready == 0) { timeind = NULL; lock_mutex(&queuelock); if ((event = pull_event(&queue)) != NULL) { switch (event->type) { case ENDOFSTREAM: printf("MEDIA FINISHED\n"); break; case FRAME: /* Video frame */ if (event->frame->frametype == VIDEO_FRAME) { rtpseqno_video += send_video_frame(sendbuf, event->frame, streamclient.videofds[0], rtpseqno_video); } /* Audio frame */ else { rtpseqno_audio += send_audio_frame(sendbuf, event->frame, streamclient.audiofds[0], rtpseqno_audio); } free(event->frame->data); free(event->frame); break; case CHECKMEDIASTATE: oma_debug_print("Checking media ready for streaming...\n"); if (mediastate != STREAM) { printf("Sending dummy RTP\n"); send_dummy_rtp(sendbuf, streamclient.videofds[0], &rtpseqno_video); push_timeout(&queue, 1000, CHECKMEDIASTATE); } break; default: oma_debug_print("ERRORENOUS EVENT TYPE!\n"); break; } /* If there are elements left in the queue, calculate next timeout */ if (queue.size > 0) { *timeout = calculate_delta(&event->time, &queue.first->time); timeind = timeout; oma_debug_print("Timeout: %ld secs, %ld usecs\n", timeout->tv_sec, timeout->tv_usec); } else { oma_debug_print("The first entry of the queue is NULL!\n"); } if (queue.size < QUEUESIZE / 2) { oma_debug_print("Signaling thread to start filling the queue"); pthread_cond_signal(&queuecond); } free(event); } unlock_mutex(&queuelock); continue; } /* End of timeout handling */ /* Start to loop through the file descriptors */ for (i = 0; i <= maxfd; i++) { if (FD_ISSET(i, &readfds)) { nready--; /* New connection from a client */ if (i == listenfd) { oma_debug_print("Recieved a new RTSP connection\n"); fflush(stdout); if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) { if (errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EPROTO && errno != EINTR) { fatal_error("accept"); } } /* If we are already serving a client, close the new connection. Otherwise, continue. */ if (streamclient.state != NOCLIENT) { printf("Another RTSP client tried to connect. Sorry, we can only serve one client at a time\n"); close (tempfd); } else { streamclient.rtspfd = tempfd; streamclient.state = CLICONNECTED; maxfd = max(2, streamclient.rtspfd, maxfd); FD_SET(streamclient.rtspfd, &masterfds); } } /* Data from the media source */ else if (i == mediafd) { switch (mediastate) { case GETSENT: /* Read ONLY the HTTP message from the socket and store the video size */ recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK); temp = strstr((char *)msgbuf, "\r\n\r\n"); recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0); printf("Received HTTP response\n%s\n", msgbuf); temp = strstr((char *)msgbuf, "Content-Length:"); sscanf(temp, "Content-Length: %d", &videosize); videoleft = videosize; mediastate = RECVTCP; break; case RECVTCP: if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); oma_debug_print("Socket closed\n"); } oma_debug_print("Received data from video source!\n"); writestr(videofd, msgbuf, recvd); videoleft -= recvd; if (videoleft <= 0) { printf("Video download complete.\n"); FD_CLR(mediafd, &masterfds); close(videofd); close(mediafd); media_downloaded = 1; printf("Media socket closed\n"); /* Create the context and the queue filler thread parameter struct */ tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo)); initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx, &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen); /* Launch the queue filler thread */ CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0); pthread_detach(threadid); /* Send the sprop-parameters before any other frames */ send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0), streamclient.videofds[0], rtpseqno_video++); send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0), streamclient.videofds[0], rtpseqno_video++); g_free(sps); g_free(pps); lock_mutex(&queuelock); push_timeout(&queue, 1000, CHECKMEDIASTATE); unlock_mutex(&queuelock); mediastate = STREAM; } break; case STREAM: /* close(videofd); close(mediafd); close(listenfd); quit = 1; */ break; default: break; } } /* Data from a client ( i == streamclient.rtspfd) */ else { oma_debug_print("Received data from rtspfd\n"); fflush(stdout); if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) { FD_CLR(i, &masterfds); close(i); oma_debug_print("RTSP client closed the connection\n"); streamclient.state = NOCLIENT; } else { oma_debug_print("%s", msgbuf); parse_rtsp(&rtspmsg, msgbuf); } if (rtspmsg.type == TEARDOWN) { /* Kill thread and empty queue */ lock_mutex(&queuelock); pthread_cancel(threadid); empty_queue(&queue); sleep(1); /* Reply with 200 OK */ sent = rtsp_teardown(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); FD_CLR(i, &masterfds); close(i); close(streamclient.videofds[0]); close(streamclient.videofds[1]); close(streamclient.audiofds[0]); close(streamclient.audiofds[1]); printf("Closing AVFormatContext\n"); close_context(tinfo->ctx); free(tinfo); rtpseqno_video = (rand() % 1000000) + 7; rtpseqno_audio = rtpseqno_video + 9; init_client(&streamclient); printf("Closing RTSP client sockets (RTP&RTCP)\n"); streamclient.state = NOCLIENT; unlock_mutex(&queuelock); pthread_cond_signal(&queuecond); } switch (streamclient.state) { case CLICONNECTED: if (rtspmsg.type == OPTIONS) { sent = rtsp_options(&rtspmsg, &streamclient, sendbuf); send_all(i, sendbuf, sent); } else if (rtspmsg.type == DESCRIBE) { if (media_downloaded == 0) { /* Start fetching the file from the server */ parse_url(url, urlhost, urlpath); resolve_host(urlhost, "80", SOCK_STREAM, 0, &info); mediafd = client_socket(info, 0); FD_SET(mediafd, &masterfds); maxfd = max(2, maxfd, mediafd); /* Send the GET message */ http_get(url, msgbuf); send_all(mediafd, msgbuf, strlen((char *)msgbuf)); mediastate = GETSENT; } else { mediastate = STREAM; } /* Send the SDP without sprop-parameter-sets, those are sent * later in-band */ streamclient.state = SDPSENT; sent = rtsp_describe(&streamclient, sendbuf); send_all(i, sendbuf, sent); } break; case SDPSENT: if (rtspmsg.type == SETUP) { streamclient.setupsreceived++; /* Open up the needed ports and bind them locally. The RTCP ports opened here * are not really used by this application. */ write_remote_ip(tempstr, streamclient.rtspfd); oma_debug_print("Remote IP: %s\n", tempstr); if (streamclient.setupsreceived < 2) { resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[0] = client_socket(info, streamclient.server_rtp_audio_port); resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_audio_port); sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf, streamclient.server_rtp_audio_port, streamclient.server_rtcp_audio_port); } else { resolve_host(tempstr, rtspmsg.clirtpport, SOCK_DGRAM, 0, &info); streamclient.videofds[0] = client_socket(info, streamclient.server_rtp_video_port); resolve_host(tempstr, rtspmsg.clirtcpport, SOCK_DGRAM, 0, &info); streamclient.audiofds[1] = client_socket(info, streamclient.server_rtcp_video_port); sent = rtsp_setup(&rtspmsg, &streamclient, sendbuf, streamclient.server_rtp_video_port, streamclient.server_rtcp_video_port); streamclient.state = SETUPCOMPLETE; } oma_debug_print("Sending setup response...\n"); send_all(i, sendbuf, sent); } break; case SETUPCOMPLETE: if (rtspmsg.type == PLAY) { /* Respond to the PLAY request, and start sending dummy RTP packets * to disable the client timeout */ sent = rtsp_play(&rtspmsg, sendbuf); send_all(i, sendbuf, sent); if (media_downloaded == 0) { lock_mutex(&queuelock); push_timeout(&queue, 100, CHECKMEDIASTATE); unlock_mutex(&queuelock); } /* Media has already been once downloaded, initialize context and thread */ else { tinfo = (ThreadInfo *)malloc(sizeof(ThreadInfo)); initialize_context(&tinfo->ctx, "videotemp.mp4", &tinfo->videoIdx, &tinfo->audioIdx, &tinfo->videoRate, &tinfo->audioRate, &sps, &spslen, &pps, &ppslen); /* Launch the queue filler thread */ CHECK((pthread_create(&threadid, NULL, fill_queue, tinfo)) == 0); pthread_detach(threadid); /* Send the sprop-parameters before any other frames */ send_video_frame(sendbuf, create_sprop_frame(sps, spslen, 0), streamclient.videofds[0], rtpseqno_video++); send_video_frame(sendbuf, create_sprop_frame(pps, ppslen, 0), streamclient.videofds[0], rtpseqno_video++); g_free(sps); g_free(pps); /* Dummy timeouts to start queue/timeout mechanism */ push_timeout(&queue, 100, CHECKMEDIASTATE); push_timeout(&queue, 2000, CHECKMEDIASTATE); } } break; default: break; } } } if (nready <= 0) break; } /* Set the timeout value again, since select will mess it up */ lock_mutex(&queuelock); if (queue.size > 0) { CHECK((gettimeofday(&timenow, NULL)) == 0); *timeout = calculate_delta(&timenow, &queue.first->time); /* oma_debug_print("Delta sec: %ld, Delta usec: %ld\n", timeout->tv_sec, timeout->tv_usec); */ if (timeout->tv_sec < 0) { timeout->tv_sec = 0; timeout->tv_usec = 0; } timeind = timeout; } else timeind = NULL; unlock_mutex(&queuelock); } return 1; }
void *fill_queue(void *thread_params) { struct timeval basetime, prev_timestamp; int frametype; int quitflag = 0, mutlocked = 0, timeset = 0; Frame *frame; TimeoutEvent *event; ThreadInfo *tinfo = (ThreadInfo *)thread_params; /* set the cancel type to PTHREAD_CANCEL_ASYNCHRONOUS instead of PTHREAD_CANCEL_DEFERRED to get the thread immediately cancelled */ if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0) { puts("pthread_setcanceltype"); } while (!quitflag) { lock_mutex(&queuelock); pthread_cond_wait(&queuecond, &queuelock); mutlocked = 1; if (!timeset) { CHECK((gettimeofday(&basetime, NULL)) == 0); timeset = 1; } oma_debug_print("Starting to fill the queue...\n"); while (queue.size < QUEUESIZE && !quitflag) { if (!mutlocked) { lock_mutex(&queuelock); } frame = (Frame *)malloc(sizeof(Frame)); oma_debug_print("fill_queue: calling get_frame\n"); /* Get the frame. If none are available, end the loop and the entire function. */ if ((frametype = get_frame(tinfo->ctx, frame, tinfo->videoIdx, tinfo->audioIdx)) == -1) { oma_debug_print("EOF from the media file!\n"); quitflag = 1; /* Notify the server about the EOF */ event = (TimeoutEvent *)malloc(sizeof(TimeoutEvent)); event->frame = NULL; event->type = ENDOFSTREAM; event->time = prev_timestamp; event->time.tv_usec += 10; push_event(event, &queue); } else { frame->frametype = (frametype == tinfo->videoIdx)?VIDEO_FRAME:AUDIO_FRAME; event = (TimeoutEvent *)malloc(sizeof(TimeoutEvent)); event->frame = frame; event->type = FRAME; set_timeval(event, basetime); prev_timestamp = event->time; push_event(event, &queue); } unlock_mutex(&queuelock); mutlocked = 0; usleep(1000); } /* End of inner while loop */ oma_debug_print("The queue is full\n"); } /* End of outer while loop */ pthread_exit(NULL); }
void cgm_lock(void) { lock_mutex(&cgm_mutex); }
/// \brief For add message info, this function is thread safe void DebugEngine::addDebugInformation(const DebugLevel_custom &level,const QString& function,const QString& text,QString file,const int& ligne,const QString& location) { if(DebugEngine::debugEngine==NULL) { qWarning() << "After close: " << function << file << ligne; return; } //Remove the compiler extra patch generated file=file.remove(QRegularExpression("\\.\\.?[/\\\\]([^/]+[/\\\\])?")); QString addDebugInformation_lignestring=QString::number(ligne); QString addDebugInformation_fileString=file; if(ligne!=-1) addDebugInformation_fileString+=":"+addDebugInformation_lignestring; //Load the time from start QString addDebugInformation_time = QString::number(startTime.elapsed()); QString addDebugInformation_htmlFormat; bool important=true; switch(level) { case DebugLevel_custom_Information: addDebugInformation_htmlFormat="<tr class=\"Information\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Critical: addDebugInformation_htmlFormat="<tr class=\"Critical\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Warning: addDebugInformation_htmlFormat="<tr class=\"Warning\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; case DebugLevel_custom_Notice: { addDebugInformation_htmlFormat="<tr class=\"Notice\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; important=false; } break; case DebugLevel_custom_UserNote: addDebugInformation_htmlFormat="<tr class=\"Note\"><td class=\"time\">"+addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n"; break; } //To prevent access of string in multi-thread { //Show the text in console QString addDebugInformation_textFormat; addDebugInformation_textFormat = "("+addDebugInformation_time.rightJustified(8,' ')+") "; if(file!="" && ligne!=-1) addDebugInformation_textFormat += file+":"+addDebugInformation_lignestring+":"; addDebugInformation_textFormat += function+"(), (location: "+location+"): "+text; QMutexLocker lock_mutex(&mutex); if(currentBackend==File) { if(logFile.size()<ULTRACOPIER_DEBUG_MAX_ALL_SIZE*1024*1024 || (important && logFile.size()<ULTRACOPIER_DEBUG_MAX_IMPORTANT_SIZE*1024*1024)) { puts(qPrintable(addDebugInformation_textFormat)); logFile.write(addDebugInformation_htmlFormat.toUtf8()); } } else { if(debugHtmlContent.size()<ULTRACOPIER_DEBUG_MAX_ALL_SIZE*1024*1024 || (important && debugHtmlContent.size()<ULTRACOPIER_DEBUG_MAX_IMPORTANT_SIZE*1024*1024)) { puts(qPrintable(addDebugInformation_textFormat)); debugHtmlContent+=addDebugInformation_htmlFormat; } } //Send the new line if(addDebugInformationCallNumber<ULTRACOPIER_DEBUG_MAX_GUI_LINE) { addDebugInformationCallNumber++; DebugModel::debugModel->addDebugInformation(startTime.elapsed(),level,function,text,file,ligne,location); } } }
void ProcessEncodedFrame(List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, mfxU32 wait=0) { if(!filled_bitstream_waiter.wait_for(2, wait)) return; uint32_t index = 0; { auto lock = lock_mutex(filled_bitstream); index = *filled_bitstream; *filled_bitstream = -1; } encode_task& task = encode_tasks[index]; mfxBitstream& bs = task.bs; List<x264_nal_t> nalOut; mfxU8 *start, *end; { bitstream_info &info = bs_info[index]; bs.TimeStamp = info.time_stamp; bs.DataLength = info.data_length; bs.DataOffset = info.data_offset; bs.PicStruct = info.pic_struct; bs.FrameType = info.frame_type; } start = bs.Data + bs.DataOffset; end = bs.Data + bs.DataOffset + bs.DataLength; const static mfxU8 start_seq[] = {0, 0, 1}; start = std::search(start, end, start_seq, start_seq+3); while(start != end) { decltype(start) next = std::search(start+1, end, start_seq, start_seq+3); x264_nal_t nal; nal.i_ref_idc = start[3]>>5; nal.i_type = start[3]&0x1f; if(nal.i_type == NAL_SLICE_IDR) nal.i_ref_idc = NAL_PRIORITY_HIGHEST; else if(nal.i_type == NAL_SLICE) { switch(bs.FrameType & (MFX_FRAMETYPE_REF | (MFX_FRAMETYPE_S-1))) { case MFX_FRAMETYPE_REF|MFX_FRAMETYPE_I: case MFX_FRAMETYPE_REF|MFX_FRAMETYPE_P: nal.i_ref_idc = NAL_PRIORITY_HIGH; break; case MFX_FRAMETYPE_REF|MFX_FRAMETYPE_B: nal.i_ref_idc = NAL_PRIORITY_LOW; break; case MFX_FRAMETYPE_B: nal.i_ref_idc = NAL_PRIORITY_DISPOSABLE; break; default: Log(TEXT("Unhandled frametype %u"), bs.FrameType); } } start[3] = ((nal.i_ref_idc<<5)&0x60) | nal.i_type; nal.p_payload = start; nal.i_payload = int(next-start); nalOut << nal; start = next; } size_t nalNum = nalOut.Num(); packets.Clear(); ClearPackets(); INT64 dts = outputTimestamp; INT64 in_pts = msFromTimestamp(task.surf.Data.TimeStamp), out_pts = msFromTimestamp(bs.TimeStamp); if(!bFirstFrameProcessed && nalNum) { delayOffset = -dts; bFirstFrameProcessed = true; } INT64 ts = INT64(outputTimestamp); int timeOffset; //if frame duplication is being used, the shift will be insignificant, so just don't bother adjusting audio timeOffset = int(out_pts-dts); timeOffset += frameShift; if(nalNum && timeOffset < 0) { frameShift -= timeOffset; timeOffset = 0; } //Log(TEXT("inpts: %005d, dts: %005d, pts: %005d, timestamp: %005d, offset: %005d, newoffset: %005d"), task.surf.Data.TimeStamp/90, dts, bs.TimeStamp/90, outputTimestamp, timeOffset, bs.TimeStamp/90-dts); timeOffset = htonl(timeOffset); BYTE *timeOffsetAddr = ((BYTE*)&timeOffset)+1; VideoPacket *newPacket = NULL; PacketType bestType = PacketType_VideoDisposable; bool bFoundFrame = false; for(unsigned i=0; i<nalNum; i++) { x264_nal_t &nal = nalOut[i]; if(nal.i_type == NAL_SEI) { BYTE *skip = nal.p_payload; while(*(skip++) != 0x1); int skipBytes = (int)(skip-nal.p_payload); int newPayloadSize = (nal.i_payload-skipBytes); BYTE *sei_start = skip+1; while(sei_start < (nal.p_payload+nal.i_payload)) { BYTE *sei = sei_start; int sei_type = 0; while(*sei == 0xff) { sei_type += 0xff; sei += 1; } sei_type += *sei++; int payload_size = 0; while(*sei == 0xff) { payload_size += 0xff; sei += 1; } payload_size += *sei++; const static BYTE emulation_prevention_pattern[] = {0, 0, 3}; BYTE *search = sei; for(BYTE *search = sei;;) { search = std::search(search, sei+payload_size, emulation_prevention_pattern, emulation_prevention_pattern+3); if(search == sei+payload_size) break; payload_size += 1; search += 3; } int sei_size = (int)(sei-sei_start) + payload_size; sei_start[-1] = NAL_SEI; if(sei_type == SEI_USER_DATA_UNREGISTERED) { SEIData.Clear(); BufferOutputSerializer packetOut(SEIData); packetOut.OutputDword(htonl(sei_size+1)); packetOut.Serialize(sei_start-1, sei_size+1); } else { if (!newPacket) newPacket = CurrentPackets.CreateNew(); BufferOutputSerializer packetOut(newPacket->Packet); packetOut.OutputDword(htonl(sei_size+1)); packetOut.Serialize(sei_start-1, sei_size+1); } sei_start += sei_size; } } else if(nal.i_type == NAL_AUD) { BYTE *skip = nal.p_payload; while(*(skip++) != 0x1); int skipBytes = (int)(skip-nal.p_payload); int newPayloadSize = (nal.i_payload-skipBytes); if (!newPacket) newPacket = CurrentPackets.CreateNew(); BufferOutputSerializer packetOut(newPacket->Packet); packetOut.OutputDword(htonl(newPayloadSize)); packetOut.Serialize(nal.p_payload+skipBytes, newPayloadSize); } else if(nal.i_type == NAL_SLICE_IDR || nal.i_type == NAL_SLICE) { BYTE *skip = nal.p_payload; while(*(skip++) != 0x1); int skipBytes = (int)(skip-nal.p_payload); if (!newPacket) newPacket = CurrentPackets.CreateNew(); if (!bFoundFrame) { newPacket->Packet.Insert(0, (nal.i_type == NAL_SLICE_IDR) ? 0x17 : 0x27); newPacket->Packet.Insert(1, 1); newPacket->Packet.InsertArray(2, timeOffsetAddr, 3); bFoundFrame = true; } int newPayloadSize = (nal.i_payload-skipBytes); BufferOutputSerializer packetOut(newPacket->Packet); packetOut.OutputDword(htonl(newPayloadSize)); packetOut.Serialize(nal.p_payload+skipBytes, newPayloadSize); switch(nal.i_ref_idc) { case NAL_PRIORITY_DISPOSABLE: bestType = MAX(bestType, PacketType_VideoDisposable); break; case NAL_PRIORITY_LOW: bestType = MAX(bestType, PacketType_VideoLow); break; case NAL_PRIORITY_HIGH: bestType = MAX(bestType, PacketType_VideoHigh); break; case NAL_PRIORITY_HIGHEST: bestType = MAX(bestType, PacketType_VideoHighest); break; } } /*else if(nal.i_type == NAL_SPS) { VideoPacket *newPacket = CurrentPackets.CreateNew(); BufferOutputSerializer headerOut(newPacket->Packet); headerOut.OutputByte(0x17); headerOut.OutputByte(0); headerOut.Serialize(timeOffsetAddr, 3); headerOut.OutputByte(1); headerOut.Serialize(nal.p_payload+5, 3); headerOut.OutputByte(0xff); headerOut.OutputByte(0xe1); headerOut.OutputWord(htons(nal.i_payload-4)); headerOut.Serialize(nal.p_payload+4, nal.i_payload-4); x264_nal_t &pps = nalOut[i+1]; //the PPS always comes after the SPS headerOut.OutputByte(1); headerOut.OutputWord(htons(pps.i_payload-4)); headerOut.Serialize(pps.p_payload+4, pps.i_payload-4); }*/ else continue; } packetTypes << bestType; packets.SetSize(CurrentPackets.Num()); for(UINT i=0; i<packets.Num(); i++) { packets[i].lpPacket = CurrentPackets[i].Packet.Array(); packets[i].size = CurrentPackets[i].Packet.Num(); } idle_tasks << index; assert(queued_tasks[0] == index); queued_tasks.Remove(0); }
void toggle_led() { lock_mutex(); PORTB^=(1<<PINB0); unlock_mutex(); }