frame.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "basic/frame.h"
  2. extern "C" {
  3. #include <libswscale/swscale.h>
  4. }
  5. AVFrame* Frame<MediaType::AUDIO>::Alloc(AVSampleFormat sampleFmt,
  6. const AVChannelLayout* channel_layout,
  7. int sampleRate, int nbSamples)
  8. {
  9. AVFrame* frame = av_frame_alloc();
  10. if (!frame) {
  11. __DebugPrint("av_frame_alloc failed");
  12. return nullptr;
  13. }
  14. frame->format = sampleFmt;
  15. av_channel_layout_copy(&frame->ch_layout, channel_layout);
  16. frame->sample_rate = sampleRate;
  17. frame->nb_samples = nbSamples;
  18. /* allocate the buffers for the frame data */
  19. if (av_frame_get_buffer(frame, 0) < 0) {
  20. __DebugPrint("av_frame_get_buffer failed");
  21. av_frame_free(&frame);
  22. return nullptr;
  23. }
  24. return frame;
  25. }
  26. Frame<MediaType::AUDIO>::Frame(AVSampleFormat sampleFmt,
  27. const AVChannelLayout* channel_layout, int sampleRate,
  28. int nbSamples)
  29. {
  30. frame = Alloc(sampleFmt, channel_layout, sampleRate, nbSamples);
  31. if (!frame) {
  32. __DebugPrint("Frame<MediaType::AUDIO>::Alloc failed");
  33. return;
  34. }
  35. }
  36. Frame<MediaType::AUDIO>::Frame(AVFrame* frame)
  37. {
  38. if (frame == nullptr) {
  39. this->frame = nullptr;
  40. return;
  41. }
  42. this->frame = Alloc(AVSampleFormat(frame->format), &frame->ch_layout, frame->sample_rate, frame->nb_samples);
  43. if (!this->frame) {
  44. __DebugPrint("Alloc failed in AUDIO copy ctor");
  45. return;
  46. }
  47. if (av_frame_copy(this->frame, frame) < 0) {
  48. __DebugPrint("av_frame_copy failed in AUDIO copy ctor");
  49. av_frame_free(&this->frame);
  50. this->frame = nullptr;
  51. return;
  52. }
  53. }
  54. Frame<MediaType::VIDEO>::Frame(AVPixelFormat pixFmt, int width, int height)
  55. {
  56. frame = Alloc(pixFmt, width, height);
  57. if (!frame) {
  58. __DebugPrint("Frame<MediaType::VIDEO>::Alloc failed");
  59. return;
  60. }
  61. }
  62. AVFrame* Frame<MediaType::VIDEO>::Alloc(AVPixelFormat pixFmt, int width, int height)
  63. {
  64. AVFrame* frame = av_frame_alloc();
  65. if (!frame) {
  66. __DebugPrint("av_frame_alloc failed");
  67. return nullptr;
  68. }
  69. frame->format = pixFmt;
  70. frame->width = width;
  71. frame->height = height;
  72. /* allocate the buffers for the frame data */
  73. if (av_frame_get_buffer(frame, 0) < 0) {
  74. __DebugPrint("av_frame_get_buffer failed");
  75. av_frame_free(&frame);
  76. return nullptr;
  77. }
  78. return frame;
  79. }
  80. Frame<MediaType::VIDEO>::Frame(AVFrame* frame)
  81. {
  82. if (frame == nullptr) {
  83. this->frame = nullptr;
  84. return;
  85. }
  86. this->frame = Alloc(AVPixelFormat(frame->format), frame->width, frame->height);
  87. if (!this->frame) {
  88. __DebugPrint("Alloc failed in VIDEO copy ctor");
  89. return;
  90. }
  91. if (av_frame_copy(this->frame, frame) < 0) {
  92. __DebugPrint("av_frame_copy failed in VIDEO copy ctor");
  93. av_frame_free(&this->frame);
  94. this->frame = nullptr;
  95. return;
  96. }
  97. }
  98. bool FfmpegConverter::SetSize(int width, int height)
  99. {
  100. Free(_swsCtx, [this] { sws_freeContext(_swsCtx); });
  101. Free(_frameTo, [this] { av_frame_free(&_frameTo); });
  102. // 创建格式转换
  103. _swsCtx = sws_getContext(
  104. width, height, _from,
  105. width, height, _to,
  106. 0, NULL, NULL, NULL);
  107. if (!_swsCtx) {
  108. __DebugPrint("sws_getContext failed");
  109. return false;
  110. }
  111. _frameTo = Frame<MediaType::VIDEO>::Alloc(_to, width, height);
  112. if (!_frameTo) {
  113. __DebugPrint("Frame<MediaType::VIDEO>::Alloc failed");
  114. return false;
  115. }
  116. return true;
  117. }
  118. AVFrame* FfmpegConverter::Trans(AVFrame* frameFrom)
  119. {
  120. // 如果是空指针,直接把缓存返回
  121. if (frameFrom == nullptr) {
  122. return _frameTo;
  123. }
  124. int rc = sws_scale(_swsCtx, (const uint8_t* const*)frameFrom->data,
  125. frameFrom->linesize, 0, frameFrom->height, _frameTo->data,
  126. _frameTo->linesize);
  127. if (rc < 0) {
  128. __DebugPrint("sws_scale failed: rc=%d", rc);
  129. return nullptr;
  130. }
  131. return _frameTo;
  132. }
  133. FfmpegConverter::~FfmpegConverter()
  134. {
  135. Free(_swsCtx, [this] { sws_freeContext(_swsCtx); });
  136. Free(_frameTo, [this] { av_frame_free(&_frameTo); });
  137. }