gen_frame.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. __CheckBool(SUCCEEDED(rgbToNv12.Convert(img, nv12Img.get())));
  18. // 填充缓冲区
  19. __CheckBool(buffers.Fill(device, desc));
  20. ctx->CopyResource(buffers.GetCopy(), nv12Img.get());
  21. D3D11_MAPPED_SUBRESOURCE resource;
  22. __CheckBool(SUCCEEDED(ctx->Map(buffers.GetMap(), 0, D3D11_MAP_READ, 0, &resource)));
  23. auto height = std::min(outFrame->height, (int)desc.Height);
  24. auto width = outFrame->width;
  25. auto srcLinesize = resource.RowPitch;
  26. auto dstLinesize = outFrame->linesize[0];
  27. auto srcData = (uint8_t*)resource.pData;
  28. auto titleHeight = std::max(int(desc.Height - height), 0);
  29. /* auto copyLine = std::min(std::min(width, (int) srcLinesize), dstLinesize);*/
  30. auto border = (desc.Width - width) / 2;
  31. __mtx.lock();
  32. // Y
  33. int Ystart = (titleHeight - border) * srcLinesize + border;
  34. auto dstData = outFrame->data[0];
  35. for (int row = 0; row < height; ++row) {
  36. memcpy(dstData + row * dstLinesize, srcData + Ystart + row * srcLinesize, width);
  37. }
  38. // UV
  39. dstData = outFrame->data[1];
  40. int UVStart = srcLinesize * desc.Height + (titleHeight - border) / 2 * srcLinesize + border / 2 * 2;
  41. for (int row = 0; row < height / 2; ++row) {
  42. memcpy(dstData + row * dstLinesize, srcData + UVStart + row * srcLinesize, width);
  43. }
  44. __mtx.unlock();
  45. ctx->Unmap(buffers.GetMap(), 0);
  46. __CheckBool(buffers.Reset());
  47. return true;
  48. }
  49. bool GenRgbFrame(ID3D11Device* device, ID3D11DeviceContext* ctx, const D3D11_TEXTURE2D_DESC& desc,
  50. ID3D11Texture2D* img, BufferFiller& buffers, AVFrame*& outFrame)
  51. {
  52. __CheckBool(buffers.Fill(device, desc));
  53. ctx->CopyResource(buffers.GetCopy(), img);
  54. D3D11_MAPPED_SUBRESOURCE resource;
  55. __CheckBool(SUCCEEDED(ctx->Map(buffers.GetMap(), 0, D3D11_MAP_READ, 0, &resource)));
  56. auto height = std::min(outFrame->height, (int)desc.Height);
  57. auto width = outFrame->width;
  58. auto srcLinesize = resource.RowPitch;
  59. auto dstLinesize = outFrame->linesize[0];
  60. auto srcData = (uint8_t*)resource.pData;
  61. auto dstData = outFrame->data[0];
  62. auto titleHeight = std::max(int(desc.Height - height), 0);
  63. auto copyLine = std::min(std::min(width * 4, (int)srcLinesize), dstLinesize);
  64. auto border = (desc.Width - width) / 2;
  65. __mtx.lock();
  66. for (int row = 0; row < height; ++row) {
  67. auto offset = (titleHeight + row - border) * srcLinesize + border * 4;
  68. memcpy(dstData + row * dstLinesize, srcData + offset, copyLine);
  69. }
  70. __mtx.unlock();
  71. ctx->Unmap(buffers.GetMap(), 0);
  72. __CheckBool(buffers.Reset());
  73. return true;
  74. }