<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    ffmpeg顯示視頻

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    項目最近需要實現播放視頻功能,這個在上家公司就做過。雖然跟之前的場景不一樣,有以前的功底還是很快可以解決,事實也確實如此。在使用DShow處理完視頻分割與合并后,繼續使用DShow顯示視頻,很快即完成。然而在播放dvr錄制的視頻文件時,發現播放幀率不對,分析發現是dvr存儲的視頻文件不是按標準格式進行存儲(使用ffplay效果還好點,media player根本沒法播放),于是重寫代碼。

    先簡要說明一下項目:client是delphi開發的GUI程序,視頻所有操作功能都由mfc dll實現,這個dll也就是由我實現。delphi只傳入要顯示視頻的窗口句柄、操作類型、文件名,這個跟我在以前設計但未能完工的顯示流媒體庫有不少借鑒作用,因此在此記錄一下。

    使用ffmpeg一直到讀取文件每一幀、解碼,剩下就是顯示的工作:解碼每一幀的rgb數據在CDC上顯示,顯示過程中一開始通過CreateDIBSection創建一個HBITMAP對象,memorydc中選入,然后在顯示cdc中StretchBlt,代碼如下

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 bmpInfoHdr.biPlanes = 1; bmpInfoHdr.biBitCount = 24; bmpInfoHdr.biWidth = pAvCdcCtx->width; bmpInfoHdr.biHeight = pAvCdcCtx->height; bmpInfoHdr.biSizeImage = nBytes; bmpInfoHdr.biSize = sizeof(bmpInfoHdr);   //創建DIB HBITMAP hBmpShow = CreateDIBSection(NULL, (BITMAPINFO*)&bmpInfoHdr, DIB_RGB_COLORS, (void**)&pRgbData, NULL, 0); if (!hBmpShow) {     itrace("CreateDIBSection failed %d", GetLastError());     continue; } memcpy(pRgbData, pBmpRgbData, nBytes);   //顯示圖片 hBmpBackup = (HBITMAP)m_memDc.SelectObject(hBmpShow); m_pShowDc->StretchBlt(0, 0, m_width, m_height, &m_memDc, 0, 0,         pAvCdcCtx->width, pAvCdcCtx->height, SRCCOPY);

     結果發現現實視頻效果極差,轉而研究ffplay代碼,發現ffplay分讀線程與解碼線程。懷疑是播放前未能讀取足夠的視頻幀進行緩存,導致視頻在解碼播放過程中出現因讀取視頻占用時間導致效果極差的原因。于是在代碼中添加了讀/解碼線程,修改后發現播放效果沒有任何改善。于是排除幀緩沖導致播放問題,這時候看到了yuv viewer代碼,發現其顯示是通過StretchDIBits實現,且不需要通過CreateDIBSection創建HBITMAP對象。嘗試修改代碼,播放效果非常好,代碼如下

    1 2 3 4 m_pShowDc->SetStretchBltMode(STRETCH_DELETESCANS); StretchDIBits(m_pShowDc->m_hDC, 0, 0, m_width, m_height,         0, 0, pAvCdcCtx->width, pAvCdcCtx->height,         pBmpRgbData, (BITMAPINFO*)&bmpInfoHdr, DIB_RGB_COLORS, SRCCOPY);

     ====視頻定位

    可以通過前進或者后退多少秒以及百分比對視頻進行定位,其實都是獲取其絕對時間通過av_rescale_q轉成ffmpeg所需要的時間格式,進行視頻定位。

    我們知道可以通過av_q2d(m_pAvFmtCtx->streams[i]->time_base)* pAvFrame->best_effort_timestamp來獲取當前播放時間

    1 2 3 AVRational bp = {1, AV_TIME_BASE}; target_pos = av_rescale_q(target_pos, bp, m_pAvFmtCtx->streams[idx]->time_base); av_seek_frame(m_pAvFmtCtx, idx, target_pos, AVSEEK_FLAG_ANY); RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全