2016-03-03 93 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的旧开发版本。 –