【FFMPEG使用经验一】FFMPEG解码MP4帧数不对问题探索

最近在使用FFMPEG如下命令解码MP4时发现比较奇怪的现象:解码264码流打包的MP4出现最前两帧是一样的,解码后的yuv比编码yuv多一帧;解码265码流打包的MP4出现解码后的yuv比编码yuv少一帧的问题(具体哪一帧不确定)。

	ffmpeg.exe -i name.mp4 name_dec.yuv

经过查找资料和尝试,在我的使用中,针对264和265打包的MP4分别使用如下方法可解决该问题。

  • 针对264打包的MP4加上-vsync passthrough可避免多帧的问题。

    ffmpeg.exe -i name.mp4 -vsync passthrough name_dec.yuv
    
  • 针对265打包的MP4需要先从MP4中抽取265裸流,然后解码265裸流可避免多帧的问题。当然264也可以这样处理,但是在解码264打包的MP4时上面的方法要更简单一些。

    ffmpeg -i name.mp4 -vcodec copy -bsf hevc_mp4toannexb name.h265
    ffmpeg -i name.h265 name_dec.yuv
    

以上是我的解决办法,经过测试发现解码得到的yuv帧数与编码时输入的yuv帧数、画面都是一致的。如果仍然不能解决你遇到的问题,欢迎留言探讨。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用FFmpeg库来逐解码MP3文件。以下是一个使用FFmpeg解码MP3文件并逐处理的示例代码: ```cpp extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> } int main() { av_register_all(); AVFormatContext *formatContext = avformat_alloc_context(); if (avformat_open_input(&formatContext, "input.mp3", NULL, NULL) != 0) { // 打开文件失败 return -1; } if (avformat_find_stream_info(formatContext, NULL) < 0) { // 获取流信息失败 return -1; } int audioStreamIndex = -1; for (int i = 0; i < formatContext->nb_streams; i++) { if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audioStreamIndex = i; break; } } if (audioStreamIndex == -1) { // 未找到音频流 return -1; } AVCodecParameters *codecParameters = formatContext->streams[audioStreamIndex]->codecpar; AVCodec *codec = avcodec_find_decoder(codecParameters->codec_id); if (codec == NULL) { // 找不到解码器 return -1; } AVCodecContext *codecContext = avcodec_alloc_context3(codec); if (avcodec_parameters_to_context(codecContext, codecParameters) != 0) { // 获取解码器上下文失败 return -1; } if (avcodec_open2(codecContext, codec, NULL) < 0) { // 打开解码器失败 return -1; } AVPacket *packet = av_packet_alloc(); AVFrame *frame = av_frame_alloc(); while (av_read_frame(formatContext, packet) >= 0) { if (packet->stream_index == audioStreamIndex) { if (avcodec_send_packet(codecContext, packet) != 0) { // 发送据包到解码器失败 break; } while (avcodec_receive_frame(codecContext, frame) == 0) { // 在这里处理每一音频据 // frame->data[0] 中存储了解码后的音频据 // frame->nb_samples 表示每个声道的采样点 // frame->channels 表示声道 // frame->sample_rate 表示采样率 } } av_packet_unref(packet); } av_packet_free(&packet); av_frame_free(&frame); avcodec_close(codecContext); avcodec_free_context(&codecContext); avformat_close_input(&formatContext); return 0; } ``` 你可以将输入文件名替换为你要解码的MP3文件的路径。在代码中的注释部分,你可以根据你的需求来处理每一的音频据。 请注意,上述代码只是一个简单的示例,你可能需要根据自己的项目需求进行适当的修改和错误处理。此外,你需要在编译时链接FFmpeg库,并正确设置头文件和库文件路径。 希望这能对你有所帮助!如果有任何问题,请随时问我。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值