FFMPEG_avi转码到mp4(aac+h264)源码
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
#include <stdio.h>
#include <ffmpeg/avutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;//why int here
char *q = buf;
if (buf_size <= 0)
return;
for(;;) {
c = *str++;
if (c == 0 || q >= buf + buf_size - 1)
break;
*q++ = c;
}
*q = '\0';
}
main(int argc,char **argv)
{
const char *input_file_name="/home/movie.avi";
av_register_all();//注册库中所有可用的文件格式和编码器
AVFormatContext *ic;
//输入文件处理部分
ic=av_alloc_format_context();
if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0)
{
printf("can't open the file %s\n",input_file_name);
exit(1);
}//打开输入文件
if(av_find_stream_info(ic)<0)
{
printf("can't find suitable codec parameters\n");
exit(1);
}//取出流信息
dump_format(ic,0,input_file_name,0);//列出输入文件的相关流信息
int i;
int videoindex=-1;int audioindex=-1;
for(i=0;i<ic->nb_streams;i++)
{
if(ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
{
videoindex=i;
//printf("video\n");
}
else if(ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO)
{
//printf("audio\n");
audioindex=i;
}
}
if(videoindex==-1)
{
printf("can't find video stream\n");
exit(1);
}//没有找到视频流
AVCodecContext *vCodecCtx;
vCodecCtx=ic->streams[videoindex]->codec;//取得视频流编码上下文指针
AVCodec *vCodec;
vCodec=avcodec_find_decoder(vCodecCtx->codec_id);
if(vCodec==NULL)
{
printf("can't find suitable video decoder\n");
exit(1);
}//找到合适的视频解码器
if(avcodec_open(vCodecCtx,vCodec)<0)
{
printf("can't open the video decoder\n");
exit(1);
}//打开该视频解码器
if(audioindex==-1)
{
printf("can't find audio stream\n");
exit(1);
}//没有找到音频流
AVCodecContext *aCodecCtx;
aCodecCtx=ic->streams[audioindex]->codec;
AVCodec *aCodec;
aCodec=avcodec_find_decoder(aCodecCtx->codec_id);
if(aCodec==NULL)
{
printf("can't find suitable audio decoder\n");
exit(1);
}//找到合适的音频解码器
if(avcodec_open(aCodecCtx,aCodec)<0)
{
printf("can't open the audio decoder\n");
exit(1);
}//打开该音频解码器
//下面为输出文件处理部分
const char *output_file_name="/home/result.aac";
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodecContext *oVcc,*oAcc;
AVCodec *oVc,*oAc;
AVStream *video_st,*audio_st;
AVFrame *oVFrame,*oAFrame;
double video_pts;
oVFrame=avcodec_alloc_frame();
fmt=guess_format(NULL,output_file_name,NULL);
if(!fmt)
{
printf("could not deduce output format from outfile extension\n");
exit(0);
}//判断是否可以判断输出文件的编码格式
oc=av_alloc_format_context();
if(!oc)
{
printf("Memory error\n");
exit(0);
}
oc->oformat=fmt;
pstrcpy(oc->filename,sizeof(oc->filename),output_file_name);
video_st=av_new_stream(oc,0);
if(!video_st)
{
printf("could not alloc video stream\n");
exit(0);
}
oVcc=avcodec_alloc_context();
oVcc=video_st->codec;
oVcc->codec_id=CODEC_ID_H264;
oVcc->codec_type=CODEC_TYPE_VIDEO;
oVcc->bit_rate=1000000;
oVcc->width=320;
oVcc->height=240;
oVcc->time_base=vCodecCtx->time_base;
oVcc->gop_size=vCodecCtx->gop_size;
//oVcc->pix_fmt=vCodecCtx->pix_fmt;
oVcc->pix_fmt=vCodecCtx->pix_fmt;
oVcc->max_b_frames=vCodecCtx->max_b_frames;
video_st->r_frame_rate=ic->streams[videoindex]->r_frame_rate;// frame rate
// audio_st=av_new_stream(oc,oc->nb_streams); //
audio_st=av_new_stream(oc,1);
if(!audio_st)
{
printf("could not alloc audio stream\n");
exit(0);
}
// avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO);
avcodec_get_context_defaults(audio_st->codec);// do what
oAcc=avcodec_alloc_context();
oAcc=audio_st->codec;
oAcc->codec_id=CODEC_ID_AAC;
oAcc->codec_type=CODEC_TYPE_AUDIO;
oAcc->bit_rate=aCodecCtx->bit_rate;// bit rate
oAcc->sample_rate=aCodecCtx->sample_rate;
oAcc->channels=2;
if (av_set_parameters(oc, NULL) < 0)
{
printf( "Invalid output format parameters\n");
exit(0);
}//设置必要的输出参数
strcpy(oc->title,ic->title);
strcpy(oc->author,ic->author);
strcpy(oc->copyright,ic->copyright);
strcpy(oc->comment,ic->comment);
strcpy(oc->album,ic->album);
oc->year=ic->year;
oc->track=ic->track;
strcpy(oc->genre,ic->genre);
dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
oVc=avcodec_find_encoder(CODEC_ID_H264);
if(!oVc)
{
printf("can't find suitable video encoder\n");
exit(0);
}//找到合适的视频编码器
if(avcodec_open(oVcc,oVc)<0)
{
printf("can't open the output video codec\n");
exit(0);
}//打开视频编码器
oAc=avcodec_find_encoder(CODEC_ID_AAC);
if(!oAc)
{
printf("can't find suitable audio encoder\n");
exit(0);
}//找到合适的音频编码器
if(avcodec_open(oAcc,oAc)<0)
{
printf("can't open the output audio codec");
exit(0);
}//打开音频编码器
/*if(url_exist(output_file_name))
{
printf("the output file name %s has exist,please select other\n",output_file_name);
exit(0);
}//判断该输出文件是否已经存在*/
if (!(oc->flags & AVFMT_NOFILE))
{
if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0)
{
printf("can't open the output file %s\n",output_file_name);
exit(0);
}//打开输出文件
}
if(!oc->nb_streams)
{
fprintf(stderr,"output file dose not contain any stream\n");
exit(0);
}//查看输出文件是否含有流信息
if(av_write_header(oc)<0)
{
fprintf(stderr, "Could not write header for output file\n");
exit(1);
}
AVPacket packet;
uint8_t *ptr,*out_buf;
int out_size;
static short *samples=NULL;
static unsigned int samples_size=0;
uint8_t *video_outbuf,*audio_outbuf;
int video_outbuf_size,audio_outbuf_size;
video_outbuf_size=400000;
video_outbuf= (unsigned char *) malloc(video_outbuf_size);
audio_outbuf_size = 10000;
//audio_outbuf = av_malloc(audio_outbuf_size);
audio_outbuf = (unsigned char *) malloc(audio_outbuf_size);
int flag;int frameFinished;int len;int frame_index=0,ret;
while(av_read_frame(ic,&packet)>=0)//从输入文件中读取一个包
{
if(packet.stream_index==videoindex)//判断是否为当前视频流中的包
{
len=avcodec_decode_video(vCodecCtx,oVFrame,&frameFinished,packet.data,packet.size);//若为视频包,解码该视频包
if(len<0)
{
printf("Error while decoding\n");
exit(0);
}
if(frameFinished)//判断视频祯是否读完
{
fflush(stdout);
oVFrame->pts=av_rescale(frame_index,AV_TIME_BASE*(int64_t)oVcc->time_base.num,oVcc->time_base.den);
oVFrame->pict_type=0;
out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame);
if (out_size > 0)
{
AVPacket pkt;
av_init_packet(&pkt);
if(oVcc->coded_frame && oVcc->coded_frame->key_frame)
pkt.flags |= PKT_FLAG_KEY;
pkt.flags = packet.flags;
pkt.stream_index= video_st->index;
pkt.data= video_outbuf;
pkt.size= out_size;
ret=av_write_frame(oc, &pkt);
}
frame_index++;
}
else
{
printf(".....\n");
}
#if 0
if(ret!=0)
{
printf("while write video frame error\n");
// exit(0);
}
#endif
}else if(packet.stream_index==audioindex)
{
len=packet.size;
ptr=packet.data;
int ret=0;
while(len>0)
{
out_buf=NULL;
out_size=0;
if(&packet)
samples=(short *)av_fast_realloc(samples,&samples_size,FFMAX(packet.size*sizeof
(*samples),AVCODEC_MAX_AUDIO_FRAME_SIZE));
out_size=samples_size;
ret=avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);//若为音频包,解码该音频包
if(ret<0)
{
printf("while decode audio failure\n");
exit(0);
}
fflush(stdout);
ptr+=ret;
len-=ret;
if(out_size<=0)
continue;
out_buf=(uint8_t *)samples;
AVPacket pkt;
av_init_packet(&pkt);
pkt.size= avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, (short int*)out_buf);
pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= audioindex;
pkt.data= audio_outbuf;
#if 1
if (av_write_frame(oc, &pkt) != 0)
{
fprintf(stderr, "Error while writing audio frame\n");
exit(1);
}
#endif
}
}
av_free_packet(&packet);
}
av_write_trailer(oc);
for(i = 0; i < oc->nb_streams; i++)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
//url_fclose(oc);
av_free(oc);
av_free(oVFrame);
av_free(out_buf);
avcodec_close(vCodecCtx);
avcodec_close(aCodecCtx);
av_close_input_file(ic);
}
来源:http://my.oschina.net/u/555701/blog/56744
FFMPEG_avi转码到mp4(aac+h264)源码的更多相关文章
- [spring源码学习]十、IOC源码-conversionService
一.代码示例 1.我们在之前的Person类里新增一个两个属性,分别是客户的兴趣和生日,兴趣爱好有很多,我们使用list进行保存,生日使用日期进行保存 public class Person { pr ...
- 如何在Eclipse中查看Android源码或者第三方组件包源码
文章出处:http://blog.csdn.net/cjjky/article/details/6535426 在学习过程中如果经常阅读源码,理解程度会比较深,学习效率也会比较高,那么如何方便快捷的阅 ...
- android狼人杀源码,桌面源码,猎豹快切源码
Android精选源码 android实现狼人杀app源码 android实现精心打造的Android基础框架源码 android热门电影的客户端源码 android 实现桌面的Launcher源码 ...
- android企业级商城源码、360°全景图VR源码、全民直播源码等
Android精选源码 [新版]Android技术博客精华汇总 开源了:乐乐音乐5.0-Android音乐播放器 android实现仿真水波纹效果源码 360°全景图VR,这是一个值得把玩的APP a ...
- 【java集合框架源码剖析系列】java源码剖析之TreeSet
本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...
- 【java集合框架源码剖析系列】java源码剖析之HashSet
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...
- 框架源码系列六:Spring源码学习之Spring IOC源码学习
Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的 1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...
- 框架源码系列五:学习源码的方法(学习源码的目的、 学习源码的方法、Eclipse里面查看源码的常用快捷键和方法)
一. 学习源码的目的 1. 为了扩展和调优:掌握框架的工作流程和原理 2. 为了提升自己的编程技能:学习他人的设计思想.编程技巧 二. 学习源码的方法 方法一: 1)掌握研究的对象和研究对象的核心概念 ...
- 沐雪多用户微信公众平台开发源码,商城小程序源码(2018年最新的asp.net C# 微信源码,小程序源码)
现售价5400元,就可以搭建自己的微信平台啦 购买地址:https://item.taobao.com/item.htm?id=539102325336 该系统是由[上海沐雪网络]独家授权销售,其他地 ...
随机推荐
- 《Go语言实战》读书笔记
<Go语言实战>中文版pdf 百度网盘: https://pan.baidu.com/s/1kr-gMzaPAn8BFZG0P24Oiw 提取码: r6rt 书籍源码:https://gi ...
- 在easyui-tabs中的href或 content的多种条件下的不同页面内容和页面地址的赋值?
$('#tt').tabs('add', {.....});中 的 加载内容, 可以用content, 或用 href都是可以的. 虽然它们加载 的方式不一样, 但是 只要是加载进去后, 加载成功后, ...
- git 常用命令的总结
1. git 查看分支 git branch (星号代表当前的分支) 2. 创建一个本地分支 git checkout -b 分支名称 3. 将本地新建分支提交到远程 git push origin ...
- 运维笔记--线上服务器git环境配置
场景描述: 我们采用git去管理代码分支,本地开发环境,线上服务器多数情况下也会使用git去管理程序代码,那么新的一台服务器,如果指定了目标路径作为代码存放路径,该如何配置git环境, 以达到跟远程服 ...
- 深入理解JVM虚拟机
JVM平台上还可以运行其他语言,运行的是Class字节码.只要能翻译成Class的语言就OK了.挺强大的. JVM厂商很多 垃圾收集器.收集算法 JVM检测工具 关于类的加载: Java代码中,类型( ...
- springboot:非web启动
需要运行一些调度任务,但是又不想放到web容器中运行. 见红色代码: import java.util.concurrent.ThreadPoolExecutor; import org.spring ...
- spring boot实现切割分片上传
文件上传是web开发中经常会遇到的 springboot的默认配置为10MB,大于10M的是传不上服务器的,需要修改默认配置 但是如果修改支持大文件又会增加服务器的负担. 当文件大于一定程度时,不仅服 ...
- LeetCode 1089. 复写零(Duplicate Zeros) 72
1089. 复写零 1089. Duplicate Zeros 题目描述 给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移. 注意:请不要在超过该数组长 ...
- Windows下安装gcc环境
安装GCC环境 https://gcc.gnu.org/ 点进去后 然后 然后 点击 再点击 点击 (啊,这是跳了多少个页面) 开始下载了.完成之后打开:(自动执行的) 弹出 点击OK,弹出个窗口,让 ...
- SQL Server 参数嗅探问题
摘要 MSSQL Server参数嗅探既是一个涉及知识面非常广泛,又是一个比较难于解决的课题,即使对于数据库老手也是一个比较头痛的问题.这篇文章从参数嗅探是什么,如何产生,表象是什么,会带来哪些问题, ...