gen_frame.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "gen_frame.h"
  2. #include <winrt/base.h>
  3. #undef min
  4. #undef max
  5. bool GenNv12Frame(ID3D11Device* device,
  6. ID3D11DeviceContext* ctx,
  7. const D3D11_TEXTURE2D_DESC& desc,
  8. ID3D11Texture2D* img,
  9. BufferFiller& buffers,
  10. AVFrame*& outFrame,
  11. D3dConverter& rgbToNv12)
  12. {
  13. winrt::com_ptr<ID3D11Texture2D> nv12Img = nullptr;
  14. if (FAILED(device->CreateTexture2D(&desc, nullptr, nv12Img.put()))) {
  15. return false;
  16. }
  17. if (!CheckHR(rgbToNv12.Convert(img, nv12Img.get()), "rgbToNv12.Convert")) {
  18. return false;
  19. }
  20. // 填充缓冲区
  21. if (!buffers.Fill(device, desc)) {
  22. return false;
  23. }
  24. ctx->CopyResource(buffers.GetCopy(), nv12Img.get());
  25. D3D11_MAPPED_SUBRESOURCE resource;
  26. if (!CheckHR(ctx->Map(buffers.GetMap(), 0, D3D11_MAP_READ, 0, &resource), "ID3D11DeviceContext::Map")) {
  27. return false;
  28. }
  29. auto height = std::min(outFrame->height, (int)desc.Height);
  30. auto width = outFrame->width;
  31. auto srcLinesize = resource.RowPitch;
  32. auto dstLinesize = outFrame->linesize[0];
  33. auto srcData = (uint8_t*)resource.pData;
  34. auto titleHeight = std::max(int(desc.Height - height), 0);
  35. /* auto copyLine = std::min(std::min(width, (int) srcLinesize), dstLinesize);*/
  36. auto border = (desc.Width - width) / 2;
  37. __mtx.lock();
  38. // Y
  39. int Ystart = (titleHeight - border) * srcLinesize + border;
  40. auto dstData = outFrame->data[0];
  41. for (int row = 0; row < height; ++row) {
  42. memcpy(dstData + row * dstLinesize, srcData + Ystart + row * srcLinesize, width);
  43. }
  44. // UV
  45. dstData = outFrame->data[1];
  46. int UVStart = srcLinesize * desc.Height + (titleHeight - border) / 2 * srcLinesize + border / 2 * 2;
  47. for (int row = 0; row < height / 2; ++row) {
  48. memcpy(dstData + row * dstLinesize, srcData + UVStart + row * srcLinesize, width);
  49. }
  50. __mtx.unlock();
  51. ctx->Unmap(buffers.GetMap(), 0);
  52. if (!buffers.Reset()) {
  53. return false;
  54. }
  55. return true;
  56. }
  57. bool GenRgbFrame(ID3D11Device* device, ID3D11DeviceContext* ctx, const D3D11_TEXTURE2D_DESC& desc,
  58. ID3D11Texture2D* img, BufferFiller& buffers, AVFrame*& outFrame)
  59. {
  60. if (!buffers.Fill(device, desc)) {
  61. return false;
  62. }
  63. ctx->CopyResource(buffers.GetCopy(), img);
  64. D3D11_MAPPED_SUBRESOURCE resource;
  65. if (!CheckHR(ctx->Map(buffers.GetMap(), 0, D3D11_MAP_READ, 0, &resource), "ID3D11DeviceContext::Map")) {
  66. return false;
  67. }
  68. auto height = std::min(outFrame->height, (int)desc.Height);
  69. auto width = outFrame->width;
  70. auto srcLinesize = resource.RowPitch;
  71. auto dstLinesize = outFrame->linesize[0];
  72. auto srcData = (uint8_t*)resource.pData;
  73. auto dstData = outFrame->data[0];
  74. auto titleHeight = std::max(int(desc.Height - height), 0);
  75. auto copyLine = std::min(std::min(width * 4, (int)srcLinesize), dstLinesize);
  76. auto border = (desc.Width - width) / 2;
  77. __mtx.lock();
  78. for (int row = 0; row < height; ++row) {
  79. auto offset = (titleHeight + row - border) * srcLinesize + border * 4;
  80. memcpy(dstData + row * dstLinesize, srcData + offset, copyLine);
  81. }
  82. __mtx.unlock();
  83. ctx->Unmap(buffers.GetMap(), 0);
  84. if (!buffers.Reset()) {
  85. return false;
  86. }
  87. return true;
  88. }