EasyPlayerPro(Windows)開發系列之解決分片錄像時間戳不正常的問題

本篇文章基於上一篇EasyPlayerPro(Windows)開發系列之採用ffmpeg進行錄像進行補充,測試發現錄像的切片除了第一個時間戳是正常的,其他的初始時間戳均不正常而且是之前切片的時間長度的總和;更有甚者很長一段時間的錄像都是黑屏無法播放的,爲了解決這個問題,我們需要將時間戳進行修正。

經過分析,初始時間戳是ffmpeg讀取網絡流自帶的時間戳,在過程中讀取流進行錄像,那麼勢必初始的時間戳需要進行減掉,執行過程如下:
1. 首先,申請幾個變量用以記錄每次開始錄像時的開始音視頻時間戳,以及音視頻是否進行重新錄像標誌:

    int64_t audio_start_pts = -1;
    int64_t audio_start_dts = -1;
    int64_t video_start_pts = -1;
    int64_t video_start_dts = -1;

    bool audio_re_record = false;
    bool video_re_record = false;

2.當達到切片條件時,置重新開啓標誌爲1,並記錄當前幀的時間戳爲了下一個切片的開始時間戳:

            if (play->record_duration > 0 && fRecTime > play->record_duration && i_pkt.flags == AV_PKT_FLAG_KEY)
            {
                audio_re_record = true;
                video_re_record = true;
            }

這裏做了個簡單的處理,也就是當以視頻爲時間戳檢測標準時,需要要在關鍵幀到來時進行判斷,從而保證下一個切片的開始是以關鍵幀開始的。
3.當重新錄像標誌爲真的時候,則重置開始時間戳,從而在下一次切片時保證時間戳是從0開始的;

        if (in_stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)//不支持的視頻 過濾
        {
            if (video_start_pts < 0)
                video_start_pts = i_pkt.pts;
            if (video_start_dts < 0)
                video_start_dts = i_pkt.dts;

            if (video_re_record)
            {
                video_start_pts = i_pkt.pts;
                video_start_dts = i_pkt.dts;
                video_re_record = false;
            }
            i_pkt.pts = i_pkt.pts - video_start_pts;
            i_pkt.dts = i_pkt.dts - video_start_dts;
        }

        if (in_stream->codec->codec_type == AVMEDIA_TYPE_AUDIO )//不支持的音頻 過濾
        {
            if (audio_start_pts < 0)
                audio_start_pts = i_pkt.pts;
            if (audio_start_dts < 0)
                audio_start_dts = i_pkt.dts;
            if (audio_re_record)
            {
                audio_start_pts = i_pkt.pts;
                audio_start_dts = i_pkt.dts;
                audio_re_record = false;
            }
            i_pkt.pts = i_pkt.pts - audio_start_pts;
            i_pkt.dts = i_pkt.dts - audio_start_dts;
        }

爲了保證錄像的成功,需要把小於0的時間戳置爲0:

        i_pkt.pts = (i_pkt.pts > 0) ? i_pkt.pts : 0;
        i_pkt.dts = (i_pkt.dts > 0) ? i_pkt.dts : 0;
        i_pkt.duration = (i_pkt.duration > 0) ? i_pkt.duration : 0;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章