微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ffmpeg转码

我想用ffmpeg库做一个音频转码.现在我有文件,但我只能听到噪音.
我的计划的步骤是:
1)打开输入文件并使用avcodec_decode_audio4以原始格式解码
2)编码并保存原始格式.
我不知道我错在哪里.这是我的代码.

/* 
 * File:   newmain.c
 * Author: antonello
 *
 * Created on 23 gennaio 2013,11.24
 */

#include <stdio.h>
#include <stdlib.h>


#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libavcodec/old_codec_ids.h>

static AVCodecContext *get_encoder(int sampleRate,int channels,int audioBitrate)
{ 
    AVCodecContext  *audioCodec;
    AVCodec *codec;



    //Set up audio encoder
    codec = avcodec_find_encoder(CODEC_ID_AAC);
    if (codec == NULL) 
    {
        printf("avcodec_find_encoder: ERROR\n");
        return NULL;
    }
    audioCodec = avcodec_alloc_context();
    audioCodec->bit_rate = audioBitrate;
    audioCodec->sample_fmt = AV_SAMPLE_FMT_S16P;
    audioCodec->sample_rate = sampleRate;
    audioCodec->channels = channels;
    audioCodec->profile = FF_PROFILE_AAC_MAIN;
    audioCodec->channel_layout=AV_CH_LAYOUT_MONO;
    //audioCodec->time_base = (AVRational){1,sampleRate};
    audioCodec->time_base.num  = 1;
    audioCodec->time_base.den  = sampleRate;

    audioCodec->codec_type = AVMEDIA_TYPE_AUdio;
    if (avcodec_open(audioCodec,codec) < 0) 
    {
        printf("avcodec_open: ERROR\n");
        return NULL;
    }

    return audioCodec;
}


int main(int argc,char** argv) {
  AVFormatContext *aFormatCtx_decoder = NULL;
  AVFormatContext *aFormatCtx_encoder = NULL;
  int             i,audioStream;
  AVPacket        packet_decoder;
  AVPacket        packet_encoder;
  int             got_frame=0;
  int             complete_decode=0;
  int             len;
  AVFrame         *decoded_frame = NULL;
  AVCodecContext  *aCodec_decoderCtx = NULL;
  AVCodec         *aCodec_decoder = NULL;
  FILE            *outfile;
  //reding input file
  avcodec_register_all();

   //register all codecs
    av_register_all();

 //open file
    if(avformat_open_input(&aFormatCtx_decoder,"sample.aac",NULL,NULL)!=0){
        fprintf(stderr,"Could not open source file \n");
        return -1; // Couldn't open file
    }

  // Retrieve stream information
  if(avformat_find_stream_info(aFormatCtx_decoder,NULL)<0){
      fprintf(stderr,"Couldn't find stream information \n");
      return -1; // Couldn't find stream information
  }

  // Dump information about file onto standard error
  //av_dump_format(aFormatCtx_decode,argv[1],0);

  // Find the first audio stream
  audioStream=-1;

  for(i=0; i<aFormatCtx_decoder->nb_streams; i++) {
    if(aFormatCtx_decoder->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUdio &&
       audioStream < 0) {
      audioStream=i;
    }
  }
  if(audioStream==-1){
      fprintf(stderr,"File haven't sudio stream \n");
      return -1;
  }

  //get audio codec contex
  aCodec_decoderCtx=aFormatCtx_decoder->streams[audioStream]->codec;
  //get audio codec
  aCodec_decoder = avcodec_find_decoder(aCodec_decoderCtx->codec_id);
  aCodec_decoder->sample_fmts=AV_SAMPLE_FMT_S16P;
  if(!aCodec_decoder) {
    fprintf(stderr,"Unsupported codec!\n");
    return -1;//Unsupported codec!
  }
  //open codec
  // Open codec
  if(avcodec_open2(aCodec_decoderCtx,aCodec_decoder,NULL)<0)
    return -1; // Could not open codec
  // allocate audio frame
  decoded_frame = avcodec_alloc_frame();
  if (!decoded_frame) {
    fprintf(stderr,"Could not allocate audio frame\n");
    return -1;//Could not allocate audio frame
    }
  aCodec_decoderCtx->bit_rate=12000;
  aFormatCtx_encoder=get_encoder(8000,1,12000);
  av_init_packet(&packet_encoder);

  printf("param %d %d %d",aCodec_decoderCtx->sample_fmt,aCodec_decoderCtx->channels,aCodec_decoderCtx->bit_rate);

  outfile = fopen("out.aac","wb");
    if (!outfile) {
        printf(stderr,"Could not open outfile \n");
        return -1;//Could not open outfile
    }
  while(av_read_frame(aFormatCtx_decoder,&packet_decoder)>=0) {
     // decode frame
     len = avcodec_decode_audio4(aCodec_decoderCtx,decoded_frame,&got_frame,&packet_decoder);
        if (len < 0) {
            fprintf(stderr,"Error while decoding\n");
            return -1;
            }

        if (got_frame){
          avcodec_encode_audio2(aFormatCtx_encoder,&packet_encoder,&complete_decode);
          if(complete_decode){
          //    printf("complete decode frame");
              fwrite(packet_encoder.data,packet_encoder.size,outfile);
              av_free_packet(&packet_encoder);
          }
        }



    }
  fclose(outfile);
    return (EXIT_SUCCESS);
}

解决方法

您不能设置变量sample_fmts的任意值:

aCodec_decoder-> sample_fmts = AV_SAMPLE_FMT_S16P; // 这是不对的

将始终使用编解码器设置的参数执行解码.您必须创建SwrContext并执行到目标的格式转换(SwrContext转换样本格式,采样率和通道布局)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐