ahua

ahua

0个粉丝

6

问答

0

专栏

0

资料

ahua  发布于  2025-02-24 15:17:55
采纳率 34%
6个问答
142

求助,通过网络接收h264数据,解码后通过region画出来,出现错位撕裂 Hi3519DV500

     
  1. 通过ss_mpi_vdec_get_frame得到解码后的数据

    while (vde->onoff)
     {
    
         int ret = ss_mpi_vdec_get_frame(chn, &frame, NULL, -1);
         // printf("ss_mpi_vdec_get_frame %X \n", ret);
         if (ret != TD_SUCCESS)
         {
             printf("ss_mpi_vdec_get_frame %X \n", ret);
             continue;
         }
         else
         {
    
             // memset(data,0,yuv_size);
             td_u8 *addr = ss_mpi_sys_mmap_cached(frame.video_frame.phys_addr[0], yuv_size);
             if (addr == TD_NULL)
             {
                 printf("sys_mmap_cached for yuv failed\n");
                 return TD_NULL;
             }
    
             (td_void) ss_mpi_sys_flush_cache(frame.video_frame.phys_addr[0], addr, yuv_size);
             memcpy_s(data, yuv_size, frame.video_frame.virt_addr[0], yuv_size);
             ss_mpi_sys_munmap(addr, yuv_size);
    
             addr = ss_mpi_sys_mmap_cached(frame.video_frame.phys_addr[1], yuv_size / 2);
             memcpy_s(uv, yuv_size / 2, addr, yuv_size / 2);
             (td_void) ss_mpi_sys_flush_cache(frame.video_frame.phys_addr[1], addr, yuv_size / 2);
             ss_mpi_sys_munmap(addr, yuv_size / 2);
    
             vde->frameHandler(vde->chn, &frame, data, uv);
             //测试代码,如果把frame发给venc后,视频是正常的
             ss_mpi_venc_send_frame(1,&frame, 0);
         }
    
         ss_mpi_vdec_release_frame(0, &frame);
     }
    

特别说明,解码是正常的,通过ss_mpi_venc_send_frame(1,&frame, 0);将frame发给venc后,存成文件能正常观看

这儿将yuv转换成rgb后,转成rgb1555,用region画出来;

static inline td_u32 GetYTileIndex(td_u32 x, td_u32 y, td_u32 stride)
{
    const td_u32 tile_cols = stride / TILE_WIDTH; // 每行Tile数量
    const td_u32 tile_x = x / TILE_WIDTH;
    const td_u32 tile_y = y / TILE_HEIGHT;
    const td_u32 in_tile_x = x - TILE_WIDTH * tile_x;
    const td_u32 in_tile_y = y - TILE_HEIGHT * tile_y;
    // printf("tile %d %d %d %d %d %d\n",x,y,tile_x,tile_y,in_tile_x,in_tile_y);

    // 计算Tile起始地址 + Tile内偏移
    return (tile_y * tile_cols + tile_x) * (TILE_WIDTH * TILE_HEIGHT) + in_tile_y * TILE_WIDTH + in_tile_x;
}

// UV分量Tile索引(32x8,色度下采样后)
static inline td_u32 GetUVTileIndex(td_u32 x, td_u32 y, td_u32 stride)
{
    const td_u32 uv_tile_w = TILE_WIDTH / 2;
    const td_u32 uv_tile_h = TILE_HEIGHT / 2;
    const td_u32 tiles_per_row = (stride / 2) / uv_tile_w; // stride已下采样

    const td_u32 tile_row = y / uv_tile_h;
    const td_u32 tile_col = x / uv_tile_w;
    const td_u32 in_tile_y = y % uv_tile_h;
    const td_u32 in_tile_x = x % uv_tile_w;

    return (tile_row * tiles_per_row + tile_col) * uv_tile_w * uv_tile_h + in_tile_y * uv_tile_w + in_tile_x;
}
static void frameHandler(int index, ot_video_frame_info *frame, td_u8 *ybuf, td_u8 *uv)
{

    int w = frame->video_frame.width;
    int h = frame->video_frame.height;
    td_u8 *rgbBuf = members[index].regionBMP.data;
    td_u32 stride = frame->video_frame.stride[0];
    // FILE* fp = fopen("y_data.bin", "wb");
    // fwrite(ybuf, 1, stride * h, fp);
    // fclose(fp);
// for(int i=0;i<17;i++)
//     memset(ybuf+stride*16*i, i*15, stride*16); // Y=255
// memset(uv, 0x80, stride*h/2);    // U=V=128(中性色)
    td_u8 r, g, b;
    td_u8 *start = TD_NULL;
    td_u16 *dst = TD_NULL;
    td_u32 tile_idx;
    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {
            tile_idx = GetYTileIndex(x, y, stride);
            start = (td_u8 *)(ybuf + tile_idx);
            dst = (td_u16 *)(rgbBuf + y * w * 2 + x * 2); /* 2 bytes */

            tile_idx = UV_TILE_INDEX(x / 2, y / 2, stride);

            const td_u8 *uv_ptr = uv + tile_idx * 2;
            const td_u8 U = uv_ptr[1];
            const td_u8 V = uv_ptr[0];

            // YUV转RGB(BT.601标准)
            r = *start;//CLAMP((298 * (*start - 16) + 409 * (V - 128) + 128) >> 8);
            g = *start;//CLAMP((298 * (*start - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
            b =*start;// CLAMP((298 * (*start - 16) + 516 * (U - 128) + 128) >> 8);

            *dst = RGB1555(r, g, b);
        }
        // break;
    }

    ss_mpi_rgn_set_bmp(index, &members[index].regionBMP);
}


下面是效果,视频是480*270的;第1张是只有亮度,第2张是y uv都有的

我来回答
回答4个
时间排序
认可量排序

ahua

0个粉丝

6

问答

0

专栏

0

资料

ahua 2025-02-24 17:21:03
认可0

另外补充说明一下,通过ss_mpi_ive_csc也不对,而且还延迟,不知道怎么搞;

解码时,只能用chn_param.video_param.video_format = OT_VIDEO_FORMAT_TILE_64x16;这儿不能改成OT_VIDEO_FORMAT_LINEAR;文档上也写明了,只能是OT_VIDEO_FORMAT_TILE_64x16

通过region画在另一个视频上,这个功能经过非OT_VIDEO_FORMAT_TILE_64x16(通过vpss从vi取)格式的视频测试无问题

求大神求助一下

UncleRoderick

44个粉丝

16

问答

3

专栏

16

资料

UncleRoderick 2025-02-24 17:30:53
认可0

把VDEC绑定VPSS再获取OT_VIDEO_FORMAT_LINEAR数据呢?ss_mpi_ive_csc不对指的是啥?

ahua
ahua   回复   UncleRoderick  2025-02-24 18:15:22
0

就是sensor初始化序列不对,但是改了一下发现还是不对,文档上面也没有说怎么修改。

UncleRoderick
UncleRoderick   回复   ahua  2025-02-24 18:53:11
0

ss_mpi_ive_csc不涉及sensor初始化呀,它只是个把YUV跟RGB数据转换的接口

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区