FFMPEG4.0 音频解码解封装
FFMPEG 音频封装编码

下面的函数方法基于最新的FFMPEG 4.0(4.X):
本文讲是如何从一个视频文件中提取出其中的图像数据,并将图像数据保存到文件中。

解码解封装的过程与音频差不多,具体如下:
1.读取视频文件的格式信息

    fmt_ctx = avformat_alloc_context();avformat_open_input(&fmt_ctx,input,NULL,NULL);avformat_find_stream_info(fmt_ctx,NULL);

2.获取视频流

    int st_index = av_find_best_stream(fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);LOGV("st_index = %d\n",st_index);AVStream *st = fmt_ctx->streams[st_index];

3.准备×××与解码context

    AVCodec *codec = avcodec_find_decoder(st->codecpar->codec_id);AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);

4.拷贝视频流中的参数到×××context中并打开×××

    avcodec_parameters_to_context(codec_ctx,st->codecpar);avcodec_open2(codec_ctx,codec,NULL);

5.读取视频的格式、宽高信息

    int width = codec_ctx->width;int height = codec_ctx->height;enum AVPixelFormat pixel_fmt = codec_ctx->pix_fmt;

6.申请图像存储空间

    uint8_t *dst_buf[4] = {0};int      dst_linesize[4];int size = av_image_alloc(dst_buf,dst_linesize,width,height,pixel_fmt,1);

7.申明存储原始数据与解码后数据的packet与frame

    AVFrame *frame = av_frame_alloc();AVPacket *packet = av_packet_alloc();

8.读取数据,只取用视频数据

int ret = av_read_frame(fmt_ctx,packet);
//读取到的packet不仅仅是图像数据,还有音频、字幕等数据。
if(packet->stream_index != st_index)
{continue;
}

9.发送数据进行解码
ret = avcodec_send_packet(codec_ctx,packet);
10.接收解码后的原始数据,这是个反复的过程,一个packet可能解码出好几个frame

        ret = avcodec_receive_frame(codec_ctx,frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) //packet解码完了,需要sentbreak;if(ret < 0) {return 1;}

注意:收到的frame可能存在宽高或者fmt格式变化这种情况,后面的流程代码没有考虑这种情况(这种奇葩视频应该不会遇到)

            if(frame->width != width || frame->height != height || frame->format != pixel_fmt){LOGV("eeeeeeeeeeeee");}

11.把frame中的数据拷贝到事先准备的dst_buf中。二维指针数组看作一位数组。
av_image_copy(dst_buf,dst_linesize,frame-&gt;data,frame-&gt;linesize,pixel_fmt,width,height);
12.把数据写入文件。
fwrite(dst_buf[0],1,size,out_file);

下面贴一段完整的示例代码,代码没有考虑失败的情况,结尾没有搞释放,也没有flush×××,示例只是为了掌握整个核心解码流程。

/** demuxing_decode_video.c**  Created on: 2019年1月8日*      Author: deanliu*/#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>static char log_buf[1024*8];
#define LOGV(...) av_log(NULL,AV_LOG_VERBOSE,__VA_ARGS__)void ffmpeg_log_callback(void* ptr, int level, const char* fmt, va_list vl)
{static int print_prefix = 1;av_log_format_line(ptr,level,fmt,vl,log_buf,sizeof(log_buf),&print_prefix);fprintf(stderr,"%s",log_buf);
}int main()
{av_log_set_callback(ffmpeg_log_callback);char *input = "E:/测试音视频/12种格式视频/test.avi";char *output = "d:/video.v";FILE *out_file = fopen(output,"wb");AVFormatContext *fmt_ctx;fmt_ctx = avformat_alloc_context();avformat_open_input(&fmt_ctx,input,NULL,NULL);avformat_find_stream_info(fmt_ctx,NULL);int st_index = av_find_best_stream(fmt_ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);LOGV("st_index = %d\n",st_index);AVStream *st = fmt_ctx->streams[st_index];AVCodec *codec = avcodec_find_decoder(st->codecpar->codec_id);AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);avcodec_parameters_to_context(codec_ctx,st->codecpar);avcodec_open2(codec_ctx,codec,NULL);int width = codec_ctx->width;int height = codec_ctx->height;enum AVPixelFormat pixel_fmt = codec_ctx->pix_fmt;uint8_t *dst_buf[4] = {0};int      dst_linesize[4];int size = av_image_alloc(dst_buf,dst_linesize,width,height,pixel_fmt,1);AVFrame *frame = av_frame_alloc();AVPacket *packet = av_packet_alloc();while(1){LOGV("READ\n");int ret = av_read_frame(fmt_ctx,packet);if(ret < 0){LOGV("ret = %d\n",ret);break;}if(packet->stream_index != st_index){continue;}LOGV("SENT\n");ret = avcodec_send_packet(codec_ctx,packet);if(ret < 0){return 1;}while(ret >= 0){LOGV("receiver\n");ret = avcodec_receive_frame(codec_ctx,frame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)break;if(ret < 0) {return 1;}if(frame->width != width || frame->height != height || frame->format != pixel_fmt){LOGV("eeeeeeeeeeeee");}av_image_copy(dst_buf,dst_linesize,frame->data,frame->linesize,pixel_fmt,width,height);LOGV("dst_buf = %d,%d,%d,%d\n",dst_buf[2][0],dst_buf[1][1],dst_buf[0][2],dst_buf[0][3]);fwrite(dst_buf[0],1,size,out_file);}}LOGV("dst_linesize = %d,%d,%d,%d\n",dst_linesize[0],dst_linesize[1],dst_linesize[2],size);printf("Play the output video file with the command:\n""ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",av_get_pix_fmt_name(pixel_fmt), width, height,output);LOGV("END!!");fclose(out_file);return 0;
}

转载于:https://blog.51cto.com/4095821/2402711

FFMPEG 视频图像解封装解码相关推荐

  1. 手把手FFmpeg入门——视频解码+解封装

    环境: QT5.7 64位 目的: 将视频解码为PCM和PPM文件 基础: 有点杂,几乎不需要基础,能看英文文档就行 基本原理: 1.无非是:解协议->解封装->解码, 这里没有协议层. ...

  2. JavaCV进阶opencv图像检测识别:ffmpeg视频图像画面人脸检测

    JavaCV免费教程目录: JavaCV入门教程(免费JavaCV教程) javacv实战专栏目录(2016年更新至今): JavaCV实战专栏文章目录(2016年更新至今) 2022年最新JavaC ...

  3. 【FFmpeg视频播放器开发】解封装解码流程、常用API和结构体简介(一)

    一.前言 在正式编写 FFmpeg 播放器前,我们需要先简单了解下所要用到的 FFmpeg 库.播放与解码流程.函数和相关结构体. 二.FFmpeg 库简介 库 介绍 avcodec 音视频编解码核心 ...

  4. (一) 音视频基础_Mpeg4封装格式音视频编码格式_解封装解码_像素格式_PCM音频-采样率-通道-planar_MP4标准和h264格式的NAL的GOP分析

    封装:从文件中把音视频读出来 解码:将音视频解压出来 重采样:将音视频转换成声卡显卡支持的格式,视频需要做像素格式的转换MPEG(或叫MPEG-4)是一套用于音频﹑视频信息压缩的编码标准. MPEG- ...

  5. FFmpeg分离(解封装)视频和音频

    使用FFmpeg库对mp4文件进行解封装,提取mp4中的视频流和音频流输出到单独的输出文件中. 所谓的分离视频和音频是我们通俗的说法,官方的说法叫解封装.与解封装对应的叫封装或复用器,也就是将多个视频 ...

  6. mjpeg stream 和FFmpeg视频图像读取分析

    1. 远程摄像头软件mjpg-streamer使用指南 mjpg-streamer 可以通过文件或者是HTTP方式访问linux UVC兼容摄像头.可以在公司,通过访问家里安 装的摄像头查看家里的情况 ...

  7. FFmpeg入门详解之119:FFmpeg的SDK编程回顾总结并操练

    3.FFmpeg的SDK编程回顾总结并操练 参考课程:"FFmpeg4.3--系列5--SDK二次开发详解与实战" FFmpeg主要框架 FFmpeg骨架:"八大金刚&q ...

  8. FFmpeg解封装、解码音频和视频(分别使用OpenGL和OpenAL播放)

    1 ffmpeg解码大致流程   下图是ffmpeg解码播放音视频的基本流程: 首先是网络媒体解协议,解协议之后得到对应的媒体文件比如mp4,ts等,这些格式是媒体文件的封装格式,也就是将音频,视频, ...

  9. ffmpeg解封装及解码实战

    ffmpeg解封装及解码实战 目录 封装格式相关函数 解封装流程 补充 分离AAC和H264 1. 封装格式相关函数 1. 基本概念 2. 相关函数 1. avformat_alloc_context ...

最新文章

  1. [Swift]LeetCode482. 密钥格式化 | License Key Formatting
  2. 【PAT - 甲级1094】The Largest Generation (25分)(dfs建树)
  3. @FeignClient中的@RequestMapping也被SpringMVC加载的问题解决
  4. DVM的进程和Linux的进,下面关于Android dvm的进程和Linux的进程,应用程序的进程说法正确的是()...
  5. 记录——《C Primer Plus (第五版)》第十章编程练习第四题
  6. Using Custom Assemblies with Reports
  7. java 中float所占字节_Java语言中,float类型所占存储空间为【】个字节
  8. TIBCO.Rendezvous简单的发消息的过程
  9. Unity接入穿山甲广告SDK教程
  10. 表单的js验证框架,只提供提示信息及正则表达式即可自动验证及提示
  11. 群晖java安装失败_群晖NAS安装Jenkins
  12. Matlab中set-gca函数的使用
  13. Java当中的IO流(中)
  14. 手机c语言多文件编程,C语言多文件编程
  15. Linux的体系结构
  16. bash:数值太大不可为算数进制的基
  17. python用opencv实现图片的美白磨皮_opencv----人脸美白算法,祛斑,祛痘,磨皮等...
  18. 储能之动力电池与储能电池区别?
  19. 用Javascript实现的嵌入式软件定制界面
  20. LFSR和CRC串行实现移位寄存器结构,并行CRC时序实现

热门文章

  1. 江森系统设置服务器日期,江森自控METASYS操作手册
  2. HTML多选框滚动条,《HTM单选.doc
  3. oracle数据库主键自增序列_Oracle数据库序列详解
  4. 再见安卓 鸿蒙,安卓系统:鸿蒙系统,正式再见
  5. queue java 用法_Java队列(Queue)用法
  6. uni-app 手指左右滑动实现翻页效果
  7. codeforces 1017E
  8. Windows10系统Python2.7通过Swig调用C++过程
  9. zip:命令行下zip压缩/解压缩
  10. C语言 将整数写入内存指定的连续字节单元中