sophgo/sophon-demo

AVFrame 转 BM_IMAGE 遇到了问题

Opened this issue · 1 comments

下面是我从sophon-demo的yolov5中,转换格式的代码,但这个转发有一个问题,就是,我发现转换后的bm_image的图片,会随着视频播放而改变图片的内容,但我想要达到的效果是,类似截图的效果,我转换后,里面的图片内容不要随着视频的进度而变化,请问要怎么调整?

static inline bm_status_t bm_image_from_frame(bm_handle_t &bm_handle,
                                              AVFrame &in,
                                              bm_image &out)
{
  if (in.format != AV_PIX_FMT_NV12)
  {
    std::cout << "format donot support" << std::endl;
    return BM_NOT_SUPPORTED;
  }

  if (in.channel_layout == 101)
  { /* COMPRESSED NV12 FORMAT */
    /* sanity check */
    if ((0 == in.height) || (0 == in.width) ||
        (0 == in.linesize[4]) || (0 == in.linesize[5]) || (0 == in.linesize[6]) || (0 == in.linesize[7]) ||
        (0 == in.data[4]) || (0 == in.data[5]) || (0 == in.data[6]) || (0 == in.data[7]))
    {
      std::cout << "bm_image_from_frame: get yuv failed!!" << std::endl;
      return BM_ERR_PARAM;
    }
    bm_image cmp_bmimg;
    bm_image_create(bm_handle,
                    in.height,
                    in.width,
                    FORMAT_COMPRESSED,
                    DATA_TYPE_EXT_1N_BYTE,
                    &cmp_bmimg);

    bm_device_mem_t input_addr[4];
    int size = in.height * in.linesize[4];
    input_addr[0] = bm_mem_from_device((unsigned long long)in.data[6], size);
    size = (in.height / 2) * in.linesize[5];
    input_addr[1] = bm_mem_from_device((unsigned long long)in.data[4], size);
    size = in.linesize[6];
    input_addr[2] = bm_mem_from_device((unsigned long long)in.data[7], size);
    size = in.linesize[7];
    input_addr[3] = bm_mem_from_device((unsigned long long)in.data[5], size);
    bm_image_attach(cmp_bmimg, input_addr);

    bm_image_create(bm_handle,
                    in.height,
                    in.width,
                    FORMAT_YUV420P,
                    DATA_TYPE_EXT_1N_BYTE,
                    &out);

    bm_image_dev_mem_alloc(out);
    bmcv_rect_t crop_rect = {0, 0, in.width, in.height};
    bmcv_image_vpp_convert(bm_handle, 1, cmp_bmimg, &out, &crop_rect);
    bm_image_destroy(cmp_bmimg);
  }
  else
  { /* UNCOMPRESSED NV12 FORMAT */
    /* sanity check */
    if ((0 == in.height) || (0 == in.width) ||
        (0 == in.linesize[4]) || (0 == in.linesize[5]) ||
        (0 == in.data[4]) || (0 == in.data[5]))
    {
      std::cout << "bm_image_from_frame: get yuv failed!!" << std::endl;
      return BM_ERR_PARAM;
    }

    int stride[2];
    stride[0] = in.linesize[4];
    stride[1] = in.linesize[5];

    // bm_image_create (bm_handle,
    //      in.height,
    //      in.width,
    //      FORMAT_BGR_PACKED,
    //      DATA_TYPE_EXT_1N_BYTE,
    //      &out,
    //      stride);

    bm_image_create(bm_handle,
                    in.height,
                    in.width,
                    FORMAT_NV12,
                    DATA_TYPE_EXT_1N_BYTE,
                    &out,
                    stride);

    /* calculate physical address of yuv mat */
    bm_device_mem_t input_addr[2];
    int size = in.height * stride[0];
    input_addr[0] = bm_mem_from_device((unsigned long long)in.data[4], size);
    size = in.height * stride[1];
    input_addr[1] = bm_mem_from_device((unsigned long long)in.data[5], size);

    // /* attach memory from mat to bm_image */
    bm_image_attach(out, input_addr);
  }

  return BM_SUCCESS;
}

这个bm_image的内存是attach的,你可以copy一下,把这块内存拷贝到一个固定的位置,使用bmcv_image_copy_to接口。