From 7b7787f638ab5295a727a1761e0c81c50cd57eaa Mon Sep 17 00:00:00 2001 From: dijunkun Date: Tue, 21 Nov 2023 22:32:06 -0800 Subject: [PATCH] Add audio capture test --- test/audio_capture/audio_capture.cpp | 83 ++++++++++++++++ test/audio_capture/sdl2_audio_capture.cpp | 105 ++++++++++++++++++++ test/{ => screen_capture}/linux_capture.cpp | 0 xmake.lua | 17 +++- 4 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 test/audio_capture/audio_capture.cpp create mode 100644 test/audio_capture/sdl2_audio_capture.cpp rename test/{ => screen_capture}/linux_capture.cpp (100%) diff --git a/test/audio_capture/audio_capture.cpp b/test/audio_capture/audio_capture.cpp new file mode 100644 index 0000000..0f84ff6 --- /dev/null +++ b/test/audio_capture/audio_capture.cpp @@ -0,0 +1,83 @@ +#include + +#ifdef _WIN32 +// Windows +extern "C" { +#include +#include +#include +#include +#include +}; +#else +// Linux... +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include +#include +#ifdef __cplusplus +}; +#endif +#endif + +int main(int argc, char **argv) { + int ret = 0; + char errors[1024] = {0}; + // context + AVFormatContext *fmt_ctx = NULL; // ffmpeg下的“文件描述符” + + // paket + int count = 0; + AVPacket pkt; + + // create file + char *out = "audio_old.pcm"; + FILE *outfile = fopen(out, "wb+"); + + char *devicename = "default"; + // register audio device + avdevice_register_all(); + + // get format + AVInputFormat *iformat = (AVInputFormat *)av_find_input_format("sndio"); + + // open audio + if ((ret = avformat_open_input(&fmt_ctx, devicename, iformat, NULL)) < 0) { + av_strerror(ret, errors, 1024); + printf("Failed to open audio device, [%d]%s\n", ret, errors); + return -1; + } + + // 查找音频流信息 + if (avformat_find_stream_info(fmt_ctx, NULL) < 0) { + printf("111\n"); + return -1; + } + + // 寻找第一个音频流索引 + int audioStreamIndex = + av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); + if (audioStreamIndex < 0) { + printf("222\n"); + return -1; + } + + av_init_packet(&pkt); + // read data form audio + while (ret = (av_read_frame(fmt_ctx, &pkt)) == 0 && count++ < 10000) { + av_log(NULL, AV_LOG_INFO, "pkt size is %d(%p), count=%d\n", pkt.size, + pkt.data, count); + fwrite(pkt.data, 1, pkt.size, outfile); + fflush(outfile); + av_packet_unref(&pkt); // release pkt + } + + fclose(outfile); + avformat_close_input(&fmt_ctx); // releas ctx + + return 0; +} \ No newline at end of file diff --git a/test/audio_capture/sdl2_audio_capture.cpp b/test/audio_capture/sdl2_audio_capture.cpp new file mode 100644 index 0000000..60f61a8 --- /dev/null +++ b/test/audio_capture/sdl2_audio_capture.cpp @@ -0,0 +1,105 @@ +#include +#include +#include + +static SDL_AudioDeviceID input_dev; +static SDL_AudioDeviceID output_dev; + +static Uint8 *buffer = 0; +static int in_pos = 0; +static int out_pos = 0; + +char *out = "audio_old.pcm"; +FILE *outfile = fopen(out, "wb+"); + +void cb_in(void *userdata, Uint8 *stream, int len) { + // If len < 4, the printf below will probably segfault + + // fwrite(stream, 1, len, outfile); + // fflush(outfile); + + // SDL_memcpy(stream, buffer + in_pos, len); + // in_pos += len; + // printf("IN: %d\t%d %d %d %d\n", in_pos, stream[0], stream[1], stream[2], + // stream[3]); +} + +void cb_out(void *userdata, Uint8 *stream, int len) { + // If len < 4, the printf below will probably segfault + fwrite(stream, 1, len, outfile); + fflush(outfile); + + // if (out_pos >= in_pos) { + // // Output is way ahead of input; fill with emptiness + // memset(buffer + out_pos, 0, len * sizeof(Uint8)); + // printf("OUT: %d\t(Empty)\n", out_pos); + // } else if (out_pos + len > in_pos) { + // // Output is reaching input; read until reaching input, and leave the + // rest + // // empty + // memset(buffer + out_pos, 0, len * sizeof(Uint8)); + // SDL_memcpy(buffer + out_pos, stream, in_pos - out_pos); + // out_pos = in_pos; + // printf("OUT: %d\t%d %d %d %d (Partial)\n", out_pos, stream[0], stream[1], + // stream[2], stream[3]); + // } else { + // // Input is way ahead of output; read as much as requested + // SDL_memcpy(buffer + out_pos, stream, len); + // out_pos += len; + // printf("OUT: %d\t%d %d %d %d\n", out_pos, stream[0], stream[1], + // stream[2], + // stream[3]); + // } + + // This is to make sure the output device works + // for (int i = 0; i < len; i++) + // stream[i] = (Uint8) random(); +} + +int main() { + SDL_Init(SDL_INIT_AUDIO); + + // 16Mb should be enough; the test lasts 5 seconds + buffer = (Uint8 *)malloc(16777215); + + SDL_AudioSpec want_in, want_out, have_in, have_out; + + SDL_zero(want_out); + want_out.freq = 48000; + want_out.format = AUDIO_U16LSB; + want_out.channels = 2; + want_out.samples = 960; + want_out.callback = cb_out; + + output_dev = SDL_OpenAudioDevice(NULL, 0, &want_out, &have_out, + SDL_AUDIO_ALLOW_ANY_CHANGE); + if (output_dev == 0) { + SDL_Log("Failed to open output: %s", SDL_GetError()); + return 1; + } + + SDL_zero(want_in); + want_in.freq = 48000; + want_in.format = AUDIO_U16LSB; + want_in.channels = 2; + want_in.samples = 960; + want_in.callback = cb_in; + + input_dev = SDL_OpenAudioDevice(NULL, 1, &want_in, &have_in, + SDL_AUDIO_ALLOW_ANY_CHANGE); + if (input_dev == 0) { + SDL_Log("Failed to open input: %s", SDL_GetError()); + return 1; + } + + SDL_PauseAudioDevice(input_dev, 0); + SDL_PauseAudioDevice(output_dev, 0); + + SDL_Delay(5000); + + SDL_CloseAudioDevice(output_dev); + SDL_CloseAudioDevice(input_dev); + free(buffer); + + fclose(outfile); +} diff --git a/test/linux_capture.cpp b/test/screen_capture/linux_capture.cpp similarity index 100% rename from test/linux_capture.cpp rename to test/screen_capture/linux_capture.cpp diff --git a/xmake.lua b/xmake.lua index e0bcf4f..eaee4ef 100644 --- a/xmake.lua +++ b/xmake.lua @@ -77,12 +77,23 @@ target("remote_desk") os.rm("$(projectdir)/out/lib") end) --- target("linux_capture") +-- target("screen_capture") -- set_kind("binary") -- add_packages("sdl2", "imgui", "ffmpeg", "openh264") --- add_files("test/linux_capture.cpp") +-- add_files("test/screen_capture/linux_capture.cpp") -- add_ldflags("-lavformat", "-lavdevice", "-lavfilter", "-lavcodec", -- "-lswscale", "-lavutil", "-lswresample", -- "-lasound", "-lxcb-shape", "-lxcb-xfixes", "-lsndio", "-lxcb", -- "-lxcb-shm", "-lXext", "-lX11", "-lXv", "-lpthread", "-lSDL2", "-lopenh264", --- "-ldl" ,{force = true}) \ No newline at end of file +-- "-ldl", {force = true}) + +target("audio_capture") + set_kind("binary") + add_packages("ffmpeg") + add_files("test/audio_capture/sdl2_audio_capture.cpp") + add_includedirs("test/audio_capture") + add_ldflags("-lavformat", "-lavdevice", "-lavfilter", "-lavcodec", + "-lswscale", "-lavutil", "-lswresample", + "-lasound", "-lxcb-shape", "-lxcb-xfixes", "-lsndio", "-lxcb", + "-lxcb-shm", "-lXext", "-lX11", "-lXv", "-lpthread", "-lSDL2", "-lopenh264", + "-ldl", {force = true}) \ No newline at end of file