ffmpeg把pcm编码为aac

avatar
作者
筋斗云
阅读量:0

version

#define LIBSWRESAMPLE_VERSION_MAJOR 2

#define LIBSWRESAMPLE_VERSION_MINOR 9

#define LIBSWRESAMPLE_VERSION_MICRO 100

#define LIBAVCODEC_VERSION_MINOR 31

#define LIBAVCODEC_VERSION_MICRO 102

code

void CFfmpegOps::EncodePCMToAAC(const char *pcm_file, const char *aac_file) {     AVFormatContext *fmt_ctx = nullptr;     const AVOutputFormat *out_fmt = nullptr;     int ret = -1;     AVStream *avstream = nullptr;     const AVCodec *codec = nullptr;     AVCodecContext *codec_ctx = nullptr;     AVFrame *avframe = nullptr;       // pcm file对应的avframe     AVFrame *codec_avframe = nullptr; // 编码器接收的avframe     AVPacket *avpacket = nullptr;     int frame_data_bytes = 0;     FILE *in_fp = nullptr;     size_t n = 0;     int64_t pts = 0;     struct SwrContext *swr_ctx = nullptr; // 音频帧转换器     AVChannelLayout src_channel_layout;     AVChannelLayout dest_channel_layout;      codec = avcodec_find_encoder(AV_CODEC_ID_AAC);     if (!codec)     {         printf("avcodec_find_encoder error\n");         goto END;     }      codec_ctx = avcodec_alloc_context3(codec);     if (!codec_ctx)     {         printf("avcodec_alloc_context3 error\n");         goto END;     }     codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP; // 编码器的接受的采样格式     codec_ctx->sample_rate = 44100;     codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO;     codec_ctx->channels = av_get_channel_layout_nb_channels(codec_ctx->channel_layout);     codec_ctx->bit_rate = 128000;     codec_ctx->time_base.num = 1;     codec_ctx->time_base.den = codec_ctx->sample_rate;      ret = avcodec_open2(codec_ctx, codec, nullptr);     if (ret < 0)     {         printf("avcodec_open2 error(%s)\n", GetFfmpegERR(ret));         goto END;     }     printf("codec_ctx->frame_size:%d\n", codec_ctx->frame_size);      codec_avframe = av_frame_alloc();     if (!codec_avframe)     {         printf("av_frame_alloc error\n");         goto END;     }     codec_avframe->format = codec_ctx->sample_fmt; // pcm的采样格式     codec_avframe->sample_rate = codec_ctx->sample_rate;     codec_avframe->channel_layout = codec_ctx->channel_layout;     codec_avframe->channels = av_get_channel_layout_nb_channels(codec_avframe->channel_layout);     codec_avframe->nb_samples = codec_ctx->frame_size;      ret = av_frame_get_buffer(codec_avframe, 0);     if (ret < 0)     {         printf("av_frame_get_buffer error(%s)\n", GetFfmpegERR(ret));         goto END;     }      avframe = av_frame_alloc();     if (!avframe)     {         printf("av_frame_alloc error\n");         goto END;     }     avframe->format = AV_SAMPLE_FMT_FLT; // pcm的采样格式     avframe->sample_rate = 44100;     avframe->channel_layout = AV_CH_LAYOUT_STEREO;     avframe->channels = av_get_channel_layout_nb_channels(avframe->channel_layout);     avframe->nb_samples = 1024;      ret = av_samples_get_buffer_size(nullptr,                                      avframe->channels,                                      avframe->nb_samples,                                      (AVSampleFormat)(avframe->format),                                      1);     if (ret < 0)     {         printf("av_samples_get_buffer_size error(%s)\n", GetFfmpegERR(ret));         goto END;     }      frame_data_bytes = av_get_bytes_per_sample((AVSampleFormat)(avframe->format)) * av_get_channel_layout_nb_channels(avframe->channel_layout) * avframe->nb_samples;     if (frame_data_bytes != ret)     {         printf("frame_data_bytes != ret\n");         goto END;     }      ret = av_frame_get_buffer(avframe, 0);     if (ret < 0)     {         printf("av_frame_get_buffer error(%s)\n", GetFfmpegERR(ret));         goto END;     }      avpacket = av_packet_alloc();     if (!avpacket)     {         printf("av_packet_alloc error\n");         goto END;     }      ret = avformat_alloc_output_context2(&fmt_ctx, nullptr, nullptr, aac_file);     if (ret < 0)     {         printf("avformat_alloc_output_context2 error(%s)\n", GetFfmpegERR(ret));         goto END;     }     out_fmt = fmt_ctx->oformat; // name:adts    long_name:ADTS AAC      avstream = avformat_new_stream(fmt_ctx, codec);     if (!avstream)     {         printf("avformat_new_stream error\n");         goto END;     }      ret = avcodec_parameters_from_context(avstream->codecpar, codec_ctx);     if (ret < 0)     {         printf("avcodec_parameters_from_context error(%s)\n", GetFfmpegERR(ret));         goto END;     }      if (!(fmt_ctx->flags & AVFMT_FLAG_NOFILLIN))     {         ret = avio_open(&(fmt_ctx->pb), aac_file, AVIO_FLAG_WRITE);         if (ret < 0)         {             printf("avio_open error(%s)\n", GetFfmpegERR(ret));             goto END;         }     }      in_fp = fopen(pcm_file, "rb");     if (!in_fp)     {         printf("fopen error\n");         goto END;     }      // int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask);     ret = av_channel_layout_from_mask(&src_channel_layout, avframe->channel_layout);     if (ret < 0)     {         printf("av_channel_layout_from_mask error(%s)\n", GetFfmpegERR(ret));         goto END;     }      ret = av_channel_layout_from_mask(&dest_channel_layout, codec_avframe->channel_layout);     if (ret < 0)     {         printf("av_channel_layout_from_mask error(%s)\n", GetFfmpegERR(ret));         goto END;     }      // int swr_alloc_set_opts2(struct SwrContext **ps,     //                     const AVChannelLayout *out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,     //                     const AVChannelLayout *in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,     //                     int log_offset, void *log_ctx);      ret = swr_alloc_set_opts2(&swr_ctx,                               &dest_channel_layout, (AVSampleFormat)(codec_avframe->format), codec_avframe->sample_rate,                               &src_channel_layout, (AVSampleFormat)(avframe->format), avframe->sample_rate,                               0, nullptr);     if (ret < 0)     {         printf("swr_alloc_set_opts2 error(%s)\n", GetFfmpegERR(ret));         goto END;     }      ret = avformat_write_header(fmt_ctx, nullptr);     if (ret < 0)     {         printf("avformat_write_header error(%s)\n", GetFfmpegERR(ret));         goto END;     }      while (1)     {         if (feof(in_fp))         {             printf("feof\n");             break;         }          if (av_sample_fmt_is_planar((AVSampleFormat)(avframe->format)))         {             n = fread(avframe->data[0], sizeof(uint8_t), frame_data_bytes / 2, in_fp);             if ((int)n != frame_data_bytes / 2)             {                 printf("n != frame_data_bytes / 2\n");             }              n = fread(avframe->data[1], sizeof(uint8_t), frame_data_bytes / 2, in_fp);             if ((int)n != frame_data_bytes / 2)             {                 printf("n != frame_data_bytes / 2\n");             }         }         else         {             n = fread(avframe->data[0], sizeof(uint8_t), frame_data_bytes, in_fp);             if ((int)n != frame_data_bytes)             {                 printf("n != frame_data_bytes\n");             }         }          ret = swr_convert_frame(swr_ctx, codec_avframe, avframe);         if (ret < 0)         {             printf("swr_convert_frame error(%s)\n", GetFfmpegERR(ret));             goto END;         }          codec_avframe->pts = pts;         ++pts;          ret = avcodec_send_frame(codec_ctx, codec_avframe);         if (ret < 0)         {             if (ret == AVERROR(EAGAIN))             {                 printf("read output first\n");             }             else             {                 printf("avcodec_send_frame error(%s)\n", GetFfmpegERR(ret));                 break;             }         }          while (1)         {             ret = avcodec_receive_packet(codec_ctx, avpacket);             if (ret < 0)             {                 if (ret == AVERROR(EAGAIN))                 {                     printf("send input first\n");                     break;                 }                 else                 {                     printf("avcodec_receive_packet error(%s)\n", GetFfmpegERR(ret));                     break;                 }             }              ret = av_write_frame(fmt_ctx, avpacket);             if (ret < 0)             {                 printf("av_write_frame error(%s)\n", GetFfmpegERR(ret));                 av_packet_unref(avpacket);                 goto END;             }              av_packet_unref(avpacket);         }     }      ret = avcodec_send_frame(codec_ctx, nullptr);     while (1)     {         ret = avcodec_receive_packet(codec_ctx, avpacket);         if (ret < 0)         {             if (ret == AVERROR(EAGAIN))             {                 printf("send input first\n");                 break;             }             else             {                 printf("avcodec_receive_packet error(%s)\n", GetFfmpegERR(ret));                 break;             }         }          ret = av_write_frame(fmt_ctx, avpacket);         if (ret < 0)         {             printf("av_write_frame error(%s)\n", GetFfmpegERR(ret));             av_packet_unref(avpacket);             goto END;         }          av_packet_unref(avpacket);     }      ret = av_write_trailer(fmt_ctx);     if (ret != 0)     {         printf("av_write_trailer error(%s)\n", GetFfmpegERR(ret));         goto END;     }  END:     if (swr_ctx)     {         swr_free(&swr_ctx);         swr_ctx = nullptr;     }     if (in_fp)     {         fclose(in_fp);         in_fp = nullptr;     }     if (avpacket)     {         av_packet_free(&avpacket);         avpacket = nullptr;     }     if (codec_avframe)     {         av_frame_free(&codec_avframe);         codec_avframe = nullptr;     }     if (avframe)     {         av_frame_free(&avframe);         avframe = nullptr;     }     if (codec_ctx)     {         avcodec_free_context(&codec_ctx);         codec_ctx = nullptr;     }      if (fmt_ctx)     {         if (fmt_ctx->pb)         {             avio_close(fmt_ctx->pb);             fmt_ctx->pb = nullptr;         }          avformat_free_context(fmt_ctx);         fmt_ctx = nullptr;     } }

performance

    广告一刻

    为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!