オーディオコーディングパッケージFFMPEG

Androidの準備のためのFFMPEG 4.0

FFMPEG4.0オーディオデコードカプセル化解除

最新のFFMPEG 4.0(4.X)に基づいて、次の関数法:

この記事では、ファイルが以前と組み合わせて、我々は、元のデータを使用する必要があるオーディオ形式、生成された、PCMファイルからの生データを取得する方法に焦点を当てFFMPEG4.0オーディオ復号化ソリューションパッケージを、あなたはオーディオフォーマット変換を達成することができるようになります。

ファイルから読み込んだPCMデータは、MP3形式を生成しました。
まず、初期出力

 AVFormatContext *fmt_ctx;
    int ret = avformat_alloc_output_context2(&fmt_ctx,NULL,NULL,out_file);
 ret = avio_open(&fmt_ctx->pb,out_file,AVIO_FLAG_WRITE);

以下の変数は、オーディオおよびビデオ符号化フォーマットを生成することをさらに含む、出力フォーマット情報を保たれ、必要ではありません。

AVOutputFormat *ofmt;
ofmt = fmt_ctx->oformat;

第二に、エンコーダ、ストリームの符号化パラメータセットを準備

encodec = avcodec_find_encoder(AV_CODEC_ID_MP3);//可通过ofmt->audio_codec得到格式
st = avformat_new_stream(fmt_ctx,encodec);
encodec_ctx = avcodec_alloc_context3(encodec);

encodec_ctx->sample_rate = 44100;
encodec_ctx->bit_rate = 64000;
encodec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
encodec_ctx->channel_layout = AV_CH_LAYOUT_STEREO;
encodec_ctx->channels = av_get_channel_layout_nb_channels(encodec_ctx->channel_layout);

第三に、オープンエンコーダ、データを取得するサンプル数

ret = avcodec_open2(encodec_ctx,encodec,NULL);
int encode_nb_sample = encodec_ctx->frame_size;

第四に、初期化フレームとパケット

    frame = av_frame_alloc();
    pkt = av_packet_alloc();
    frame->nb_samples = encode_nb_sample;
    frame->format = encodec_ctx->sample_fmt;
    frame->channel_layout = encodec_ctx->channel_layout;

    //frame.data 需要申请的字节数
    int size = av_samples_get_buffer_size(NULL,encodec_ctx->channels,encode_nb_sample,encodec_ctx->sample_fmt,1);
    uint8_t *frame_buf = (uint8_t *) av_malloc(size);
avcodec_fill_audio_frame(frame,encodec_ctx->channels,encodec_ctx->sample_fmt,frame_buf,size,1);

メモリ割り当てのフレームデータの上記方法は、以下のメソッドを呼び出すことによって、(メソッドをサンプリング)を達成することができます。
ret = av_frame_get_buffer(frame, 0);

リサンプリングのPCMデータが読み出される変換データを取得したサンプル数がサンプルの数に応じて算出されたファイルから読み込まれる(サンプリングレートは、44,100サンプルのPCMである)(例は、本明細書中にネットワーク上にあるフレームデータを生成!彼らの例では、サンプルレートは変更されません何の問題は、再生時間の変化)がない間違っています:
int in_nb_sample = av_rescale_rnd(frame->nb_samples,44100,encodec_ctx->sample_rate,AV_ROUND_UP);

所望のデータ変換のbufサイズの計算:

int readSize = in_nb_sample * av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO) * av_get_bytes_per_sample(in_fmt);
char *read_buf = (char*)malloc(readSize);

第五に、レプリケーションのパラメータは、ヘッダ情報を書き込みます

    avcodec_parameters_from_context(st->codecpar,encodec_ctx);
    avformat_write_header(fmt_ctx,NULL);

第六に、パラメータ設定リサンプリング

    swc = swr_alloc();
    av_opt_set_int(swc,"in_channel_layout",AV_CH_LAYOUT_STEREO,0);
    av_opt_set_int(swc,"in_sample_rate",in_sample_rate,0);
    av_opt_set_sample_fmt(swc,"in_sample_fmt",in_fmt,0);

    av_opt_set_int(swc,"out_channel_layout",encodec_ctx->channel_layout,0);
    av_opt_set_int(swc,"out_sample_rate",encodec_ctx->sample_rate,0);
    av_opt_set_sample_fmt(swc,"out_sample_fmt",encodec_ctx->sample_fmt,0);
ret = swr_init(swc);

セブンコーディング(以下符号化されたファイルが読み込まれるまで、実際の符号化処理は、以下の行為のサイクルを繰り返すべきである)
、1 PCMはファイルポインタアレイ調製リサンプリングアプローチは、いくつかのffmpegのフレームインタフェースの生成を使用することで読み取りますデータメモリ割り当てたフレームの、本質は同じです。

        if (fread(read_buf, 1, readSize, infile) < 0) {
            printf("文件读取错误!\n");
            return -1;
        } else if (feof(infile)) {
            break;
        }
        //重采样源数据
        const uint8_t *indata[AV_NUM_DATA_POINTERS] = {0};
        indata[0] = (uint8_t *) read_buf;

2.リサンプリングは、PTSを提供しました

        int len = swr_convert(swc, frame->data, frame->nb_samples,indata, in_nb_sample);
        LOGV("len = %d\n",len);
        frame->pts = apts;
        apts += av_rescale_q(len,(AVRational){1,encodec_ctx->sample_rate},encodec_ctx->time_base);

(ノートファイルの読み取りが主にエンコーダをフラッシュするために、一度フレームパスNULLそれを送信する必要が後。そうでないかもしれないwhileループ)3.コーディング

ret = avcodec_send_frame(encodec_ctx, frame);

        while(ret >= 0) {
            LOGV("receiver\n");
            ret = avcodec_receive_packet(encodec_ctx, pkt);
            if (ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "%s,ret = %d\n", "avcodec_receive_packet!error ",ret);
                break;
            }
            pkt->stream_index = st->index;
            av_log(NULL, AV_LOG_DEBUG, "第%d帧\n", i);
            pkt->pts = av_rescale_q(pkt->pts, encodec_ctx->time_base, st->time_base);
            pkt->dts = av_rescale_q(pkt->dts, encodec_ctx->time_base, st->time_base);
            pkt->duration = av_rescale_q(pkt->duration, encodec_ctx->time_base, st->time_base);
            LOGV("duration = %d,dts=%d,pts=%d\n",pkt->duration,pkt->dts,pkt->pts);
            ret = av_write_frame(fmt_ctx, pkt);
            if (ret < 0) {
                av_log(NULL, AV_LOG_ERROR, "av_write_frame error!");
            }
            av_packet_unref(pkt);
        }

4.書き込みターミネータ
av_write_trailer(fmt_ctx);

おすすめ

転載: blog.51cto.com/4095821/2402673