2016-03-03 91 views
0

我正在開發一個項目,需要打開.mp4文件格式,逐幀讀取它的幀,將它們解碼並使用更好類型的無損壓縮對它們進行編碼並將它們保存到文件中。FFmpeg解碼.mp4視頻文件

如果我對做事的順序有誤,請糾正我,因爲我不是100%確定應該如何做這件事情。從我的理解,它應該是這樣的:

1. Open input .mp4 file 
2. Find stream info -> find video stream index 
3. Copy codec pointer of found video stream index into AVCodecContext type pointer 
4. Find decoder -> allocate codec context -> open codec 
5. Read frame by frame -> decode the frame -> encode the frame -> save it into a file 

到目前爲止,我遇到了幾個問題。例如,如果我想使用av_interleaved_write_frame()函數保存一個幀,我無法使用avformat_open_input()打開輸入.mp4文件,因爲它將填充AVFormatContext結構的一部分,輸入文件名爲filename,因此我無法「寫入」文件。我試過使用av_guess_format()不同的解決方案,但是當我使用dump_format()轉儲格式時,我什麼也沒得到,所以我找不到有關使用哪個編解碼器的流信息。

所以如果有人有任何建議,我會非常感激他們。先謝謝你。

+0

你們是不是要一個的MP4轉換爲一系列的無損的靜止圖像? – Eugene

+0

嗯,我試圖將.mp4文件拆分爲幀,壓縮它們並通過網絡發送它們。另一方面,這些幀將連接回.mp4文件。 –

+0

這是什麼意思?壓縮無損圖像毫無意義.mp4格式已被設計爲一個高效的容器。這個過程很慢,處理器密集,帶寬效率低下等。 – Eugene

回答

4

看到muxing docs的「詳細說明」。您:在使用使用avio_open2

  • 呼籲avformat_new_stream在輸出文件中的每個流av_guess_format
  • 組則將ctx->pb

    1. 組則將ctx->oformat。如果您正在重新編碼,這是通過將每個輸入文件流添加到輸出文件中。
    2. 呼叫avformat_write_header
    3. 呼叫av_interleaved_write_frame在循環
    4. 呼叫av_write_trailer
    5. 關閉文件(avio_close)並清除了所有分配的內存
  • +0

    你知道我如何將'AVFrame'結構的內容拷貝到'char * buffer'中,所以我可以使用winsock2的send()函數將該緩衝區發送到不同的進程?我正嘗試創建本地服務器 - 客戶端通信,以測量使用不同壓縮方法發送幀所需的時間。對於(y = 0; y data [0] + y * frame-> linesize [0],width),則爲 –

    +0

    。你也可以使用avcodec_encode_video2()來壓縮幀(而不是gzip,這是你可能要做的)。 –

    +0

    嗯,如果我這樣做,而不是複製整個'AVFrame'結構,考慮到我複製原始視頻幀,我將能夠編碼該幀(僅基於幀 - >數據[0]'和幀 - >使用'avcodec_encode_video2()'函數在接收端使用lineize [0]')? –

    0

    您可以將視頻轉換爲損失圖像的一個序列:

    ffmpeg -i video.mp4 image-%05d.png 
    

    ,然後從一系列的圖像回用視頻:

    ffmpeg -i image-%05d.png video.mp4 
    

    的功能還可以通過提供包裝。

    你可以看到一個類似的問題:Extracting frames from MP4/FLV?

    +0

    我沒有使用ffmpeg的靜態構建,我在我自己的項目中使用它們的API。 –

    +0

    FFmpeg是命令行實用程序。你使用哪種圖書館和語言? libavcodec的? – Eugene

    +0

    我正在使用libavcodec/format/device/filter/util/postproc/swscale。我用C寫。基本上它是一個FFmpeg的舊開發版本。 –