extern "C"
{
#include "libavformat\avformat.h"
};
int write_frame(AVFormatContext* pFormatContext,const AVRational* pRational,AVStream* pStream,AVPacket* pPacket)
{
av_packet_rescale_ts(pPacket,*pRational,pStream->time_base);
pPacket->stream_index = pStream->index;
return av_interleaved_write_frame(pFormatContext,pPacket);
}
int write_video_frame(AVFormatContext* pFormatContext,AVStream* pStream,AVFrame* pFrame)
{
AVCodecContext* pCodecContext = NULL;
pCodecContext = pStream->codec;
int ret,got_packet = 0;
if(pFormatContext->oformat->flags & AVFMT_RAWPICTURE)
{
AVPacket pPacket = {0};
av_init_packet(&pPacket);
if(!pFrame)
return 1;
pPacket.flags |= AV_PKT_FLAG_KEY;
pPacket.stream_index = pStream->index;
pPacket.data = (uint8_t *)pFrame;
pPacket.size = sizeof(AVPicture);
pPacket.pts = pPacket.dts = pFrame->pts;
av_packet_rescale_ts(&pPacket,pCodecContext->time_base,pStream->time_base);
ret = av_interleaved_write_frame(pFormatContext,&pPacket);
}
else
{
AVPacket pPacket = {0};
av_init_packet(&pPacket);
ret = avcodec_encode_video2(pCodecContext,&pPacket,pFrame,&got_packet);
if(ret < 0)
return -1;
if(got_packet)
ret = write_frame(pFormatContext,&pCodecContext->time_base,pStream,&pPacket);
else
ret = 0;
}
if(ret < 0)
return -2;
return (pFrame || got_packet) ? 0 : 1;
}
int main()
{
av_register_all();
//打开输入文件
AVFormatContext *pFormatContext_In = NULL;
pFormatContext_In = avformat_alloc_context();
char* FileName_In = "input.ts";
if(avformat_open_input(&pFormatContext_In,FileName_In,NULL,NULL) < 0)
{
avformat_free_context(pFormatContext_In);
return -1;
}
if(avformat_find_stream_info(pFormatContext_In,NULL) < 0)
{
avformat_close_input(&pFormatContext_In);
return -2;
}
//获取输入文件视频流索引
int VideoIndex = -1;
VideoIndex = av_find_best_stream(pFormatContext_In,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
if(VideoIndex == -1)
{
avformat_close_input(&pFormatContext_In);
return -3;
}
//锁定输出文件格式
AVFormatContext* pFormatContext_Out = NULL;
char* FileName_Out = "output.ts";
avformat_alloc_output_context2(&pFormatContext_Out,NULL,NULL,FileName_Out);
if(!pFormatContext_Out)
{
avformat_close_input(&pFormatContext_In);
return -4;
}
AVOutputFormat* pOutputFormat_Out = NULL;
pOutputFormat_Out = pFormatContext_Out->oformat;
//找到输出文件格式对应的编解码器
AVCodec* pCodec_Out = NULL;
pCodec_Out = avcodec_find_encoder(pOutputFormat_Out->video_codec);
if(!pCodec_Out)
{
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -5;
}
//创建输出流
AVStream* pStream_Out = NULL;
pStream_Out = avformat_new_stream(pFormatContext_Out,pCodec_Out);
if(!pStream_Out)
{
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -6;
}
pStream_Out->id = pFormatContext_Out->nb_streams - 1;
//设定输出文件编解码器上下文环境
AVCodecContext* pCodecContext_Out = NULL;
pCodecContext_Out = pStream_Out->codec;
pCodecContext_Out->codec_id = pOutputFormat_Out->video_codec;
pCodecContext_Out->bit_rate = 400000;
pCodecContext_Out->width = pFormatContext_In->streams[VideoIndex]->codec->width;
pCodecContext_Out->height = pFormatContext_In->streams[VideoIndex]->codec->height;
pStream_Out->time_base.num = 1;
pStream_Out->time_base.den = 25;
pCodecContext_Out->time_base = pStream_Out->time_base;
pCodecContext_Out->gop_size = 12;
pCodecContext_Out->pix_fmt = AV_PIX_FMT_YUV420P;
if(pCodecContext_Out->codec_id == AV_CODEC_ID_MPEG2VIDEO)
pCodecContext_Out->max_b_frames = 2;
if(pCodecContext_Out->codec_id == AV_CODEC_ID_MPEG1VIDEO)
pCodecContext_Out->mb_decision = 2;
if(pFormatContext_Out->oformat->flags & AVFMT_GLOBALHEADER)
pCodecContext_Out->flags |= CODEC_FLAG_GLOBAL_HEADER;
//打开输出文件对应的视频流编解码器
AVDictionary *pDictionary_Out = NULL;
av_dict_copy(&pDictionary_Out,NULL,0);
if(avcodec_open2(pCodecContext_Out,pCodec_Out,&pDictionary_Out) < 0)
{
av_dict_free(&pDictionary_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -7;
}
av_dict_free(&pDictionary_Out);
//打开输出文件
int ret = 0;
if(!(pOutputFormat_Out->flags & AVFMT_NOFILE))
{
ret = avio_open(&pFormatContext_Out->pb,FileName_Out,AVIO_FLAG_WRITE);
if(ret < 0)
{
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -8;
}
}
//写输出文件头
ret = avformat_write_header(pFormatContext_Out,&pDictionary_Out);
if(ret < 0)
{
avio_closep(&pFormatContext_Out->pb);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -9;
}
//打开输入文件对应解码器
AVCodecContext* pCodecContext_In = NULL;
pCodecContext_In = pFormatContext_In->streams[VideoIndex]->codec;
AVCodec* pCodec_In = NULL;
pCodec_In = avcodec_find_decoder(pCodecContext_In->codec_id);
if(pCodec_In == NULL)
{
avio_closep(&pFormatContext_Out->pb);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -10;
}
if(avcodec_open2(pCodecContext_In,pCodec_In,nullptr)!=0)
{
avio_closep(&pFormatContext_Out->pb);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -11;
}
//帧缓存
AVFrame* pFrame = NULL;
pFrame = av_frame_alloc();
if(pFrame == NULL)
{
avio_closep(&pFormatContext_Out->pb);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
return -12;
}
//数据缓存
AVPacket pPacket;
av_init_packet(&pPacket);
pPacket.data = NULL;
pPacket.size = 0;
//解码、编码
int gotFrame = 0;
while(1)
{
if(av_read_frame(pFormatContext_In,&pPacket) >= 0)
{
if(pPacket.stream_index == VideoIndex)
{
if((ret = avcodec_decode_video2(pCodecContext_In,pFrame,&gotFrame,&pPacket)) < 0)
return ret;
if(gotFrame)
write_video_frame(pFormatContext_Out,pStream_Out,pFrame);
}
av_free_packet(&pPacket);
}
else
break;
}
//写输出文件尾
av_write_trailer(pFormatContext_Out);
//释放
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avio_closep(&pFormatContext_Out->pb);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
avformat_close_input(&pFormatContext_In);
system("PAUSE");
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
FFmpeg_15_视频流转码(含解复用、解码、编码
共203个文件
h:98个
tlog:70个
dll:8个
需积分: 35 28 下载量 67 浏览量
2015-08-21
11:30:29
上传
评论 1
收藏 23.99MB ZIP 举报
温馨提示
FFmpeg系列,之前有发过一部分,但并未系列总结性将功能展现,目前按序号,将常用的发上来,VC2010环境下
资源推荐
资源详情
资源评论
收起资源包目录
FFmpeg_15_视频流转码(含解复用、解码、编码 (203个子文件)
FFmpeg.cpp 7KB
avcodec-56.dll 21.33MB
avformat-56.dll 5.73MB
avfilter-5.dll 2.28MB
avdevice-56.dll 1.32MB
avutil-54.dll 482KB
swscale-3.dll 442KB
swresample-1.dll 275KB
postproc-53.dll 129KB
FFmpeg.exe 32KB
FFmpeg.vcxproj.filters 955B
avcodec.h 178KB
avformat.h 103KB
avfilter.h 56KB
opt.h 37KB
pixfmt.h 34KB
frame.h 24KB
avio.h 22KB
swresample.h 20KB
intreadwrite.h 18KB
avdevice.h 18KB
pixdesc.h 15KB
mem.h 14KB
common.h 14KB
old_pix_fmts.h 14KB
avstring.h 13KB
swscale.h 12KB
log.h 10KB
old_codec_ids.h 10KB
samplefmt.h 10KB
buffer.h 10KB
channel_layout.h 9KB
avutil.h 8KB
imgutils.h 8KB
_mingw.h 8KB
vdpau.h 8KB
dict.h 8KB
bprint.h 8KB
parseutils.h 7KB
buffersink.h 7KB
version.h 6KB
xvmc.h 6KB
vda.h 6KB
stdint.h 6KB
inttypes.h 6KB
error.h 5KB
timecode.h 5KB
eval.h 5KB
mathematics.h 5KB
fifo.h 5KB
cpu.h 5KB
buffersrc.h 5KB
audio_fifo.h 4KB
rational.h 4KB
attributes.h 4KB
version.h 4KB
vaapi.h 4KB
dv_profile.h 4KB
stereo3d.h 4KB
hash.h 4KB
asrc_abuffer.h 3KB
downmix_info.h 3KB
display.h 3KB
threadmessage.h 3KB
avfft.h 3KB
postprocess.h 3KB
version.h 3KB
hmac.h 3KB
bswap.h 3KB
crc.h 3KB
timestamp.h 3KB
cast5.h 2KB
d3d11va.h 2KB
file.h 2KB
version.h 2KB
avcodec.h 2KB
dxva2.h 2KB
vorbis_parser.h 2KB
blowfish.h 2KB
twofish.h 2KB
camellia.h 2KB
avassert.h 2KB
base64.h 2KB
pixelutils.h 2KB
lzo.h 2KB
sha512.h 2KB
ripemd.h 2KB
version.h 2KB
lfg.h 2KB
md5.h 2KB
sha.h 2KB
xtea.h 2KB
version.h 2KB
aes.h 2KB
time.h 2KB
intfloat.h 2KB
version.h 2KB
version.h 2KB
replaygain.h 2KB
adler32.h 2KB
共 203 条
- 1
- 2
- 3
资源评论
黄忻
- 粉丝: 27
- 资源: 108
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功