對視頻和音頻進行編碼 音頻算法是G.711 視頻算法是mpeg4和H.264 這些算法符合xDM界面。 6個線程:控制線程、視頻線程、顯示線程、寫線程、語音線程、采集線程。 主線程—--->視頻線程video thread、語音線程Speech Thread、采集線程、寫線程 視頻線程-->顯示線程Display Thread、寫線程Write Thread 主線程-à控制線程 注:視頻文件存在則創(chuàng)建視頻線程、采集線程、寫線程、顯示線程 語音文件存在則創(chuàng)建語音線程 完成以上線程的創(chuàng)建后控制線程變?yōu)榭刂凭€程。 至少存在一個文件,因此系統(tǒng)中最少有2個線程,最多有6個線程。 用法 Usage: encode [options] Options: -s | --speechfile Speech file to record to 聲音文件名 -v | --videofile Video file to record to 視頻文件名 -r | --resolution Video resolution ('width'x'height') [720x480] 視頻分辨率 -b | --bitrate Bit rate to encode video at [variable] -d | --deinterlace Disable removal of interlacing artifacts from the captured video frames before encoding [off] -x | --svideo Use s-video instead of composite video input [off] -l | --linein Use line in for encoding sound instead of mic [off] -k | --keyboard Enable keyboard interface [off] -t | --time Number of seconds to run the demo [infinite] -i | --interface Launch the demo interface when exiting [off] -h | --help Print this message You must supply at least a video or a speech file or both with appropriate extensions for the file formats. writer線程分析 1. Open the output video file: outputFp = fopen(envp->videoFile, "w"); 2. 等待匯集: 如果有視頻文件或語音文件則匯集線程數(shù)為5; 如果視頻文件和語音文件都有則匯集線程數(shù)為6; 視頻文件和語音文件至少有一個。 Rendezvous_meet(envp->hRendezvousInit); 這些線程是:控制線程、視頻線程、采集線程、寫線程、顯示線程 語音線程 3. 進入循環(huán) 4. Get an encoded buffer from the video thread. 5. Is the video thread flushing the pipe? Yes, Exit. No, cont. 6. Store the encoded frame to disk. 7. Send back the buffer to the video thread. (the encoded buffer) 8. goto 3. video線程分析 視頻線程所用管道 videoEnv.hCaptureOutFifo = &captureEnv.outFifo; videoEnv.hCaptureInFifo = &captureEnv.inFifo; videoEnv.hWriterOutFifo = &writerEnv.outFifo; videoEnv.hWriterInFifo = &writerEnv.inFifo; 1. Open Codec Engine, Reset, load, and start DSP Engine. 2. Create video encoder ,/* Allocate and initialize video encoder on the engine; 3. Allocate buffers for encoded data and prime the writer thread. 為已編碼的數(shù)據(jù)分配緩沖區(qū),并裝填給寫線程。 Memory_contigAlloc() 分配連續(xù)的緩沖區(qū) FifoUtil_put(envp->hWriterInFifo, &we) //寫管道操作 // 將申請的緩沖區(qū)內(nèi)容寫到管道hWriterInFifo中。 我的理解,申請若干個緩沖區(qū),每個緩沖區(qū)要連續(xù),并將緩沖區(qū)中的內(nèi)容 寫到管道envp->hWriterInFifo中(注:該管道在創(chuàng)建線程之前,已打開)。 有用嗎?buffer中的數(shù)據(jù)是什么? 4. Allocate buffers for interacting with the capture thread Memory_contigAlloc() 分配連續(xù)的緩沖區(qū) FifoUtil_put(envp->hCaptureInFifo, &ce) // FIFo且當(dāng)管道 // 將申請的緩沖區(qū)放在hCaptureInFifo隊列中。 我的理解,申請若干個緩沖區(qū),每個緩沖區(qū)要連續(xù),并將它們放在 采集線程的緩沖隊列中。 5. 等待匯集; 6. 當(dāng)不需要退出時,執(zhí)行下列步驟: 7. 測試等待狀態(tài),按要求決定是否繼續(xù)。 8. Get a buffer from the capture thread. hCaptureOutFifo 視頻線程讀采集線程采集的數(shù)據(jù)-->ce 9. 視頻線程從寫線程讀回數(shù)據(jù)。àwe 10. 對ce編碼并送到we中。 11. 視頻線程將已編碼的數(shù)據(jù)寫到管道,由寫線程寫文件 12. 視頻線程將原數(shù)據(jù)送給采集線程。ce 13. goto 6. pause Pause_open 初始化互斥變量和條件變量; 且設(shè)置pause未暫停,hPause->pause = FALSE; Pause_test 如果在暫停中則等待,否則繼續(xù)。 1. 進入臨界區(qū)(有互斥變量控制); 2. 如果在暫停中,則等待在條件變量中; 3. 退出臨界區(qū)。 Pause_on 1. 進入臨界區(qū)(有互斥變量控制); 2. 設(shè)置暫停標(biāo)志; 3. 退出臨界區(qū)。 Pause_off 1. 進入臨界區(qū)(有互斥變量控制); 2. 如果在暫停中,則清暫停標(biāo)志,并向其他線程廣播該消息; 3. 退出臨界區(qū)。 Pause_close 釋放互斥變量和條件變量。 Pause的應(yīng)用 顯示線程: 開始循環(huán)時:Pause_test(envp->hPause); 退出時:Pause_off(envp->hPause); 語音線程: 開始循環(huán)時:Pause_test(envp->hPause); 退出時:Pause_off(envp->hPause); 采集線程: 開始循環(huán)時:Pause_test(envp->hPause); 退出時:Pause_off(envp->hPause); 寫線程: 退出時:Pause_off(envp->hPause); 控制線程: 當(dāng)按下錄制鍵時:Pause_off(envp->hPause); 當(dāng)按下暫停鍵時:Pause_on(hPause); 退出時:Pause_off(envp->hPause); fifoutil This interface enables easy passing of fixed size messages between POSIX threads in Linux using first in first out ordering. Only one reader and writer per fifo is supported unless the application serializes the calls. FifoUtil_open static inline int FifoUtil_open(FifoUtil_Handle hFifo, size_t size); brief Opens the fifo. Must be called before other API:s on a fifo. 摘要:打開fifo管道。 @param hFifo Pointer to the fifo object to open. @param size Size in bytes of the messages to be passed through this fifo. @return FIFOUTIL_SUCCESS for success or FIFOUTIL_FAILURE for failure. 使用管道。 FifoUtil_close static inline int FifoUtil_close(FifoUtil_Handle hFifo); brief Closes the fifo. No API calls can be made on this fifo after this. param hFifo Pointer to the fifo object to close. return FIFOUTIL_SUCCESS for success or FIFOUTIL_FAILURE for failure. FifoUtil_get 讀管道 FifoUtil_get(FifoUtil_Handle hFifo, void *buffer); brief Blocking call to get a message from a fifo. param hFifo Pointer to a previously opened fifo object. param buffer A pointer to the buffer which will be copied to the fifo. return FIFOUTIL_SUCCESS for success or FIFOUTIL_FAILURE for failure. 讀管道。 static inline int FifoUtil_get(FifoUtil_Handle hFifo, void *buffer) { if (read(hFifo->pipes[0], buffer, hFifo->size) != hFifo->size) { return FIFOUTIL_FAILURE; } return FIFOUTIL_SUCCESS; } FifoUtil_put 寫管道 FifoUtil_put(FifoUtil_Handle hFifo, void *buffer) @brief Put a message on the fifo. @param hFifo Pointer to a previously opened fifo object. @param buffer A pointer to the buffer which will be copied from the fifo. @return FIFOUTIL_SUCCESS for success or FIFOUTIL_FAILURE for failure. static inline int FifoUtil_put(FifoUtil_Handle hFifo, void *buffer) { if (write(hFifo->pipes[1], buffer, hFifo->size) != hFifo->size) { return FIFOUTIL_FAILURE; } return FIFOUTIL_SUCCESS; } |
|