操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    問題描述

    當(dāng)解碼較快的時(shí)候ffmpeg時(shí)間戳同步,并不是解碼后立馬顯示視頻幀,這樣看著是倍速的效果。如何還原實(shí)際的播放速率?

    解決方案

    為了解決在解碼后視頻播放還原原來每幀播放的時(shí)刻點(diǎn)。我們需要在解碼較快的情況下對(duì)幀顯示加一定的時(shí)間延時(shí)ffmpeg中時(shí)間戳同步,這個(gè)延時(shí)策略就是計(jì)算出

    延時(shí)調(diào)整時(shí)間 =(當(dāng)前幀時(shí)間戳  -  上一幀時(shí)間戳)- (當(dāng)前機(jī)器準(zhǔn)顯示時(shí)間  -  上一幀顯示機(jī)器時(shí)間)
    

    延時(shí)調(diào)整時(shí)間 有可能為負(fù)值則丟棄。如果為正值,可根據(jù)時(shí)長(zhǎng)做一定調(diào)整,畢竟送幀顯示也是耗時(shí)操作。

    demo示例:

    void dispThread(void *arg)
    {
        Input *input = (Input *)arg;
        static const double interval = 1000000.0 / input->fps;
        double q2d = av_q2d(input->tb) * 1000000.0;
        int64_t pre_pts = 0;
        int64_t frame_pre_pts = AV_NOPTS_VALUE;
        AVFrame *pending_frm = NULL;
        while (!input->is_req_exit()) {
            int64_t cur_pts;
            int remaining_time = 10000;
            double duration = interval;
            AVFrame *frm;
            if (pending_frm) {
                frm = pending_frm;
            } else {
                frm = input->PopFrame();
                if (!frm) {
                    msleep(10);
                    continue;
                }
                // printf("pop frame pts: %ld\n", frm->pts);
            }
            static auto delete_func = [](AVFrame * f) {
                av_frame_free(&f);
            };
            cur_pts = av_gettime_relative();
            if (frame_pre_pts != AV_NOPTS_VALUE)
                duration = (frm->pts - frame_pre_pts) * q2d;
            int countdown = (pre_pts == 0) ? 0 : (int)(duration - (cur_pts - pre_pts));
            remaining_time = std::min<int>(remaining_time, countdown);
            // printf("countdown: %d, remaining_time: %d us\n",
            //         countdown, remaining_time);
            if (input->realtime) {
                countdown = 0;
                remaining_time = 0;
            }
            if (countdown <= 0) {
                frame_pre_pts = frm->pts;
                pre_pts = cur_pts;
                if (frm == pending_frm)
                    pending_frm = NULL;
                push_frame(input->join, input->slice_idx,
                           std::shared_ptr<AVFrame>(frm, delete_func));
            } else {
                pending_frm = frm;
            }
            if (remaining_time > 0)
            {
                printf("countdown: %d, remaining_time: %d us\n",
                     countdown, remaining_time);
                std::this_thread::sleep_for(std::chrono::microseconds(remaining_time));
            }
        }
        if (pending_frm)
            av_frame_free(&pending_frm);
    }
    

    如果是直播的情況下我們不做延時(shí)。

    大致的流程如下

    取得解碼視頻幀記錄當(dāng)前機(jī)器時(shí)間計(jì)算當(dāng)前準(zhǔn)顯示時(shí)間與上次顯示時(shí)間差值d1計(jì)算當(dāng)前幀時(shí)間戳與上次顯示時(shí)間戳差值d2計(jì)算延時(shí)時(shí)間 d2 - d1延時(shí)時(shí)間大于0則進(jìn)行sleep延時(shí)并保存當(dāng)前幀在下一次循環(huán)送顯

    以上步驟為解決方案。請(qǐng)參考。

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有