FFMpeg筆記(七) 代碼結構分析,以HLS為例


HLS流在播放時是先解協議(hls.c)后解封裝(mpegts.c),libavformat下的hls.c和mpegts.c實際上是同一個級別的,同屬於demuxer。

一、解HLS協議

1. FFmpeg代碼分析    

    首先看一下ff_hls_demuxer的定義:

AVInputFormat ff_hls_demuxer = {
    .name           = "hls,applehttp",
    .long_name      = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
    .priv_class     = &hls_class,
    .priv_data_size = sizeof(HLSContext),
    .read_probe     = hls_probe,
    .read_header    = hls_read_header,
    .read_packet    = hls_read_packet,
    .read_close     = hls_close,
    .read_seek      = hls_read_seek,
};

(1)FFmpeg在拿到hls流后,它一開始並不知道該用哪個demuxer,這個時候它會進行probe,即依次調用demuxer的read_probe函數,選擇返回分數最高的一個demuxer,最后選定ff_hls_demuxer。AVFormatContext中的s->iformat->priv_data一般是指demuxer內部的結構體,在解HLS協議時,這個priv_data就是HLSContext;

(2)之后FFmpeg會調用read_header函數,即執行hls_read_header,獲取hls的播放列表,並賦值到HLSContext結構體中;

(3)當准備工作妥當后,FFmpeg會調用hls_read_packet讀取數據,傳遞給上層;

(4)如果有seek操作會執行hls_read_seek;

(5)視頻關閉時,FFmpeg會調用hls_close;

2. discontinue字段

    FFmpeg3.4沒有支持HLS標准的discontinue字段。discontinue字段常用於ts播放列表里插入一段廣告,這段廣告的參數可以與正片的參數不一致。上層在識別到這個參數后,可以重置解碼器。對於iOS,需要重新創建解碼器,對於Android,解碼器兼容了這種情況,無需重新創建解碼器。

二、解ts封裝 

以mpegts.c為例,probe一般是將讀取到的probe數據與ts格式對比,如果是ts格式則返回高分數,上層選擇最高的分數的demuxer;

PES包:分割打包的ES流,加入了PES頭。

struct MpegTSFilter {
    int pid;
    int es_id;
    int last_cc; /* last cc code (-1 if first packet) */
    int64_t last_pcr;
    enum MpegTSFilterType type;
    union {// 一個Filter是下邊的一種類型
        MpegTSPESFilter pes_filter;
        MpegTSSectionFilter section_filter;
    } u;
};

handle_packet函數處理一個ts包,在函數中switch case語句中處理ts包。一般是先處理ts header, 之后是pes header,代碼中狀態定義:

/* TS stream handling */
// 標識TS流狀態
enum MpegTSState {
    MPEGTS_HEADER = 0,
    MPEGTS_PESHEADER,
    MPEGTS_PESHEADER_FILL,
    MPEGTS_PAYLOAD,
    MPEGTS_SKIP,
};

 從av_read_frame讀到的pkt,其音頻和視頻的pts是連續的,但是兩者之間不是連續的,因為pts乘以時基才是真正的顯示時間,比如如下打印日志,pkt時間進行換算后,可以看到其整體pts是連續的。

martinjia time_base:1 30000, pkt index:0, pkt pts:83083(pts換算后:2.76s)
martinjia martinjia time_base:1 48000, pkt index:1, pkt pts:118784(pts換算后:2.47s)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM