# 开发入门

# 视频解码知识

纯粹视频解码流程

压缩编码数据 --> 像素数据

常见视频解码流程

解封装 --> 提取视频码流 --> 视频数据

# Visual Studio 开发环境搭建

新建控制台工程

文件--> 新建项目 --> Win32 控制台应用程序

拷贝 FFmpeg 开发文件

*.h 拷贝到 include *.lib 拷贝到 lib *.dll 拷贝到项目根目录

MinGW

  • inttypes.h
  • stdint.h
  • _mingw.h

配置静态链接库

属性 --> 链接器 --> 输入 --> 附加依赖项

avcodec.lib;avformat.lib;avutil.lib;avdevice.lib;avfilter.lib;postproc.lib;swresample.lib;swscale.lib;

# FFmpeg 库简介

  • avcodec 编解码
  • avformat 封装处理
  • avfilter 滤镜特效
  • avdevice 设备输入输出
  • avutil 工具库
  • postproc 后加工
  • swresample 音频采样格式转换
  • swscale 视频像素数据格式转换

# FFmpeg 数据结构分析

  • AVFormatContext

    • iformat AVInputFormat
    • nb_streams 输入视频的 AVStream 个数
    • streams AVStream[]
    • duration 输入视频的时长
    • bit_rate 输入视频的码率
  • AVInputFormat

    • id
    • name
    • long_name
    • extensions
    • 一些函数
  • AVStream

    • id 序号
    • codec AVCodecContext
    • time_base 时基
    • r_frame_rate 帧率
  • AVCodecContext

    • codec 编解码器的 AVCodec
    • width 图像的宽度
    • height 图像的高度
    • pix_fmt 像素格式
    • sample_rate 采样率
    • channels 声道数
    • sample_fmt 采样格式
  • AVCodec

    • id
    • name
    • long_name
    • type
    • 一些编解码的接口函数
  • AVPacket

    • pts:显示时间戳
    • dts :解码时间戳
    • data :压缩编码数据
    • size :压缩编码数据大小
    • stream_index :所属的 AVStream
  • AVFrame

    • pts:显示时间戳
    • dts :解码时间戳
    • data :压缩编码数据
    • size :压缩编码数据大小
    • stream_index :所属的 AVStream
// duration
printf("duraion: %d \n", pFormatCtx->duration);
// bit_rate
printf("bit_rate: %d \n", pFormatCtx->bit_rate);
// long_name
printf("long_name: %s \n", pFormatCtx->iformat->long_name);
// time_base
printf("time_base: %d \n", pFormatCtx->streams[0]->time_base);
// width height
int streamIndex = 1;
for(i = 0; i < pFormatCtx->nb_streams; i++){
  if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
      streamIndex = i;
      break;
    }
}
printf("width: %d \n", pFormatCtx->streams[0]->codec->width);
printf("height: %d \n", pFormatCtx->streams[0]->codec->height);

输出结果

duraion: 34087000
bit_rate: 219113
long_name: FLV (Flash Video)
time_base: 1
width: 512
height: 288

输出信息到文件

FILE *fp = fopen("info.txt","wb+");
// duration
fprintf(fp, "duraion: %d \n", pFormatCtx->duration);
// bit_rate
fprintf(fp, "bit_rate: %d \n", pFormatCtx->bit_rate);
// long_name
fprintf(fp, "long_name: %s \n", pFormatCtx->iformat->long_name);
// time_base
fprintf(fp, "time_base: %d \n", pFormatCtx->streams[0]->time_base);
// width height
int streamIndex = 1;
for(i = 0; i < pFormatCtx->nb_streams; i++){
  if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
      streamIndex = i;
      break;
    }
}
fprintf(fp, "width: %d \n", pFormatCtx->streams[0]->codec->width);
fprintf(fp, "height: %d \n", pFormatCtx->streams[0]->codec->height);
fclose(fp);
// fwrite packet
fwrite(packet->data, 1, packet->size, fp_h264);
// fwrite yuv
fwrite(pFrameYUV->data[0], 1, pCodecCtx->width * pCodecCtx->height, fp_yuv);
fwrite(pFrameYUV->data[1], 1, pCodecCtx->width * pCodecCtx->height/4, fp_yuv);
fwrite(pFrameYUV->data[2], 1, pCodecCtx->width * pCodecCtx->height/4, fp_yuv);