Recorder.cpp 34 KB

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