FFmpeg(2)-avformat_open_input()函數詳解並示例打開mp4文件


一. 解封裝

pts 是顯示的時間 dts是解碼的時間, 這個時間是用來做同步。

  1. av_register_all(), 注冊所有的格式。包括解封裝格式和加封裝格式。
  2. avformat_network_init(), 用於初始化網絡。FFmpeg本身也支持解封裝RTSP的數據,如果要解封裝網絡數據格式,則可調用該函數。
  3. avformat_open_input()。打開一個文件並解析。可解析的內容包括:視頻流、音頻流、視頻流參數、音頻流參數、視頻幀索引。
  4. avformat_find_stream_info(),查找格式和索引。有些早期格式它的索引並沒有放到頭當中,需要你到后面探測,就會用到此函數。
  5. av_find_best_stream(), 當視頻被解封裝出來后,需要分開處理音頻和視頻,需要找到對應的音頻流和視頻流
  6. 解封裝后涉及到的結構體:

AVFormatContext: 封裝的上下文

AVStream : 存放的是音頻流或視頻流的參數信息

AVPacket: 針對於具體的解封裝完后的一個一個的數據包。

av_read_frame() 用於讀取一個AVPacket,AVPacket里面包含了這個包的pts,dts,還有這個包的stream index(它是音頻還是視頻),是否是關鍵幀,AVPacket把h264數據的間隔符去掉了。

二.avformat_open_input()函數詳解及mp4文件打開示例

2.1 avformat_open_input函數詳解

該函數用於打開一個輸入的封裝器。在調用該函數之前,須確保av_register_all()和avformat_network_init()已調用。

參數說明:

AVFormatContext **ps, 格式化的上下文。要注意,如果傳入的是一個AVFormatContext*的指針,則該空間須自己手動清理,若傳入的指針為空,則FFmpeg會內部自己創建。

const char *url, 傳入的地址。支持http,RTSP,以及普通的本地文件。地址最終會存入到AVFormatContext結構體當中。

AVInputFormat *fmt, 指定輸入的封裝格式。一般傳NULL,由FFmpeg自行探測。

AVDictionary **options, 其它參數設置。它是一個字典,用於參數傳遞,不傳則寫NULL。參見:libavformat/options_table.h,其中包含了它支持的參數設置。

2.2 mp4文件打開示例

extern "C" JNIEXPORT jstring
JNICALL
Java_com_yuneec_yongdaimi_ff_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    hello += avcodec_configuration();

    // 初始化解封裝
    av_register_all();
    // 初始化網絡
    avformat_network_init();
    // 打開文件
    AVFormatContext *ic = NULL;
    char path[] = "sdcard/1080.mp4";
    int ret = avformat_open_input(&ic, path, 0, 0);
    if (ret == 0) {
        LOGI("avformat_open_input() called success.");
    } else {
        LOGE("avformat_open_input() called failed: %s", av_err2str(ret));
    }
    return env->NewStringUTF(hello.c_str());
}

PS:

1.這里用到了avformat_open_input()函數,需要包含其對應的頭文件: #include <libavformat/avformat.h> ;

2.代碼中還用到了 av_err2str() 這個函數,因此CMakeLists.txt中還需要包含它所對應的 libavutil.so 庫,相關的CMakeLists.txt如下:

# avcodec
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/libavcodec.so)

# avformat
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/libavformat.so)

# avutil
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/libavutil.so)

另外,不要忘記添加鏈接:

target_link_libraries( # Specifies the target library.
                       native-lib
                       avcodec
                       avformat
                       avutil

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

 


免責聲明!

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



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