#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)源码的更多相关文章

  1. [spring源码学习]十、IOC源码-conversionService

    一.代码示例 1.我们在之前的Person类里新增一个两个属性,分别是客户的兴趣和生日,兴趣爱好有很多,我们使用list进行保存,生日使用日期进行保存 public class Person { pr ...

  2. 如何在Eclipse中查看Android源码或者第三方组件包源码

    文章出处:http://blog.csdn.net/cjjky/article/details/6535426 在学习过程中如果经常阅读源码,理解程度会比较深,学习效率也会比较高,那么如何方便快捷的阅 ...

  3. android狼人杀源码,桌面源码,猎豹快切源码

    Android精选源码 android实现狼人杀app源码 android实现精心打造的Android基础框架源码 android热门电影的客户端源码 android 实现桌面的Launcher源码 ...

  4. android企业级商城源码、360°全景图VR源码、全民直播源码等

    Android精选源码 [新版]Android技术博客精华汇总 开源了:乐乐音乐5.0-Android音乐播放器 android实现仿真水波纹效果源码 360°全景图VR,这是一个值得把玩的APP a ...

  5. 【java集合框架源码剖析系列】java源码剖析之TreeSet

    本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...

  6. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

  7. 框架源码系列六:Spring源码学习之Spring IOC源码学习

    Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的  1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...

  8. 框架源码系列五:学习源码的方法(学习源码的目的、 学习源码的方法、Eclipse里面查看源码的常用快捷键和方法)

    一. 学习源码的目的 1. 为了扩展和调优:掌握框架的工作流程和原理 2. 为了提升自己的编程技能:学习他人的设计思想.编程技巧 二. 学习源码的方法 方法一: 1)掌握研究的对象和研究对象的核心概念 ...

  9. 沐雪多用户微信公众平台开发源码,商城小程序源码(2018年最新的asp.net C# 微信源码,小程序源码)

    现售价5400元,就可以搭建自己的微信平台啦 购买地址:https://item.taobao.com/item.htm?id=539102325336 该系统是由[上海沐雪网络]独家授权销售,其他地 ...

随机推荐

  1. 《Go语言实战》读书笔记

    <Go语言实战>中文版pdf 百度网盘: https://pan.baidu.com/s/1kr-gMzaPAn8BFZG0P24Oiw 提取码: r6rt 书籍源码:https://gi ...

  2. 在easyui-tabs中的href或 content的多种条件下的不同页面内容和页面地址的赋值?

    $('#tt').tabs('add', {.....});中 的 加载内容, 可以用content, 或用 href都是可以的. 虽然它们加载 的方式不一样, 但是 只要是加载进去后, 加载成功后, ...

  3. git 常用命令的总结

    1. git 查看分支 git branch (星号代表当前的分支) 2. 创建一个本地分支 git checkout -b 分支名称 3. 将本地新建分支提交到远程 git push origin ...

  4. 运维笔记--线上服务器git环境配置

    场景描述: 我们采用git去管理代码分支,本地开发环境,线上服务器多数情况下也会使用git去管理程序代码,那么新的一台服务器,如果指定了目标路径作为代码存放路径,该如何配置git环境, 以达到跟远程服 ...

  5. 深入理解JVM虚拟机

    JVM平台上还可以运行其他语言,运行的是Class字节码.只要能翻译成Class的语言就OK了.挺强大的. JVM厂商很多 垃圾收集器.收集算法 JVM检测工具 关于类的加载: Java代码中,类型( ...

  6. springboot:非web启动

    需要运行一些调度任务,但是又不想放到web容器中运行. 见红色代码: import java.util.concurrent.ThreadPoolExecutor; import org.spring ...

  7. spring boot实现切割分片上传

    文件上传是web开发中经常会遇到的 springboot的默认配置为10MB,大于10M的是传不上服务器的,需要修改默认配置 但是如果修改支持大文件又会增加服务器的负担. 当文件大于一定程度时,不仅服 ...

  8. LeetCode 1089. 复写零(Duplicate Zeros) 72

    1089. 复写零 1089. Duplicate Zeros 题目描述 给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移. 注意:请不要在超过该数组长 ...

  9. Windows下安装gcc环境

    安装GCC环境 https://gcc.gnu.org/ 点进去后 然后 然后 点击 再点击 点击 (啊,这是跳了多少个页面) 开始下载了.完成之后打开:(自动执行的) 弹出 点击OK,弹出个窗口,让 ...

  10. SQL Server 参数嗅探问题

    摘要 MSSQL Server参数嗅探既是一个涉及知识面非常广泛,又是一个比较难于解决的课题,即使对于数据库老手也是一个比较头痛的问题.这篇文章从参数嗅探是什么,如何产生,表象是什么,会带来哪些问题, ...