视频的封装和编码
视频格式
1.封装格式 AVI MP4 ASF
2.编码格式 H264 wmv XviD
常用的封装格式
1.AVI 压缩标准可任意选择
2.FLV ts 流媒体格式
3.ASF
4.mp4
常用编码格式
1.视频h264 (AVC Part10),wmv XviD(part2),mjpeg
2.音频acc MP3 ape flac
封装格式和编码格式
----------------------------------------------------------
封装格式(格式头) | 视频编码帧 | 音频编码帧 | 视频编码帧 | 音频编码帧
----------------------------------------------------------
格式头:mp4(Part14) flv mov avi box音视频信息(编码和格式关键帧索引)
视频编码帧:h264 mpeg-4-10 NAL VCL SPS PPS I B P 解码YUV->转RGB显示
音频编码帧: AAC APE FLAC无损压缩PCM原始音频 解码PCM FLT->转为声卡支持的s16 播放
像素格式
1.BGRA RGBA ARGB32 RGB32 YUV420
2.R = Y + 1.4075 * (V - 128);
3.G = Y - 0.3455 * (U - 128) - 0.7169*(V - 128);
4.B = Y + 1.779 * (U - 128);
PCM音频参数
1.采样率 sample_rate 44100 (CD)
2.通道channels(左右声道)
3.样本大小(格式)sample_simple
-AV_SAMPLE_FMT_S16
-AV_SAMPLE_FMT_FLTP
样本类型planar
1.AV_SAMPLE_FMT_S16 在内存的格式为
c1,c2,c1,c2,c1,c2,…
2.AV_SAMPLE_FMT_S16P 在内存中的格式为:
c1,c1,c1…c2,c2,c2…
H.264/AVC视频编码标准
1.视频编码层面(VCL)
-视频数据的内容
2.网络抽象层面(NAL)
-格式化数据并提供头信息
NAL单元
因此我们平时的每一帧数据就是一个NAL单元(SPS与PPS除外),在实机的h264数据
帧中,往往帧前面带有00 00 00 01或00 00 01分割符一般来说编码出来的首帧数据为PPS与SPS,接着为I帧
MPEG-4
1.MPEG-4是一套用于音频,视频信息的压缩编码标准
2.MPEG-4 Part 14 MPEG-4 文件格式Part 15 AVC文件格式
3.H264(AVC Part10)
视频转封装示例
1.解封mp4
2.封装为WMV
avformat_open_input
1.AVFormatContext **ps
2.const char *url
3.AVInputFormat *fmt
4.AVDictionary **options
AVFormatContext
1.封装格式的上下文
2.AVIOContext *pb; //IO上下文
3.AVStream **streams; //视频音频字幕流
AVPacket
int64_t pts; //pts *(num / den)
int64_t dts;
uint8_t *data;int size;
int stream_index;
int flags;
CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(ffmpeg_pro VERSION 0.1.0 LANGUAGES CXX C)
##配置 预编译库 如ffmpeg库 路径
# find_library(AVCODEC_LIBRARY avcodec)
# find_library(AVFORMAT_LIBRARY avformat)
# find_library(AVUTIL_LIBRARY avutil)
# find_library(AVDEVICE_LIBRARY avdevice)
##加入预编译库的头文件 如ffmpeg库 的头文件
#include_directories(include)
add_executable(ffmpeg_pro mp4_to_wmv.cpp)
message(STATUS ${AVCODEC_LIBRARY})
target_link_libraries(
ffmpeg_pro
pthread
swresample
m
swscale
avformat
avcodec
avutil
avfilter
avdevice
postproc
z
lzma
rt)
mp4_to_wmv.cpp
extern "C"
{
#include
}
#include
using namespace std;
int main()
{
char infile[] = "test.mp4";
char outfile[] = "test.wmv";
//muxer,demuters
av_register_all();
AVFormatContext *ic = NULL;
//open input file
avformat_open_input(&ic, infile, 0, 0);
if(!ic)
{
cout<<"avformat_open_input failed!"<<endl;
return -1;
}
cout<<"open "<<infile<<" success!"<<endl;
//2 create output context
AVFormatContext *oc = NULL;
avformat_alloc_output_context2(&oc,NULL,NULL,outfile);
if(!oc)
{
cerr<<"avformat_alloc_output_context2 failed"<<outfile;
return -1;
}
///3 add the stream
AVStream *videoStream = avformat_new_stream(oc,NULL);
AVStream *audioStream = avformat_new_stream(oc,NULL);
///4 copy param
avcodec_parameters_copy(videoStream->codecpar,ic->streams[0]->codecpar);
avcodec_parameters_copy(audioStream->codecpar,ic->streams[1]->codecpar);
videoStream->codecpar->codec_tag = 0;
audioStream->codecpar->codec_tag = 0;
av_dump_format(ic,0,outfile,0);
cout<<"==================================="<<endl;
av_dump_format(oc,0,outfile,1);
///5 open out file io, write head
int ret = avio_open(&oc->pb,outfile,AVIO_FLAG_WRITE);
if(ret < 0)
{
cerr<<"avio open failed!"<<endl;
return -1;
}
//
avformat_write_header(oc,NULL);
if(ret < 0)
{
cerr<<"avformat_write_header failed !"<<endl;
}
AVPacket pkt;
for(;;)
{
int re = av_read_frame(ic, &pkt);
if(re < 0)
break;
pkt.pts = av_rescale_q_rnd(pkt.pts,
ic->streams[pkt.stream_index]->time_base,
oc->streams[pkt.stream_index]->time_base,
(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)
);
pkt.dts = av_rescale_q_rnd(pkt.dts,
ic->streams[pkt.stream_index]->time_base,
oc->streams[pkt.stream_index]->time_base,
(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)
);
pkt.pos = -1;
pkt.duration = av_rescale_q_rnd(pkt.duration,
ic->streams[pkt.stream_index]->time_base,
oc->streams[pkt.stream_index]->time_base,
(AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)
);
av_write_frame(oc,&pkt);
av_packet_unref(&pkt);
cout<<".";
}
av_write_trailer(oc);
avio_close(oc->pb);
cout<<"\n============================end========================\n";
return 0;
}
xz@xiaqiu:~/study/csdn/ffmpeg/mp4_to_wmv/build$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake ffmpeg_pro Makefile test.mp4 test.wmv
xz@xiaqiu:~/study/csdn/ffmpeg/mp4_to_wmv/build$ ./ffmpeg_pro
open test.mp4 success!
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.wmv':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:12.58, bitrate: N/A
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1294x704, 20 kb/s, SAR 1:1 DAR 647:352, 17.31 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: vorbis (mp4a / 0x6134706D), 48000 Hz, 2 channels, 0 kb/s (default)
Metadata:
handler_name : SoundHandler
===================================
Output #0, asf, to 'test.wmv':
Stream #0:0: Video: h264, none, 1294x704, q=2-31, 20 kb/s
Stream #0:1: Audio: vorbis, 48000 Hz, 2 channels, 0 kb/s
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
============================end========================
xz@xiaqiu:~/study/csdn/ffmpeg/mp4_to_wmv/build$