Recorder.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. // Recorder.cpp : Defines the entry point for the console application.
  2. //
  3. #include <exception>
  4. #include <iostream>
  5. extern "C" {
  6. #include "common.h"
  7. }
  8. void capture_screen()
  9. {
  10. try {
  11. av_register_all();
  12. avdevice_register_all();
  13. AVFormatContext *pFormatCtx = avformat_alloc_context();
  14. AVInputFormat *ifmt = av_find_input_format("gdigrab");
  15. avformat_open_input(&pFormatCtx, "desktop", ifmt, NULL);
  16. if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
  17. throw std::exception("could not find stream information");
  18. }
  19. int videoIndex = -1;
  20. for (int i = 0; i < pFormatCtx->nb_streams; i++) {
  21. if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  22. videoIndex = i;
  23. break;
  24. }
  25. }
  26. if (videoIndex == -1)
  27. throw std::exception("could not find a video stream");
  28. AVCodecContext *pDecoderCtx = pFormatCtx->streams[videoIndex]->codec;
  29. //init decoder
  30. AVCodec *pDecoder = avcodec_find_decoder(pDecoderCtx->codec_id);
  31. if (pDecoder == NULL)
  32. throw std::exception("could not find codec");
  33. if (avcodec_open2(pDecoderCtx, pDecoder, NULL) != 0) {
  34. throw std::exception("open codec ffailed");
  35. }
  36. //init transfer and buffer
  37. AVFrame *pFrameRGB, *pFrameYUV;
  38. pFrameRGB = av_frame_alloc();
  39. pFrameYUV = av_frame_alloc();
  40. uint8_t *out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pDecoderCtx->width, pDecoderCtx->height));
  41. avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pDecoderCtx->width, pDecoderCtx->height);
  42. int ret, gotPic = 0;
  43. AVPacket *packet = (AVPacket*)av_malloc(sizeof(AVPacket));
  44. struct SwsContext *imgConvertCtx = NULL;
  45. imgConvertCtx = sws_getContext(
  46. pDecoderCtx->width,
  47. pDecoderCtx->height,
  48. pDecoderCtx->pix_fmt,
  49. pDecoderCtx->width,
  50. pDecoderCtx->height,
  51. AV_PIX_FMT_YUV420P,
  52. SWS_BICUBIC,
  53. NULL, NULL, NULL);
  54. //init encoder
  55. AVCodec *pEncoder = avcodec_find_encoder(AV_CODEC_ID_H264);
  56. if (pEncoder == NULL)
  57. throw std::exception("could not find encoder");
  58. AVCodecContext *pEncoderCtx = avcodec_alloc_context3(pEncoder);
  59. if (pEncoderCtx == NULL)
  60. throw std::exception("could not alloc context for encoder");
  61. pEncoderCtx->codec_id = AV_CODEC_ID_H264;
  62. pEncoderCtx->codec_type = AVMEDIA_TYPE_VIDEO;
  63. pEncoderCtx->pix_fmt = AV_PIX_FMT_YUV420P;
  64. pEncoderCtx->width = pDecoderCtx->width;
  65. pEncoderCtx->height = pDecoderCtx->height;
  66. pEncoderCtx->time_base.num = 1;
  67. pEncoderCtx->time_base.den = 20;//֡��(��һ���Ӷ�����ͼƬ)
  68. pEncoderCtx->bit_rate = 4000000; //������(���������С���Ըı�������Ƶ������)
  69. pEncoderCtx->gop_size = 12;
  70. if (pEncoderCtx->flags & AVFMT_GLOBALHEADER)
  71. pEncoderCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  72. AVDictionary *param = 0;
  73. av_dict_set(&param, "preset", "superfast", 0);
  74. av_dict_set(&param, "tune", "zerolatency", 0);
  75. pEncoder = avcodec_find_encoder(pEncoderCtx->codec_id);
  76. if (pEncoder == NULL)
  77. throw std::exception("could not find encoder by context");
  78. if (avcodec_open2(pEncoderCtx, pEncoder, &param) != 0)
  79. throw std::exception("open encoder failed");
  80. AVFrame *pFrame264 = av_frame_alloc();
  81. int frame264Size = avpicture_get_size(pEncoderCtx->pix_fmt, pEncoderCtx->width, pEncoderCtx->height);
  82. uint8_t *frame264Buf = (uint8_t*)av_malloc(frame264Size);
  83. avpicture_fill((AVPicture*)pFrame264, frame264Buf, pEncoderCtx->pix_fmt, pEncoderCtx->width, pEncoderCtx->height);
  84. AVPacket pkt264;
  85. av_new_packet(&pkt264, frame264Size);
  86. int Y_size = pEncoderCtx->width * pEncoderCtx->height;
  87. for (;;) {
  88. if (av_read_frame(pFormatCtx, packet) < 0) {
  89. break;
  90. }
  91. if (packet->stream_index == videoIndex) {
  92. ret = avcodec_decode_video2(pDecoderCtx, pFrameRGB, &gotPic, packet);
  93. if (ret < 0) {
  94. throw std::exception("decode error");
  95. }
  96. //trans rgb to yuv420 in out_buffer
  97. if (gotPic) {
  98. sws_scale(imgConvertCtx, (const uint8_t* const*)pFrameRGB->data, pFrameRGB->linesize, 0, pDecoderCtx->height, pFrameYUV->data, pFrameYUV->linesize);
  99. gotPic = 0;
  100. pFrame264->data[0] = out_buffer;//Y
  101. pFrame264->data[1] = out_buffer + Y_size;//U
  102. pFrame264->data[2] = out_buffer + Y_size * 5 / 4;//V
  103. ret = avcodec_encode_video2(pEncoderCtx, &pkt264, pFrame264, &gotPic);
  104. if (gotPic == 1) {
  105. printf("264 packet:%d\r\n", pkt264.size);
  106. static FILE *fp = fopen("a.264", "wb+");
  107. fwrite(pkt264.data, 1, pkt264.size, fp);
  108. av_free_packet(&pkt264);
  109. }
  110. }
  111. _sleep(50);
  112. }
  113. av_free_packet(packet);
  114. }//for(;;��
  115. av_free(pFrameYUV);
  116. avcodec_close(pDecoderCtx);
  117. avformat_close_input(&pFormatCtx);
  118. }
  119. catch (std::exception ex) {
  120. printf("%s\r\n", ex.what());
  121. }
  122. }
  123. #include <MMDeviceAPI.h>
  124. #include <AudioClient.h>
  125. #include <AudioPolicy.h>
  126. #define REFTIMES_PER_SEC 10000000
  127. #define REFTIMES_PER_MILLISEC 10000
  128. #define EXIT_ON_ERROR(hres) \
  129. if (FAILED(hres)) { goto Exit; }
  130. #define SAFE_RELEASE(punk) \
  131. if ((punk) != NULL) \
  132. { (punk)->Release(); (punk) = NULL; }
  133. const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
  134. const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
  135. const IID IID_IAudioClient = __uuidof(IAudioClient);
  136. const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
  137. #define MoveMemory RtlMoveMemory
  138. #define CopyMemory RtlCopyMemory
  139. #define FillMemory RtlFillMemory
  140. #define ZeroMemory RtlZeroMemory
  141. #define min(a,b) (((a) < (b)) ? (a) : (b))
  142. //
  143. // WAV file writer.
  144. //
  145. // This is a VERY simple .WAV file writer.
  146. //
  147. //
  148. // A wave file consists of:
  149. //
  150. // RIFF header: 8 bytes consisting of the signature "RIFF" followed by a 4 byte file length.
  151. // WAVE header: 4 bytes consisting of the signature "WAVE".
  152. // fmt header: 4 bytes consisting of the signature "fmt " followed by a WAVEFORMATEX
  153. // WAVEFORMAT: <n> bytes containing a waveformat structure.
  154. // DATA header: 8 bytes consisting of the signature "data" followed by a 4 byte file length.
  155. // wave data: <m> bytes containing wave data.
  156. //
  157. //
  158. // Header for a WAV file - we define a structure describing the first few fields in the header for convenience.
  159. //
  160. struct WAVEHEADER
  161. {
  162. DWORD dwRiff; // "RIFF"
  163. DWORD dwSize; // Size
  164. DWORD dwWave; // "WAVE"
  165. DWORD dwFmt; // "fmt "
  166. DWORD dwFmtSize; // Wave Format Size
  167. };
  168. // Static RIFF header, we'll append the format to it.
  169. const BYTE WaveHeader[] =
  170. {
  171. 'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', 0x00, 0x00, 0x00, 0x00
  172. };
  173. // Static wave DATA tag.
  174. const BYTE WaveData[] = { 'd', 'a', 't', 'a' };
  175. //
  176. // Write the contents of a WAV file. We take as input the data to write and the format of that data.
  177. //
  178. bool WriteWaveFile(HANDLE FileHandle, const BYTE *Buffer, const size_t BufferSize, const WAVEFORMATEX *WaveFormat)
  179. {
  180. DWORD waveFileSize = sizeof(WAVEHEADER) + sizeof(WAVEFORMATEX) + WaveFormat->cbSize + sizeof(WaveData) + sizeof(DWORD) + static_cast<DWORD>(BufferSize);
  181. BYTE *waveFileData = new (std::nothrow) BYTE[waveFileSize];
  182. BYTE *waveFilePointer = waveFileData;
  183. WAVEHEADER *waveHeader = reinterpret_cast<WAVEHEADER *>(waveFileData);
  184. if (waveFileData == NULL)
  185. {
  186. printf("Unable to allocate %d bytes to hold output wave data\n", waveFileSize);
  187. return false;
  188. }
  189. //
  190. // Copy in the wave header - we'll fix up the lengths later.
  191. //
  192. CopyMemory(waveFilePointer, WaveHeader, sizeof(WaveHeader));
  193. waveFilePointer += sizeof(WaveHeader);
  194. //
  195. // Update the sizes in the header.
  196. //
  197. waveHeader->dwSize = waveFileSize - (2 * sizeof(DWORD));
  198. waveHeader->dwFmtSize = sizeof(WAVEFORMATEX) + WaveFormat->cbSize;
  199. //
  200. // Next copy in the WaveFormatex structure.
  201. //
  202. CopyMemory(waveFilePointer, WaveFormat, sizeof(WAVEFORMATEX) + WaveFormat->cbSize);
  203. waveFilePointer += sizeof(WAVEFORMATEX) + WaveFormat->cbSize;
  204. //
  205. // Then the data header.
  206. //
  207. CopyMemory(waveFilePointer, WaveData, sizeof(WaveData));
  208. waveFilePointer += sizeof(WaveData);
  209. *(reinterpret_cast<DWORD *>(waveFilePointer)) = static_cast<DWORD>(BufferSize);
  210. waveFilePointer += sizeof(DWORD);
  211. //
  212. // And finally copy in the audio data.
  213. //
  214. CopyMemory(waveFilePointer, Buffer, BufferSize);
  215. //
  216. // Last but not least, write the data to the file.
  217. //
  218. DWORD bytesWritten;
  219. if (!WriteFile(FileHandle, waveFileData, waveFileSize, &bytesWritten, NULL))
  220. {
  221. printf("Unable to write wave file: %d\n", GetLastError());
  222. delete[]waveFileData;
  223. return false;
  224. }
  225. if (bytesWritten != waveFileSize)
  226. {
  227. printf("Failed to write entire wave file\n");
  228. delete[]waveFileData;
  229. return false;
  230. }
  231. delete[]waveFileData;
  232. return true;
  233. }
  234. //
  235. // Write the captured wave data to an output file so that it can be examined later.
  236. //
  237. void SaveWaveData(BYTE *CaptureBuffer, size_t BufferSize, const WAVEFORMATEX *WaveFormat)
  238. {
  239. HRESULT hr = NOERROR;
  240. SYSTEMTIME st;
  241. GetLocalTime(&st);
  242. char waveFileName[_MAX_PATH] = { 0 };
  243. sprintf(waveFileName, ".\\WAS_%04d-%02d-%02d_%02d_%02d_%02d_%02d.wav",
  244. st.wYear, st.wMonth, st.wDay,
  245. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  246. HANDLE waveHandle = CreateFile(waveFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
  247. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  248. NULL);
  249. if (waveHandle != INVALID_HANDLE_VALUE)
  250. {
  251. if (WriteWaveFile(waveHandle, CaptureBuffer, BufferSize, WaveFormat))
  252. {
  253. printf("Successfully wrote WAVE data to %s\n", waveFileName);
  254. }
  255. else
  256. {
  257. printf("Unable to write wave file\n");
  258. }
  259. CloseHandle(waveHandle);
  260. }
  261. else
  262. {
  263. printf("Unable to open output WAV file %s: %d\n", waveFileName, GetLastError());
  264. }
  265. }
  266. static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt);
  267. static int select_sample_rate(const AVCodec *codec);
  268. BOOL AdjustFormatTo16Bits(WAVEFORMATEX *pwfx)
  269. {
  270. BOOL bRet(FALSE);
  271. if (pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
  272. {
  273. pwfx->wFormatTag = WAVE_FORMAT_PCM;
  274. pwfx->wBitsPerSample = 16;
  275. pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
  276. pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
  277. bRet = TRUE;
  278. }
  279. else if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
  280. {
  281. PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
  282. if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat))
  283. {
  284. pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
  285. pEx->Samples.wValidBitsPerSample = 16;
  286. pwfx->wBitsPerSample = 16;
  287. pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
  288. pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
  289. bRet = TRUE;
  290. }
  291. }
  292. return bRet;
  293. }
  294. #define DEF_CAPTURE_MIC
  295. HRESULT capture_audio()
  296. {
  297. HRESULT hr;
  298. REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
  299. REFERENCE_TIME hnsActualDuration;
  300. UINT32 bufferFrameCount;
  301. UINT32 numFramesAvailable;
  302. IMMDeviceEnumerator *pEnumerator = NULL;
  303. IMMDevice *pDevice = NULL;
  304. IAudioClient *pAudioClient = NULL;
  305. IAudioCaptureClient *pCaptureClient = NULL;
  306. WAVEFORMATEX *pwfx = NULL;
  307. UINT32 packetLength = 0;
  308. BOOL bDone = FALSE;
  309. BYTE *pData;
  310. DWORD flags;
  311. /*CoTaskMemFree(pwfx);
  312. SAFE_RELEASE(pEnumerator)
  313. SAFE_RELEASE(pDevice)
  314. SAFE_RELEASE(pAudioClient)
  315. SAFE_RELEASE(pCaptureClient)*/
  316. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  317. hr = CoCreateInstance(
  318. CLSID_MMDeviceEnumerator, NULL,
  319. CLSCTX_ALL, IID_IMMDeviceEnumerator,
  320. (void**)&pEnumerator);
  321. EXIT_ON_ERROR(hr)
  322. hr = pEnumerator->GetDefaultAudioEndpoint(
  323. eRender, eConsole, &pDevice);
  324. EXIT_ON_ERROR(hr)
  325. hr = pDevice->Activate(
  326. IID_IAudioClient, CLSCTX_ALL,
  327. NULL, (void**)&pAudioClient);
  328. EXIT_ON_ERROR(hr)
  329. hr = pAudioClient->GetMixFormat(&pwfx);
  330. EXIT_ON_ERROR(hr)
  331. //AdjustFormatTo16Bits(pwfx);
  332. hr = pAudioClient->Initialize(
  333. AUDCLNT_SHAREMODE_SHARED,
  334. AUDCLNT_STREAMFLAGS_LOOPBACK| AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
  335. hnsRequestedDuration,
  336. 0,
  337. pwfx,
  338. NULL);
  339. EXIT_ON_ERROR(hr)
  340. size_t persample_size = (pwfx->wBitsPerSample / 8) * pwfx->nChannels;
  341. // Get the size of the allocated buffer.
  342. hr = pAudioClient->GetBufferSize(&bufferFrameCount);
  343. EXIT_ON_ERROR(hr)
  344. hr = pAudioClient->GetService(
  345. IID_IAudioCaptureClient,
  346. (void**)&pCaptureClient);
  347. EXIT_ON_ERROR(hr)
  348. // Calculate the actual duration of the allocated buffer.
  349. hnsActualDuration = (double)REFTIMES_PER_SEC *
  350. bufferFrameCount / pwfx->nSamplesPerSec;
  351. av_register_all();
  352. AVIOContext *output_io_context = NULL;
  353. AVFormatContext *output_format_context = NULL;
  354. AVCodecContext *output_codec_context = NULL;
  355. AVStream *output_stream = NULL;
  356. AVCodec *output_codec = NULL;
  357. const char* out_file = "tdjm.aac";
  358. if (avio_open(&output_io_context, out_file, AVIO_FLAG_READ_WRITE) < 0) {
  359. printf("Failed to open output file!\n");
  360. return -1;
  361. }
  362. output_format_context = avformat_alloc_context();
  363. if (output_format_context == NULL) {
  364. return -1;
  365. }
  366. output_format_context->pb = output_io_context;
  367. output_format_context->oformat = av_guess_format(NULL, out_file, NULL);
  368. output_format_context->url = av_strdup(out_file);
  369. if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC)))
  370. return -1;
  371. int is_support = check_sample_fmt(output_codec, AV_SAMPLE_FMT_S16);
  372. int selected_sample = select_sample_rate(output_codec);
  373. output_stream = avformat_new_stream(output_format_context, NULL);
  374. if (!output_stream)
  375. return -1;
  376. output_codec_context = avcodec_alloc_context3(output_codec);
  377. if (output_codec_context == NULL)
  378. return -1;
  379. output_codec_context->channels = 2;//av_get_channel_layout_nb_channels(pEncoderCtx->channel_layout);
  380. output_codec_context->channel_layout = av_get_default_channel_layout(2); //AV_CH_LAYOUT_STEREO;
  381. output_codec_context->sample_rate = pwfx->nSamplesPerSec;//48000
  382. output_codec_context->sample_fmt = AV_SAMPLE_FMT_FLTP;
  383. output_codec_context->bit_rate = 96000;
  384. output_codec_context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
  385. output_codec_context->time_base.den = pwfx->nSamplesPerSec;
  386. output_codec_context->time_base.num = 1;
  387. if (output_format_context->oformat->flags & AVFMT_GLOBALHEADER) {
  388. output_format_context->oformat->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  389. }
  390. if (avcodec_open2(output_codec_context, output_codec, NULL) < 0)
  391. throw std::exception("open audio encoder failed");
  392. if (avcodec_parameters_from_context(output_stream->codecpar, output_codec_context) < 0)
  393. return -1;
  394. AVFrame *resampled_frame = av_frame_alloc();
  395. resampled_frame->nb_samples = output_codec_context->frame_size;
  396. resampled_frame->channel_layout = output_codec_context->channel_layout;
  397. resampled_frame->format = output_codec_context->sample_fmt;
  398. resampled_frame->sample_rate = output_codec_context->sample_rate;
  399. int resampled_size = av_samples_get_buffer_size(NULL, output_codec_context->channels, output_codec_context->frame_size, output_codec_context->sample_fmt, 0);
  400. uint8_t *resampled_buf = (uint8_t*)av_malloc(resampled_size);
  401. if (avcodec_fill_audio_frame(resampled_frame, output_codec_context->channels, output_codec_context->sample_fmt, resampled_buf, resampled_size, 0) < 0)
  402. return -1;
  403. AVFrame *sample_frame = av_frame_alloc();
  404. sample_frame->nb_samples = 1024;
  405. sample_frame->channel_layout = av_get_default_channel_layout(pwfx->nChannels);
  406. sample_frame->format = AV_SAMPLE_FMT_FLT;
  407. sample_frame->sample_rate = pwfx->nSamplesPerSec;
  408. int sample_size = av_samples_get_buffer_size(NULL, pwfx->nChannels, 1024, AV_SAMPLE_FMT_FLT, 0);
  409. uint8_t *sample_buf = (uint8_t*)av_malloc(sample_size);
  410. avcodec_fill_audio_frame(sample_frame, pwfx->nChannels, AV_SAMPLE_FMT_FLT, sample_buf, sample_size, 0);
  411. AVPacket pkt;
  412. HANDLE hAudioSamplesReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  413. if (hAudioSamplesReadyEvent == NULL)
  414. {
  415. printf("Unable to create samples ready event: %d.\n", GetLastError());
  416. goto Exit;
  417. }
  418. hr = pAudioClient->SetEventHandle(hAudioSamplesReadyEvent);
  419. if (FAILED(hr))
  420. {
  421. printf("Unable to set ready event: %x.\n", hr);
  422. return false;
  423. }
  424. //init resampler
  425. SwrContext *resample_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_FLTP, 48000, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_FLT, 48000, 0, NULL);
  426. int error = swr_init(resample_ctx);
  427. if (error < 0)
  428. return false;
  429. //init FIFO buffer
  430. //start recording
  431. avformat_write_header(output_format_context, NULL);
  432. hr = pAudioClient->Start();
  433. EXIT_ON_ERROR(hr)
  434. int pcmInBuffer = 0;
  435. int copiedPcm = 0;
  436. int gotPacket = 0;
  437. int index = 0;
  438. HANDLE waitArray[3];
  439. waitArray[0] = hAudioSamplesReadyEvent;
  440. uint64_t nextptx = 0;
  441. while (bDone == false)
  442. {
  443. DWORD waitResult = WaitForMultipleObjects(1, waitArray, FALSE, INFINITE);
  444. switch (waitResult)
  445. {
  446. case WAIT_OBJECT_0 + 0: // _AudioSamplesReadyEvent
  447. hr = pCaptureClient->GetNextPacketSize(&packetLength);
  448. while (packetLength != 0)
  449. {
  450. // Get the available data in the shared buffer.
  451. hr = pCaptureClient->GetBuffer(
  452. &pData,
  453. &numFramesAvailable,
  454. &flags, NULL, NULL);
  455. if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
  456. {
  457. pData = NULL; // Tell CopyData to write silence.
  458. }
  459. // Copy the available capture data to the audio sink.
  460. if (pData != NULL) {
  461. copiedPcm = min(sample_size - pcmInBuffer, numFramesAvailable*persample_size);
  462. if (copiedPcm > 0) {
  463. memcpy(sample_buf + pcmInBuffer, pData, copiedPcm);
  464. pcmInBuffer += copiedPcm;
  465. }
  466. if (pcmInBuffer == sample_size) {//got one frame ,encode
  467. int ret = swr_convert(resample_ctx, resampled_frame->data, output_codec_context->frame_size, (const uint8_t**)sample_frame->data, 1024);
  468. if (ret <= 0)
  469. return -1;
  470. av_init_packet(&pkt);
  471. resampled_frame->pts = nextptx;
  472. nextptx += resampled_frame->nb_samples;
  473. int error = avcodec_send_frame(output_codec_context, resampled_frame);
  474. if (error == 0) {
  475. error = avcodec_receive_packet(output_codec_context, &pkt);
  476. if (error == 0) {
  477. av_write_frame(output_format_context, &pkt);
  478. index++;
  479. printf("index:%d\r\n", index);
  480. }
  481. av_packet_unref(&pkt);
  482. }
  483. pcmInBuffer = 0;
  484. }
  485. if (numFramesAvailable*persample_size - copiedPcm > 0)
  486. {
  487. memcpy(sample_buf + pcmInBuffer, pData + copiedPcm, numFramesAvailable*persample_size - copiedPcm);
  488. pcmInBuffer += numFramesAvailable*persample_size - copiedPcm;
  489. }
  490. if (index > 2000) {
  491. printf("pcm still in buffer:%d\r\n", pcmInBuffer);
  492. bDone = true;
  493. break;
  494. }
  495. }
  496. hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
  497. EXIT_ON_ERROR(hr)
  498. hr = pCaptureClient->GetNextPacketSize(&packetLength);
  499. EXIT_ON_ERROR(hr)
  500. }
  501. break;
  502. } // end of 'switch (waitResult)'
  503. } // end of 'while (stillPlaying)'
  504. av_write_trailer(output_format_context);
  505. if (output_codec_context)
  506. avcodec_free_context(&output_codec_context);
  507. if (output_format_context) {
  508. avio_closep(&output_format_context->pb);
  509. avformat_free_context(output_format_context);
  510. }
  511. hr = pAudioClient->Stop(); // Stop recording.
  512. EXIT_ON_ERROR(hr)
  513. Exit:
  514. CoTaskMemFree(pwfx);
  515. SAFE_RELEASE(pEnumerator)
  516. SAFE_RELEASE(pDevice)
  517. SAFE_RELEASE(pAudioClient)
  518. SAFE_RELEASE(pCaptureClient)
  519. return hr;
  520. }
  521. HRESULT cpature_wave()
  522. {
  523. HRESULT hr;
  524. IMMDeviceEnumerator *pEnumerator = NULL;
  525. IMMDevice *pDevice = NULL;
  526. IAudioClient *pAudioClient = NULL;
  527. IAudioCaptureClient *pCaptureClient = NULL;
  528. WAVEFORMATEX *pwfx = NULL;
  529. REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
  530. UINT32 bufferFrameCount;
  531. UINT32 numFramesAvailable;
  532. BYTE *pData;
  533. UINT32 packetLength = 0;
  534. DWORD flags;
  535. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  536. if (FAILED(hr))
  537. {
  538. printf("Unable to initialize COM in thread: %x\n", hr);
  539. return hr;
  540. }
  541. hr = CoCreateInstance(CLSID_MMDeviceEnumerator,
  542. NULL,
  543. CLSCTX_ALL,
  544. IID_IMMDeviceEnumerator,
  545. (void**)&pEnumerator);
  546. EXIT_ON_ERROR(hr)
  547. #ifdef DEF_CAPTURE_MIC
  548. hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, &pDevice);
  549. //hr = pEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &pDevice);
  550. #else
  551. hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
  552. #endif
  553. EXIT_ON_ERROR(hr)
  554. hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);
  555. EXIT_ON_ERROR(hr)
  556. hr = pAudioClient->GetMixFormat(&pwfx);
  557. EXIT_ON_ERROR(hr)
  558. AdjustFormatTo16Bits(pwfx);
  559. #ifdef DEF_CAPTURE_MIC
  560. hr = pAudioClient->Initialize(
  561. AUDCLNT_SHAREMODE_SHARED,
  562. AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
  563. hnsRequestedDuration,
  564. 0,
  565. pwfx,
  566. NULL);
  567. #else
  568. /*
  569. The AUDCLNT_STREAMFLAGS_LOOPBACK flag enables loopback recording.
  570. In loopback recording, the audio engine copies the audio stream
  571. that is being played by a rendering endpoint device into an audio endpoint buffer
  572. so that a WASAPI client can capture the stream.
  573. If this flag is set, the IAudioClient::Initialize method attempts to open a capture buffer on the rendering device.
  574. This flag is valid only for a rendering device
  575. and only if the Initialize call sets the ShareMode parameter to AUDCLNT_SHAREMODE_SHARED.
  576. Otherwise the Initialize call will fail.
  577. If the call succeeds,
  578. the client can call the IAudioClient::GetService method
  579. to obtain an IAudioCaptureClient interface on the rendering device.
  580. For more information, see Loopback Recording.
  581. */
  582. hr = pAudioClient->Initialize(
  583. AUDCLNT_SHAREMODE_SHARED,
  584. AUDCLNT_STREAMFLAGS_EVENTCALLBACK|
  585. AUDCLNT_STREAMFLAGS_LOOPBACK,
  586. hnsRequestedDuration,
  587. 0,
  588. pwfx,
  589. NULL);
  590. #endif
  591. EXIT_ON_ERROR(hr)
  592. int nFrameSize = (pwfx->wBitsPerSample / 8) * pwfx->nChannels;
  593. REFERENCE_TIME hnsStreamLatency;
  594. hr = pAudioClient->GetStreamLatency(&hnsStreamLatency);
  595. EXIT_ON_ERROR(hr)
  596. REFERENCE_TIME hnsDefaultDevicePeriod;
  597. REFERENCE_TIME hnsMinimumDevicePeriod;
  598. hr = pAudioClient->GetDevicePeriod(&hnsDefaultDevicePeriod, &hnsMinimumDevicePeriod);
  599. EXIT_ON_ERROR(hr)
  600. hr = pAudioClient->GetBufferSize(&bufferFrameCount);
  601. EXIT_ON_ERROR(hr)
  602. std::cout << std::endl << "GetBufferSize : " << bufferFrameCount << std::endl;
  603. // SetEventHandle
  604. //////////////////////////////////////////////////////////////////////////
  605. HANDLE hAudioSamplesReadyEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  606. if (hAudioSamplesReadyEvent == NULL)
  607. {
  608. printf("Unable to create samples ready event: %d.\n", GetLastError());
  609. goto Exit;
  610. }
  611. hr = pAudioClient->SetEventHandle(hAudioSamplesReadyEvent);
  612. if (FAILED(hr))
  613. {
  614. printf("Unable to set ready event: %x.\n", hr);
  615. return false;
  616. }
  617. //////////////////////////////////////////////////////////////////////////
  618. hr = pAudioClient->GetService(IID_IAudioCaptureClient, (void**)&pCaptureClient);
  619. EXIT_ON_ERROR(hr)
  620. hr = pAudioClient->Start(); // Start recording.
  621. EXIT_ON_ERROR(hr)
  622. printf("\nAudio Capture begin...\n\n");
  623. int nCnt = 0;
  624. size_t nCaptureBufferSize = 8 * 1024 * 1024;
  625. size_t nCurrentCaptureIndex = 0;
  626. BYTE *pbyCaptureBuffer = new (std::nothrow) BYTE[nCaptureBufferSize];
  627. HANDLE waitArray[3];
  628. waitArray[0] = hAudioSamplesReadyEvent;
  629. bool stillPlaying = true;
  630. // Each loop fills about half of the shared buffer.
  631. while (stillPlaying)
  632. {
  633. DWORD waitResult = WaitForMultipleObjects(1, waitArray, FALSE, INFINITE);
  634. switch (waitResult)
  635. {
  636. case WAIT_OBJECT_0 + 0: // _AudioSamplesReadyEvent
  637. hr = pCaptureClient->GetNextPacketSize(&packetLength);
  638. EXIT_ON_ERROR(hr)
  639. printf("%06d # _AudioSamplesReadyEvent packetLength:%06u \n", nCnt, packetLength);
  640. while (packetLength != 0)
  641. {
  642. // Get the available data in the shared buffer.
  643. hr = pCaptureClient->GetBuffer(&pData,
  644. &numFramesAvailable,
  645. &flags, NULL, NULL);
  646. EXIT_ON_ERROR(hr)
  647. nCnt++;
  648. // test flags
  649. //////////////////////////////////////////////////////////////////////////
  650. if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
  651. {
  652. printf("AUDCLNT_BUFFERFLAGS_SILENT \n");
  653. }
  654. if (flags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY)
  655. {
  656. printf("%06d # AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY \n", nCnt);
  657. }
  658. //////////////////////////////////////////////////////////////////////////
  659. UINT32 framesToCopy = min(numFramesAvailable, static_cast<UINT32>((nCaptureBufferSize - nCurrentCaptureIndex) / nFrameSize));
  660. if (framesToCopy != 0)
  661. {
  662. //
  663. // The flags on capture tell us information about the data.
  664. //
  665. // We only really care about the silent flag since we want to put frames of silence into the buffer
  666. // when we receive silence. We rely on the fact that a logical bit 0 is silence for both float and int formats.
  667. //
  668. if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
  669. {
  670. //
  671. // Fill 0s from the capture buffer to the output buffer.
  672. //
  673. ZeroMemory(&pbyCaptureBuffer[nCurrentCaptureIndex], framesToCopy*nFrameSize);
  674. }
  675. else
  676. {
  677. //
  678. // Copy data from the audio engine buffer to the output buffer.
  679. //
  680. CopyMemory(&pbyCaptureBuffer[nCurrentCaptureIndex], pData, framesToCopy*nFrameSize);
  681. printf("Get: %d\r\n", framesToCopy*nFrameSize);
  682. }
  683. //
  684. // Bump the capture buffer pointer.
  685. //
  686. nCurrentCaptureIndex += framesToCopy*nFrameSize;
  687. }
  688. hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
  689. EXIT_ON_ERROR(hr)
  690. hr = pCaptureClient->GetNextPacketSize(&packetLength);
  691. EXIT_ON_ERROR(hr)
  692. UINT32 ui32NumPaddingFrames;
  693. hr = pAudioClient->GetCurrentPadding(&ui32NumPaddingFrames);
  694. EXIT_ON_ERROR(hr)
  695. if (0 != ui32NumPaddingFrames)
  696. {
  697. printf("GetCurrentPadding : %6u\n", ui32NumPaddingFrames);
  698. }
  699. //////////////////////////////////////////////////////////////////////////
  700. if (nCnt == 1000)
  701. {
  702. stillPlaying = false;
  703. break;
  704. }
  705. } // end of 'while (packetLength != 0)'
  706. break;
  707. } // end of 'switch (waitResult)'
  708. } // end of 'while (stillPlaying)'
  709. //
  710. // We've now captured our wave data. Now write it out in a wave file.
  711. //
  712. SaveWaveData(pbyCaptureBuffer, nCurrentCaptureIndex, pwfx);
  713. printf("\nAudio Capture Done.\n");
  714. hr = pAudioClient->Stop(); // Stop recording.
  715. EXIT_ON_ERROR(hr)
  716. Exit:
  717. CoTaskMemFree(pwfx);
  718. SAFE_RELEASE(pEnumerator)
  719. SAFE_RELEASE(pDevice)
  720. SAFE_RELEASE(pAudioClient)
  721. SAFE_RELEASE(pCaptureClient)
  722. CoUninitialize();
  723. if (pbyCaptureBuffer)
  724. {
  725. delete[] pbyCaptureBuffer;
  726. pbyCaptureBuffer = NULL;
  727. }
  728. if (hAudioSamplesReadyEvent)
  729. {
  730. CloseHandle(hAudioSamplesReadyEvent);
  731. hAudioSamplesReadyEvent = NULL;
  732. }
  733. }
  734. /* check that a given sample format is supported by the encoder */
  735. static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
  736. {
  737. const enum AVSampleFormat *p = codec->sample_fmts;
  738. while (*p != AV_SAMPLE_FMT_NONE) {
  739. if (*p == sample_fmt)
  740. return 1;
  741. p++;
  742. }
  743. return 0;
  744. }
  745. /* just pick the highest supported samplerate */
  746. static int select_sample_rate(const AVCodec *codec)
  747. {
  748. const int *p;
  749. int best_samplerate = 0;
  750. if (!codec->supported_samplerates)
  751. return 44100;
  752. p = codec->supported_samplerates;
  753. while (*p) {
  754. if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
  755. best_samplerate = *p;
  756. p++;
  757. }
  758. return best_samplerate;
  759. }
  760. /* select layout with the highest channel count */
  761. static int select_channel_layout(const AVCodec *codec)
  762. {
  763. const uint64_t *p;
  764. uint64_t best_ch_layout = 0;
  765. int best_nb_channels = 0;
  766. if (!codec->channel_layouts)
  767. return AV_CH_LAYOUT_STEREO;
  768. p = codec->channel_layouts;
  769. while (*p) {
  770. int nb_channels = av_get_channel_layout_nb_channels(*p);
  771. if (nb_channels > best_nb_channels) {
  772. best_ch_layout = *p;
  773. best_nb_channels = nb_channels;
  774. }
  775. p++;
  776. }
  777. return best_ch_layout;
  778. }
  779. int main1()
  780. {
  781. //capture_audio();
  782. //test_transcode();
  783. cpature_wave();
  784. system("pause");
  785. return 0;
  786. }