本文共 3652 字,大约阅读时间需要 12 分钟。
1. 初始化 AVCodecContext *m_avctx; AVCodec *m_codec; /* Init ffmpeg log */ ffmpeg_log_callback pcb_log = libffmpeg_log_callback; av_log_set_level(AV_LOG_DEBUG); av_log_set_flags(AV_LOG_SKIP_REPEATED); av_log_set_callback(pcb_log); printf("Current ffmpeg log_level = %d\n", av_log_get_level()); /* Open the encoder. */ m_codec = avcodec_find_encoder(AV_CODEC_ID_AAC); if (!m_codec){ printf("Codec not found\n"); exit(1); } m_avctx = avcodec_alloc_context3(m_codec); if (!m_avctx) { printf("Could not allocate audio codec context\n"); exit(1); } m_avctx->codec_type = AVMEDIA_TYPE_AUDIO; m_avctx->codec_id = AV_CODEC_ID_AAC; m_avctx->bit_rate = m_audio_bitrate; m_avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (!check_sample_fmt(m_codec, m_avctx->sample_fmt)) { printf("Encoder does not support sample format %s", av_get_sample_fmt_name(m_avctx->sample_fmt)); exit(1); } m_avctx->sample_rate = m_audio_clock_rate; m_avctx->channels = m_audio_channel_num; m_avctx->channel_layout = (m_audio_channel_num == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; m_avctx->time_base = (AVRational){1, m_avctx->sample_rate}; /* open it */ if (avcodec_open2(m_avctx, m_codec, NULL) < 0) { printf("Could not open codec\n"); exit(1); }2. 调用NOTE: 1. 这里只举了个简单的例子, PCM数据是用伪码实现的;2. PCM的数据格式要和编码器相匹配, 即 编码器要求是: AV_SAMPLE_FMT_S16,则输入的PCM数据也要是 AV_SAMPLE_FMT_S16 通常,ffmpeg原生的AAC编码器 : AV_SAMPLE_FMT_FLT libfaac : AV_SAMPLE_FMT_S16 libfdk-aac : AV_SAMPLE_FTM_FLTP for (int i = 0 ; i < XXX; i++) { /* Encode by Using ffmpeg-4.0 */ AVPacket *pkt; AVFrame *frame; uint16_t *samples; pkt = av_packet_alloc(); if (!pkt) { printf("could not allocate the packet\n"); exit(1); } /* frame containing input raw audio */ frame = av_frame_alloc(); if (!frame) { printf("Could not allocate audio frame\n"); exit(1); } frame->nb_samples = m_avctx->frame_size; frame->format = m_avctx->sample_fmt; frame->channel_layout = m_avctx->channel_layout; /* allocate the data buffers */ ret = av_frame_get_buffer(frame, 0); if (ret < 0) { printf("Could not allocate audio data buffers\n"); exit(1); } /* make sure the frame is writable -- makes a copy if the encoder * kept a reference internally */ ret = av_frame_make_writable(frame); if (ret < 0){ exit(1); } samples = (uint16_t*)frame->data[0]; /* 复制一帧待编码的PCM数据 */ int in_pcm_buffer_size = 1024; uint8_t *in_pcm_buffer; // 输入的数据 memcpy(samples, in_pcm_buffer, in_pcm_buffer_size); /* send the frame for encoding */ ret = avcodec_send_frame(m_avctx, frame); if (ret < 0) { printf("Error sending the frame to the encoder\n"); exit(1); } ret = avcodec_receive_packet(m_avctx, pkt); if (ret == AVERROR(EAGAIN) ){ printf("Encoding audio frame again! \n"); } else if (ret == AVERROR_EOF) { printf("Encoding audio frame EOF! \n"); } else if (ret < 0) { printf("Error encoding audio frame\n"); exit(1); } /* 将编码后的数据输出*/ if (pkt->size > 0){ memcpy(aac_buf, pkt->data, pkt->size); aac_size = pkt->size; } av_packet_unref(pkt); av_frame_free(&frame); av_packet_free(&pkt);}/* 资源释放 */ if (m_avctx) { avcodec_close(m_avctx); av_free(m_avctx); m_avctx = NULL; }
转载地址:http://ejctd.baihongyu.com/