zoukankan      html  css  js  c++  java
  • FFMpeg音频混合,背景音(七):fileter音频混合存入缓存队列

    //FFMpeg版本:3.3.1
    #include<iostream> #include<windows.h> using namespace std; //用到的C的头文件 extern "C" { #include<libavcodec/avcodec.h> #include<libavfilter/avfilter.h> #include<libavfilter/buffersink.h> #include<libavfilter/buffersrc.h> #include<libavfilter/avfiltergraph.h> #include<libavformat/avformat.h> #include<libavutil/avutil.h> #include<libavutil/fifo.h> #include<libavutil/audio_fifo.h> #include<libavdevice/avdevice.h> } //对用到的预编译 #pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avfilter.lib") #pragma comment(lib, "avutil.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "swscale.lib") //第一个音频文件 AVFormatContext* ctx3 = NULL; int ctx3index = -1; AVCodecContext* codec_ctx_three = NULL; AVAudioFifo* ctx3buff = NULL; //第二个音频文件 AVFormatContext* ctx4 = NULL; int ctx4index = -1; AVCodecContext* codec_ctx_four = NULL; AVAudioFifo* ctx4buff = NULL; AVFilterGraph* filter_graph = NULL; AVFilterContext* filter_three_ctx = NULL; AVFilterContext* filter_four_ctx = NULL; AVFilterContext* filter_out_ctx = NULL; //打开输出的文件流IO //输出文件初始化 AVCodecContext* acode = NULL; AVFormatContext* out = NULL; bool status = false; //打开第一个音频文件 int openMp3Codec3(char* filename) { int ret = 0; ret = avformat_open_input(&ctx3, filename, NULL, NULL); if (ret < 0) { cout << "avformat_open_input ctx3 faaild" << endl; return -1; } ret = avformat_find_stream_info(ctx3, NULL); if (ret < 0) { cout << "avformat_find_stream_info ctx3 faaild" << endl; return -1; } for (int i = 0; i < ctx3->nb_streams; i++) { if (ctx3->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { ctx3index = i; break; } } if (ctx3index < 0) { cout << "stream not find ctx3 failed" << endl; return -1; } AVCodec* codec = avcodec_find_decoder(ctx3->streams[ctx3index]->codecpar ->codec_id); if (!codec) { cout << "avcodec_find_decoder ctx3 failed" << endl; return -1; } //根据找到的解码器创造上下文 codec_ctx_three = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx_three, ctx3->streams[ctx3index]->codecpar); avcodec_open2(codec_ctx_three, codec, NULL); if (ret < 0) { cout << "avcodec_open2 ctx3 failed" << endl; return -1; } //第四个参数设置为0,表示输入的音频数据,如果为1的话,就是输出的音频数据 av_dump_format(ctx3, ctx3index, filename,0); return ret; } //打开第二个音频文件 int openMp3Codec4(char* filename) { int ret = 0; ret = avformat_open_input(&ctx4, filename, NULL, NULL); ret = avformat_find_stream_info(ctx4, NULL); for (int i = 0; i < ctx4->nb_streams; i++) { if (ctx4->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { ctx4index = i; break; } } AVCodec* codec = avcodec_find_decoder(ctx4->streams[ctx4index]->codecpar->codec_id); //根据找到的解码器创造上下文 codec_ctx_four = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx_four, ctx4->streams[ctx4index]->codecpar); avcodec_open2(codec_ctx_four, codec, NULL); //第四个参数设置为0,表示输入的音频数据,如果为1的话,就是输出的音频数据 av_dump_format(ctx4, ctx4index, filename, 0); return ret; } int openFileIO(char* filename) { int ret = 0; AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_MP3); if (!codec) { cout << "avcodec_find_encoder faild" << endl; return -1; } acode = avcodec_alloc_context3(codec); if (!acode) { cout << "avcodec_alloc_context3 out faild" << endl; return -1; } acode->sample_rate = 44100; acode->bit_rate = 320000; acode->time_base.num = 1; acode->time_base.den = 44100; acode->channels = 2; acode->channel_layout = AV_CH_LAYOUT_STEREO; acode->sample_fmt = AV_SAMPLE_FMT_S32P; acode->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; ret = avcodec_open2(acode, codec, NULL); if (ret < 0) { cout << "avcodec_open2 out faild" << endl; return -1; } ret = avformat_alloc_output_context2(&out, NULL, NULL, filename); if (ret < 0) { cout << "avformat_alloc_output_context2 out faild" << endl; return -1; } AVStream* audio_stream = avformat_new_stream(out, NULL); audio_stream->codecpar->codec_tag = 0; avcodec_parameters_from_context(audio_stream->codecpar, acode); ret = avio_open(&out->pb, filename, AVIO_FLAG_WRITE); if (ret < 0) { cout << "avio_open out faild" << endl; return -1; } avformat_write_header(out, NULL); ctx3buff = av_audio_fifo_alloc(codec_ctx_three->sample_fmt, ctx3->streams[ctx3index]->codecpar->channels, 30 * codec_ctx_three->frame_size ); ctx4buff = av_audio_fifo_alloc(codec_ctx_four->sample_fmt, ctx4->streams[ctx4index]->codecpar->channels, 30 * codec_ctx_four->frame_size ); return ret; } int InitFilter(const char* filter_desc) { int ret = 0; const char* mp3_three = "in0"; const char* mp3_four = "in1"; //用于装载音频参数 char args_three[512]; char args_four[512]; //寻找输入输出的过滤器 AVFilter * filter_three = avfilter_get_by_name("abuffer"); AVFilter* filter_four = avfilter_get_by_name("abuffer"); AVFilter* filter_out = avfilter_get_by_name("abuffersink"); if (!filter_three || !filter_four || !filter_out) { cout << " avfilter_get_by_name faild" << endl; return -1; } //AVFilterGraph,分配输入输出流 AVFilterInOut* filter_three_inout = avfilter_inout_alloc(); AVFilterInOut* filter_four_inout = avfilter_inout_alloc(); AVFilterInOut* filter_out_inout = avfilter_inout_alloc(); //分配一个过滤图 filter_graph = avfilter_graph_alloc(); if (!filter_graph) { cout << " avfilter_inout_alloc faild" << endl; return -1; } sprintf_s(args_three, sizeof(args_three), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64x", codec_ctx_three->time_base.num, codec_ctx_three->time_base.den, ctx3->streams[ctx3index]->codecpar->sample_rate, av_get_sample_fmt_name(codec_ctx_three->sample_fmt), ctx3->streams[ctx3index]->codecpar->channel_layout ); sprintf_s(args_four, sizeof(args_four), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64x", codec_ctx_four->time_base.num, codec_ctx_four->time_base.den, ctx4->streams[ctx4index]->codecpar->sample_rate, av_get_sample_fmt_name(codec_ctx_four->sample_fmt), ctx4->streams[ctx4index]->codecpar->channel_layout ); //AVFilterContext* filter_three_ctx = NULL; //AVFilterContext* filter_four_ctx = NULL; //AVFilterContext* filter_out_ctx = NULL; ret = avfilter_graph_create_filter(&filter_three_ctx, filter_three, mp3_three, args_three, NULL, filter_graph); if (ret < 0) { cout << "avfilter_graph_create_filter faild" << endl; return -1; } ret = avfilter_graph_create_filter(&filter_four_ctx, filter_four, mp3_four, args_four, NULL, filter_graph); if (ret < 0) { cout << "avfilter_graph_create_filter faild" << endl; return -1; } //初始化AVFilterContext,并将其添加到过滤图,输出的过滤图初始化 ret = avfilter_graph_create_filter(&filter_out_ctx, filter_out, "out", NULL, NULL, filter_graph); if (ret < 0) { cout << "avfilter_graph_create_filter faild" << endl; return -1; } //输出的采样率,样本格式,通道样本布局 ret = av_opt_set_bin(filter_out_ctx, "sample_rates", (uint8_t *)&acode->sample_rate, sizeof(acode->sample_rate), AV_OPT_SEARCH_CHILDREN); if (ret < 0) { cout << "av_opt_set_bin faild" << endl; return -1; } ret = av_opt_set_bin(filter_out_ctx, "channel_layouts", (uint8_t*)&acode->channel_layout, sizeof(acode->channel_layout), AV_OPT_SEARCH_CHILDREN); if (ret < 0) { cout << "av_opt_set_bin faild" << endl; return -1; } ret = av_opt_set_bin(filter_out_ctx, "sample_fmts", (uint8_t*)&acode->sample_fmt, sizeof(acode->sample_fmt), AV_OPT_SEARCH_CHILDREN); if (ret < 0) { cout << "av_opt_set_bin faild" << endl; return -1; } //AVFilterGraph分配输入输出流 filter_three_inout->name = av_strdup(mp3_three); filter_three_inout->filter_ctx = filter_three_ctx; filter_three_inout->pad_idx = 0; filter_three_inout->next = filter_four_inout; filter_four_inout->name = av_strdup(mp3_four); filter_four_inout->filter_ctx = filter_four_ctx; filter_four_inout->pad_idx = 0; filter_four_inout->next = NULL; filter_out_inout->name = av_strdup("out"); filter_out_inout->filter_ctx = filter_out_ctx; filter_out_inout->pad_idx = 0; filter_out_inout->next = NULL; AVFilterInOut* filter_outputs[2]; filter_outputs[0] = filter_three_inout; filter_outputs[1] = filter_four_inout; //将描述的过滤图添加到对象中 ret = avfilter_graph_parse_ptr(filter_graph, filter_desc, &filter_out_inout, filter_outputs, NULL); if (ret < 0) { cout << "avfilter_graph_parse_ptr faild" << endl; return -1; } //检查过滤图所有链接格式 ret = avfilter_graph_config(filter_graph, NULL); if (ret < 0) { cout << " avfilter_graph_config faild" << endl; return -1; } char *infos = avfilter_graph_dump(filter_graph, NULL); printf("%s ", infos); return ret; } DWORD WINAPI three_demux(LPVOID IpParam) { int ret = 0; AVPacket packet; av_init_packet(&packet); AVFrame* pFrame = av_frame_alloc(); while (status) { packet.data = NULL; packet.size = 0; //读取数据 ret = av_read_frame(ctx3, &packet); if (ret < 0) { av_packet_unref(&packet); break; } cout << packet.size << endl; //将数据发送到解码线程 ret = avcodec_send_packet(codec_ctx_three, &packet); if (ret < 0) { cout << "avcodec_send_packet faild" << endl; break; } //接受解码后的数据 ret = avcodec_receive_frame(codec_ctx_three, pFrame); int three_size = av_audio_fifo_space(ctx3buff); while (three_size < pFrame->nb_samples && !status) { Sleep(10); three_size = av_audio_fifo_space(ctx3buff); cout<< "ctx3buff full wait" << endl; } //判断缓存队列中可供写入大小 if (three_size >= pFrame->nb_samples) { av_audio_fifo_write(ctx3buff, (void**)pFrame->data, pFrame->nb_samples); } av_packet_unref(&packet); } av_frame_free(&pFrame); return ret; } DWORD WINAPI four_demux(LPVOID IpParam) { int ret = 0; AVPacket packet; AVFrame* pFrame = av_frame_alloc(); av_init_packet(&packet); while (status) { packet.data = NULL; packet.size = 0; ret = av_read_frame(ctx4, &packet); if (ret < 0) { av_packet_unref(&packet); break; } cout << packet.size << endl; ret = avcodec_send_packet(codec_ctx_four, &packet); if (ret < 0) { cout << "avcodec_send_packet faild" << endl; break; } ret = avcodec_receive_frame(codec_ctx_four, pFrame); int four_size = av_audio_fifo_space(ctx4buff); while (four_size < pFrame->nb_samples && !status) { Sleep(10); four_size = av_audio_fifo_space(ctx4buff); cout << "ctx3buff full wait" << endl; } if (four_size >= pFrame->nb_samples) { av_audio_fifo_write(ctx4buff, (void**)pFrame->data, pFrame->nb_samples); } av_packet_unref(&packet); } av_frame_free(&pFrame); return ret; } int main() { //注册 av_register_all(); avcodec_register_all(); avfilter_register_all(); int ret = 0; char input3[] = "3.mp3"; char input4[] = "4.mp3"; ret = openMp3Codec3(input3); if (ret < 0) { cout << "openMp3Codec3 faild" << endl; return -1; } ret = openMp3Codec4(input4); if (ret < 0) { cout << "openMp3Codec4 faild" << endl; return -1; } char outfile[] = "out.mp3"; ret = openFileIO(outfile); if (ret < 0) { cout << "openFileIO faild" << endl; return -1; } //过滤器配置 const char* filter_desc = "[in0][in1]amix=inputs=2[out]"; ret = InitFilter(filter_desc); if (ret < 0) { cout << "InitFilter faild" << endl; return -1; } status = true; CreateThread(NULL, 0, three_demux, 0, 0, NULL); CreateThread(NULL, 0, four_demux, 0, 0, NULL); while (status) { } return 0; }
  • 相关阅读:
    LeetCode 121. Best Time to Buy and Sell Stock
    LeetCode 221. Maximal Square
    LeetCode 152. Maximum Product Subarray
    LeetCode 53. Maximum Subarray
    LeetCode 91. Decode Ways
    LeetCode 64. Minimum Path Sum
    LeetCode 264. Ugly Number II
    LeetCode 263. Ugly Number
    LeetCode 50. Pow(x, n)
    LeetCode 279. Perfect Squares
  • 原文地址:https://www.cnblogs.com/zhangxianrong/p/13879051.html
Copyright © 2011-2022 走看看