I 入口

格式转换入口的函数都在convert_xx之类的文件中。在我的android程序中主要用的是xx格式转成NV12。其入口在convert_from.cc中。

函数为:

int I420ToNV12(const uint8* src_y,
               int src_stride_y,
               const uint8* src_u,
               int src_stride_u,
               const uint8* src_v,
               int src_stride_v,
               uint8* dst_y,
               int dst_stride_y,
               uint8* dst_uv,
               int dst_stride_uv,
               int width,
               int height);

这里涉及到两个函数:

CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
MergeUVPlane(src_u, src_stride_u, src_v, src_stride_v, dst_uv, dst_stride_uv,
               halfwidth, halfheight);

其入口都在planar_functions.cc中:

void CopyPlane(const uint8* src_y,
               int src_stride_y,
               uint8* dst_y,
               int dst_stride_y,
               int width,
               int height) {
  int y;
  void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
  // Negative height means invert the image.
  if (height < 0) {
    height = -height;
    dst_y = dst_y + (height - 1) * dst_stride_y;
    dst_stride_y = -dst_stride_y;
  }
  // Coalesce rows.
  if (src_stride_y == width && dst_stride_y == width) {
    width *= height;
    height = 1;
    src_stride_y = dst_stride_y = 0;
  }
  // Nothing to do.
  if (src_y == dst_y && src_stride_y == dst_stride_y) {
    return;
  }
#if defined(HAS_COPYROW_SSE2)
  if (TestCpuFlag(kCpuHasSSE2)) {
    CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;
  }
#endif
#if defined(HAS_COPYROW_AVX)
  if (TestCpuFlag(kCpuHasAVX)) {
    CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX;
  }
#endif
#if defined(HAS_COPYROW_ERMS)
  if (TestCpuFlag(kCpuHasERMS)) {
    CopyRow = CopyRow_ERMS;
  }
#endif
#if defined(HAS_COPYROW_NEON)
  if (TestCpuFlag(kCpuHasNEON)) {
    CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON;
  }
#endif
#if defined(HAS_COPYROW_MIPS)
  if (TestCpuFlag(kCpuHasMIPS)) {
    CopyRow = CopyRow_MIPS;
  }
#endif

  // Copy plane
  for (y = 0; y < height; ++y) {
    CopyRow(src_y, dst_y, width);
    src_y += src_stride_y;
    dst_y += dst_stride_y;
  }
}

void MergeUVPlane(const uint8* src_u,
                  int src_stride_u,
                  const uint8* src_v,
                  int src_stride_v,
                  uint8* dst_uv,
                  int dst_stride_uv,
                  int width,
                  int height) {
  int y;
  void (*MergeUVRow)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
                     int width) = MergeUVRow_C;
  // Coalesce rows.
  // Negative height means invert the image.
  if (height < 0) {
    height = -height;
    dst_uv = dst_uv + (height - 1) * dst_stride_uv;
    dst_stride_uv = -dst_stride_uv;
  }
  // Coalesce rows.
  if (src_stride_u == width && src_stride_v == width &&
      dst_stride_uv == width * 2) {
    width *= height;
    height = 1;
    src_stride_u = src_stride_v = dst_stride_uv = 0;
  }
#if defined(HAS_MERGEUVROW_SSE2)
  if (TestCpuFlag(kCpuHasSSE2)) {
    MergeUVRow = MergeUVRow_Any_SSE2;
    if (IS_ALIGNED(width, 16)) {
      MergeUVRow = MergeUVRow_SSE2;
    }
  }
#endif
#if defined(HAS_MERGEUVROW_AVX2)
  if (TestCpuFlag(kCpuHasAVX2)) {
    MergeUVRow = MergeUVRow_Any_AVX2;
    if (IS_ALIGNED(width, 32)) {
      MergeUVRow = MergeUVRow_AVX2;
    }
  }
#endif
#if defined(HAS_MERGEUVROW_NEON)
  if (TestCpuFlag(kCpuHasNEON)) {
    MergeUVRow = MergeUVRow_Any_NEON;
    if (IS_ALIGNED(width, 16)) {
      MergeUVRow = MergeUVRow_NEON;
    }
  }
#endif
#if defined(HAS_MERGEUVROW_MSA)
  if (TestCpuFlag(kCpuHasMSA)) {
    MergeUVRow = MergeUVRow_Any_MSA;
    if (IS_ALIGNED(width, 16)) {
      MergeUVRow = MergeUVRow_MSA;
    }
  }
#endif

  for (y = 0; y < height; ++y) {
    // Merge a row of U and V into a row of UV.
    MergeUVRow(src_u, src_v, dst_uv, width);
    src_u += src_stride_u;
    src_v += src_stride_v;
    dst_uv += dst_stride_uv;
  }
}
View Code

相关文章: