当前位置:   article > 正文

YUV采样格式存储拷贝及转换_yuv 拷贝

yuv 拷贝

1.YUV采样格式初始化

  1. /* messy code alarm */
  2. void video_frame_init(struct video_frame *frame, enum video_format format,
  3. uint32_t width, uint32_t height)
  4. {
  5. size_t size;
  6. size_t offsets[MAX_AV_PLANES];
  7. int alignment = base_get_alignment();
  8. if (!frame) return;
  9. memset(frame, 0, sizeof(struct video_frame));
  10. memset(offsets, 0, sizeof(offsets));
  11. switch (format) {
  12. case VIDEO_FORMAT_NONE:
  13. return;
  14. case VIDEO_FORMAT_I420:
  15. size = width * height;
  16. ALIGN_SIZE(size, alignment);
  17. offsets[0] = size;
  18. size += (width/2) * (height/2);
  19. ALIGN_SIZE(size, alignment);
  20. offsets[1] = size;
  21. size += (width/2) * (height/2);
  22. ALIGN_SIZE(size, alignment);
  23. frame->data[0] = bmalloc(size);
  24. frame->data[1] = (uint8_t*)frame->data[0] + offsets[0];
  25. frame->data[2] = (uint8_t*)frame->data[0] + offsets[1];
  26. frame->linesize[0] = width;
  27. frame->linesize[1] = width/2;
  28. frame->linesize[2] = width/2;
  29. break;
  30. case VIDEO_FORMAT_NV12:
  31. size = width * height;
  32. ALIGN_SIZE(size, alignment);
  33. offsets[0] = size;
  34. size += (width/2) * (height/2) * 2;
  35. ALIGN_SIZE(size, alignment);
  36. frame->data[0] = bmalloc(size);
  37. frame->data[1] = (uint8_t*)frame->data[0] + offsets[0];
  38. frame->linesize[0] = width;
  39. frame->linesize[1] = width;
  40. break;
  41. case VIDEO_FORMAT_Y800:
  42. size = width * height;
  43. ALIGN_SIZE(size, alignment);
  44. frame->data[0] = bmalloc(size);
  45. frame->linesize[0] = width;
  46. break;
  47. case VIDEO_FORMAT_YVYU:
  48. case VIDEO_FORMAT_YUY2:
  49. case VIDEO_FORMAT_UYVY:
  50. size = width * height * 2;
  51. ALIGN_SIZE(size, alignment);
  52. frame->data[0] = bmalloc(size);
  53. frame->linesize[0] = width*2;
  54. break;
  55. case VIDEO_FORMAT_RGBA:
  56. case VIDEO_FORMAT_BGRA:
  57. case VIDEO_FORMAT_BGRX:
  58. size = width * height * 4;
  59. ALIGN_SIZE(size, alignment);
  60. frame->data[0] = bmalloc(size);
  61. frame->linesize[0] = width*4;
  62. break;
  63. case VIDEO_FORMAT_I444:
  64. size = width * height;
  65. ALIGN_SIZE(size, alignment);
  66. frame->data[0] = bmalloc(size * 3);
  67. frame->data[1] = (uint8_t*)frame->data[0] + size;
  68. frame->data[2] = (uint8_t*)frame->data[1] + size;
  69. frame->linesize[0] = width;
  70. frame->linesize[1] = width;
  71. frame->linesize[2] = width;
  72. break;
  73. }
  74. }

2.数据拷贝

  1. void video_frame_copy(struct video_frame *dst, const struct video_frame *src,
  2. enum video_format format, uint32_t cy)
  3. {
  4. switch (format) {
  5. case VIDEO_FORMAT_NONE:
  6. return;
  7. case VIDEO_FORMAT_I420:
  8. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  9. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2);
  10. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy / 2);
  11. break;
  12. case VIDEO_FORMAT_NV12:
  13. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  14. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2);
  15. break;
  16. case VIDEO_FORMAT_Y800:
  17. case VIDEO_FORMAT_YVYU:
  18. case VIDEO_FORMAT_YUY2:
  19. case VIDEO_FORMAT_UYVY:
  20. case VIDEO_FORMAT_RGBA:
  21. case VIDEO_FORMAT_BGRA:
  22. case VIDEO_FORMAT_BGRX:
  23. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  24. break;
  25. case VIDEO_FORMAT_I444:
  26. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  27. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy);
  28. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy);
  29. break;
  30. }
  31. }
  32. void video_frame_setblack(struct video_frame *dst, enum video_format format, uint32_t cy)
  33. {
  34. switch (format) {
  35. case VIDEO_FORMAT_NONE:
  36. return;
  37. case VIDEO_FORMAT_I420:
  38. memset(dst->data[0], 0, dst->linesize[0] * cy);
  39. memset(dst->data[1], 0x80, dst->linesize[1] * cy / 2);
  40. memset(dst->data[2], 0x80, dst->linesize[2] * cy / 2);
  41. break;
  42. case VIDEO_FORMAT_NV12:
  43. memset(dst->data[0], 0x10, dst->linesize[0] * cy);
  44. memset(dst->data[1], 0x80, dst->linesize[1] * cy / 2);
  45. break;
  46. case VIDEO_FORMAT_Y800:
  47. case VIDEO_FORMAT_YVYU:
  48. case VIDEO_FORMAT_YUY2:
  49. case VIDEO_FORMAT_UYVY:
  50. case VIDEO_FORMAT_RGBA:
  51. case VIDEO_FORMAT_BGRA:
  52. case VIDEO_FORMAT_BGRX:
  53. memset(dst->data[0], 0, dst->linesize[0] * cy);
  54. break;
  55. case VIDEO_FORMAT_I444:
  56. memset(dst->data[0], 0, dst->linesize[0] * cy*3);
  57. // memset(dst->data[1], 0, dst->linesize[0] * cy);
  58. // memset(dst->data[2], 0, dst->linesize[0] * cy);
  59. break;
  60. }
  61. }

3.格式转换

  1. void convert_nv12_to_uyvy(uint8_t* input[], uint32_t in_linesize[],
  2. uint32_t start_y, uint32_t end_y,
  3. uint8_t* output, uint32_t out_linesize)
  4. {
  5. register uint8_t* _Y;
  6. register uint8_t* _U;
  7. register uint8_t* _V;
  8. register uint8_t* _out;
  9. uint32_t width = min_uint32(in_linesize[0], out_linesize);
  10. uint8_t* _YL = input[0] + (start_y * in_linesize[0]);
  11. uint8_t* _UL = input[1] + ((start_y / 2) * in_linesize[1]);
  12. uint8_t* _outL = output + (start_y * out_linesize);
  13. for (uint32_t y = start_y; y < end_y; y++) {
  14. /*_Y = input[0] + (y * in_linesize[0]);
  15. _U = input[1] + ((y/2) * in_linesize[1]);
  16. _V = _U + 1;
  17. _out = output + (y * out_linesize);*/
  18. _Y = _YL;
  19. _U = _UL;
  20. _V = _U + 1;
  21. _out = _outL;
  22. for (uint32_t x = 0; x < width; x+=2) {
  23. *(_out++) = *(_U++); _U++;
  24. *(_out++) = *(_Y++);
  25. *(_out++) = *(_V++); _V++;
  26. *(_out++) = *(_Y++);
  27. }
  28. _YL += in_linesize[0];
  29. _UL += y&0x1?in_linesize[1]:0;
  30. _outL += out_linesize;
  31. }
  32. }
  33. void convert_i420_to_uyvy(uint8_t* input[], uint32_t in_linesize[],
  34. uint32_t start_y, uint32_t end_y,
  35. uint8_t* output, uint32_t out_linesize)
  36. {
  37. uint8_t* _Y;
  38. uint8_t* _U;
  39. uint8_t* _V;
  40. uint8_t* _out;
  41. uint32_t width = min_uint32(in_linesize[0], out_linesize);
  42. for (uint32_t y = start_y; y < end_y; y++) {
  43. _Y = input[0] + (y * in_linesize[0]);
  44. _U = input[1] + ((y/2) * in_linesize[1]);
  45. _V = input[2] + ((y/2) * in_linesize[2]);
  46. _out = output + (y * out_linesize);
  47. for (uint32_t x = 0; x < width; x += 2) {
  48. *(_out++) = *(_U++);
  49. *(_out++) = *(_Y++);
  50. *(_out++) = *(_V++);
  51. *(_out++) = *(_Y++);
  52. }
  53. }
  54. }
  55. void convert_i444_to_uyvy(uint8_t* input[], uint32_t in_linesize[],
  56. uint32_t start_y, uint32_t end_y,
  57. uint8_t* output, uint32_t out_linesize)
  58. {
  59. uint8_t* _Y;
  60. uint8_t* _U;
  61. uint8_t* _V;
  62. uint8_t* _out;
  63. uint32_t width = min_uint32(in_linesize[0], out_linesize);
  64. for (uint32_t y = start_y; y < end_y; y++) {
  65. _Y = input[0] + (y * in_linesize[0]);
  66. _U = input[1] + (y * in_linesize[1]);
  67. _V = input[2] + (y * in_linesize[2]);
  68. _out = output + (y * out_linesize);
  69. for (uint32_t x = 0; x < width; x += 2) {
  70. // Quality loss here. Some chroma samples are ignored.
  71. *(_out++) = *(_U++); _U++;
  72. *(_out++) = *(_Y++);
  73. *(_out++) = *(_V++); _V++;
  74. *(_out++) = *(_Y++);
  75. }
  76. }
  77. }

 

参考资料:

https://github.com/obsproject/obs-studio

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/194967
推荐阅读
相关标签
  

闽ICP备14008679号