Webcodecs 遇到的一些坑

2023-05-16

Webcodecs 遇到的一些坑

背景:

由于需要在web端做一款音视频剪辑软件,目前已经做到了软变软解,准备介入硬件webcodec解码的时候,遇到了一些问题,现在把问题整理如下。

问题一:通过c++调用Decoder,输出帧回调一直没有回调

C++
EM_JS(int, DecodePutBuffer, (int key_flag, int timestamp, int duration, void *pData, int nDataSize), {
    let buffer =   new Uint8Array(Module.HEAPU8.buffer, pData,  nDataSize);
    let key_string=null;
    if (key_flag)
    {
        key_string = "key";
    } 
    else
    {
        key_string = "delta";
    }
    let chunk = new EncodedVideoChunk({
    type: key_string,
    timestamp: timestamp,
    duration: duration,
    data: buffer
    });
    Module.decoder.decode(chunk);


});

 

上图中描述应该比较清楚了,我们c++线程 一直在往decoder送数据,这个任务一直在执行,导致输出帧回调一直没有及时得到调用,具体原因跟js异步执行又关系,大家可以参看我另外一个博客:

https://blog.csdn.net/c553110519/article/details/129357494?spm=1001.2014.3001.5501

显然上述设计方式满足不了这个要求,后来对js异步做了深入的学习,为了解决这个问题设计了两个方案

主线程转发

 

由于我们主线程加载wasm资源的时候,内部创建线程的内存跟主线程可以共享的,所以 主线程创建播放器线程,播放器线程创建解码器线程,一旦发现需要硬件解码,在一块内存上写上标识为,主线程轮训知道需要创建work解码线程,就去创建work,  主线程与子线程通过共享内存方式,主线程与解码器work通过postMessage方式进行通信,这样也能满足上述的要求,但是增加主线程的负担。

子线程监听与共享内存方案

 

这个方案跟上边不同的是,在主线程要创建worker解码线程的时候,把共享内存的包装SharedBuffers 传递给worker,worker 就可以跟 解码器直接通过共享内存进行交互,主线程只有在刚开始建立连接的时候发挥一次作用,后边完全交给两者了,

C++
typedef struct
{
    MInt32 dwErrorCode;
    MInt32  lKey_Width_Height;//high 1bit is key and mid 15 bit is width, low 16bit is height
    MInt32 dwDuration;
    MInt32 dwTimeStamp;
   
    MInt32  lConsumerStatus;//播放器请求解码器状态
    MInt32  lConsumerBufLen;
    MInt32  lConsumerUseLen;
    MInt32 dwConsumerBufferStatus;
    MInt32 pConsumerBuffer;

    MInt32  lProducerStatus;//worker解码当前自身状态,根据llConsumerStatus 来确认状态
    MInt32  lProducerBufLen;
    MInt32  lProducerUseLen;
    MInt32 dwProducerBufferStatus;
    MInt32 pProducerBuffer;

    MInt32 dwProfile;
    MInt32 dwProfileCompatibility;
    MInt32 dwLevel;
    MInt32 dwWorking_NoMoreOutput;
}QVET_WEBCODEC_SHARED_DATA;

整体关系是生产者与消费者的关系。

问题二:解码一段时间output只回调了几十次,后边在也不回调了

我也很奇怪,明明已经异步了,怎么还是只输出几十帧,调查了最后发先输出的VideoFrame,在使用后要Close,这样VideoFrame资源js就会回首,后边回调才能及时过来

C++
videoFrame.close();

问题三:导出视频的第一帧绿屏

  这个调查花的时间相对少一点,主要是看了api,发现

C++
VideoFrame.copyTo()
The copyTo() method of the VideoFrame interface copies the contents of the VideoFrame to an ArrayBuffer.

C++
Return value
A Promise that resolves to the layout of the copy when the copy has completed.
 

可以看出来当我把解码器copyto到自己的共享内存的时候,它是异步的,而我取的时候,以为拷贝完成了,其实没有,导致第一帧是绿色的,知道原因就好改了

JavaScript
async function SyncOutputFrame()
{
  if (queue.isEmpty)
    return ;
  let dwBufferStatus = Atomics.load(sharedBuffers, DECODER_SHARED.dwProducerBufferStatus);
  //客户端正在读取缓冲区
  if (dwBufferStatus == BUFFER_STATE.READING)
  {
    return;
  }
  //已经写了缓存一帧还没有读取
  else if (dwBufferStatus == BUFFER_STATE.WRITEED)
  {
    return;
  }
  else if (dwBufferStatus == BUFFER_STATE.WRITEING)
  {
    return ;
  }
  Atomics.store( sharedBuffers, DECODER_SHARED.dwProducerBufferStatus, BUFFER_STATE.WRITEING);
  let videoFrame = queue.dequeue();
  let pData = sharedBuffers[DECODER_SHARED.pProducerBuffer];
  let nDataSize = sharedBuffers[DECODER_SHARED.lProducerBufLen];
  let buffer =   new Uint8Array(module.buffer, pData,  nDataSize); 
  await videoFrame.copyTo(buffer);
  sharedBuffers[DECODER_SHARED.lProducerUseLen] = videoFrame.allocationSize();
  Atomics.store( sharedBuffers, DECODER_SHARED.dwProducerBufferStatus, BUFFER_STATE.WRITEED);
  // console.log("write frame size = " + videoFrame.allocationSize());

  videoFrame.close();
}

只要await下就好了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Webcodecs 遇到的一些坑 的相关文章

  • C++ friend

    在C 43 43 中 xff0c friend是一个关键字 xff0c 用于声明一个非成员函数或类可以访问另一个类的私有成员 例如 xff0c 我们有一个名为ClassA的类 xff1a span class token keyword c
  • C++ enum 和enum class

    文章目录 C 43 43 enum 和 enum class共同点区别 C 43 43 enum 和 enum class 在C 43 43 中 xff0c enum 是一种定义枚举类型的方法 一个枚举是一个整数值的命名集合 可以通过以下方
  • VS2019设置cl.exe环境变量

    版本 xff1a VS2019 设置 cl 环境变量 xff08 加入系统环境变量 xff08 PATH xff09 xff09 步骤 xff1a 1 找到cl exe的所在路径 xff0c 一般都在 xff1a C Program Fil
  • 从汇编角度看c++20 协程

    从汇编角度看c 43 43 20 协程 背景 xff1a 在学习c 43 43 20 协程的时候 xff0c 总对协程里边的局部成员存储 xff0c 以及协程栈恢复有很多疑问 xff0c 本次从过年arm64角度来分析下 xff0c 具体情
  • Win10 使用 Xrdp 远程控制 ubuntu16 闪退

    问题描述 win10使用 Xrdp 远程控制 ubuntu16 4 出现闪退 都能到这一步 xff0c 但是刚登上Xrdp4桌面就闪退 xff0c 回到下图 xfce4桌面xubuntu desktop xff0c 重新建立桌面会话 spa
  • 【华为OD机试真题 Java】字符串重新排列

    前言 本专栏将持续更新华为OD机试题目 并进行详细的分析与解答 包含完整的代码实现 希望可以帮助到正在努力的你 关于OD机试流程 面经 面试指导等 如有任何疑问 欢迎联系我 wechat steven moda email nansun09
  • atcoder abc140E (计算贡献)

    题目链接 大意 xff1a 让你 i 61 1 n
  • AtCoder Beginner Contest 143 E.Travel by Car(最短路)

    题目链接 大意 xff1a 给你一个无向带权图 xff0c 给你一些询问点 xff0c s t s t s t xff0c 你从s出发有 l
  • Ubuntu20.04软件安装大全

    目录 Ubuntu20 04 软件安装大全前言1 Windows和Ubuntu双系统安装1 1 下载Ubuntu系统镜像1 2 磁盘分区1 3 GPT分区安装Ubuntu1 4 系统完成后的一些设置1 5 遇到的一些小bug 2 换源2 1
  • 基于Nginx构建七牛云CDN静态资源加速

    创建七牛云账号 七牛云 进入管理控制台创建对象存储 3 配置nginx 使用nginx rewrite 的重定向功能进行转发到七牛云 server listen 80 server name test com 你的域名 location g
  • ChinaSkills-网络系统管理(2021年全国职业院校技能大赛A-1 模块 A:Linux 环境 真题 )

    前言 随着近年国家对技术性的比赛越来越重视 xff0c 各类技能大赛举办的相较正规 xff0c 这类大赛一般是在专科中专等技术性高中等院校中选拔优秀人才 xff0c 并且技能大赛的一等奖选手将有资格保送本科 xff0c 希望一些有能力的专科
  • Cannot resolve symbol 解决方案汇总(6种解决方案)

    Cannot resolve symbol 39 xxx 39 是比较常见一种错误 xff0c 以下整理常见的六种解决方案 xff0c 第六种会说明一下造成的原因和如何避免 方案一 检查一下pom文件依赖是否正常 xff0c 如不正常刷新m
  • 踩坑指南!import cv2出错怎么办?

    好久没有更新 xff0c 最近代码相关问题看的比较少 xff0c 有时候忙着debug就忘记了记录 xff0c 反思一下 背景 xff1a 在提取视频帧序列的时候用到了opencv包 xff0c 结果运行出错 解决 xff1a 经过查找资料
  • 最小生成树——北极通讯网络

    问题 B 北极通讯网络 时间限制 1 Sec 内存限制 128 MB 提交 17 解决 7 提交 状态 讨论版 命题人 add xiezhenghao 题目描述 北极的某区域共有n座村庄 xff08 1 n 500 xff09 xff0c
  • c++ 判定子类是否重写父类虚方法

    背景 xff1a 在做业务的时候 xff0c 有时会蹦到一个业务逻辑 xff0c 如果子类重写父类方法 xff0c 就调用 xff0c 如果没重写就不调用它 xff0c 这个逻辑在大量子类集成同一个父类的 xff0c 会节约一点点性能 xf
  • Windows | RDPWrap 远程桌面登录增强工具 (解决win10/11家庭版无法使用远程桌面 + 支持多人同时登录)

    一 前言 Windows远程桌面 Windows远程桌面是一种技术 xff0c 允许用户从远程位置访问和控制在另一个地方的Windows计算机 它可以帮助管理员和其他用户实现远程管理 技术支持和协同工作等操作 使用Windows远程桌面 x
  • 字符串匹配(java)

    字符串匹配 字符串匹配可以用到蛮力法 对于字符串s和t xff0c 若t是s的子串 xff0c 返回t在s中的位置 xff08 t的首字符在s中的下标 xff09 xff0c 否则返回 1 采用的是穷举法 xff0c 从s的第一个字符开始查

随机推荐

  • 警告:Establishing SSL connection without server's identity verification is not recommended

    解决方法 那问题来了 xff0c SSL是什么 xff1f SSL xff08 Secure Socket Layer xff1a 安全套接字层 xff09 利用数据加密 身份验证和消息完整性验证机制 xff0c 为基于TCP等可靠连接的应
  • NestJs-项目创建

    NestJs Nest js 用于构建高效且可伸缩的服务端应用程序的渐进式 Node js 框架 项目创建 构建工具 可以使用 npm yarn pnpm进行包管理 xff0c 但议使用pnpm建议安装nrm镜像源管理工具 xff0c 可以
  • C++ 字符串格式化

    使用snprintf格式化字符串使用boost format格式化字符串使用stringstream格式化字符串 具体示例 使用snprintf格式化字符串 span class token macro property span clas
  • 玩客云 一个百元级的微型服务器

    前言 下面这段基本是copy的 xff0c 就是图个完整 xff0c 不要觉得奇怪哈 玩客云是一款前些年很火的矿机 xff0c 曾经在官网售卖 xffe5 599 xff0c 现在已经沦落到 xffe5 45包邮的田地了 当然这边一般有两种
  • OpenStack双节点部署—M Manila(共享文件系统服务)

    Manila安装 一 数据库配置二 创建服务凭证和API端点三 安装并配置Heat四 启动服务并设置开机自启 一 数据库配置 Controller节点 mysql span class token operator span uroot s
  • Dockerfile简介

    1 什么是dockerfile Dockerfile是一个包含用于组合映像的命令的文本文档 可以使用在命令行中调用任何命令 Docker通过读取Dockerfile中的指令自动生成映像 docker build命令用于从Dockerfile
  • 论文阅读笔记1:EKT: Exercise-aware Knowledge Tracing for Student Performance Prediction

    该篇论文于2019年在IEEE发表 xff0c 作者为 xff1a Qi Liu Zhenya Huang Yu Yin Enhong Chen Hui Xiong Yu Su and Guoping Hu 等 知识追踪 xff08 Kno
  • 树莓派 同时使用有线和无线网卡

    树莓派同时使用有线和无线 使能双网卡待机 添加路由使用规范 备注 192 168 1 0 表明所有以192 168 1开始的网段 都将从后面的设备发送相应的数据 使能双网卡待机 Linux通过设置默认的网络信息实现双网卡待机 设置方法如下
  • c++20 协程本质

    c 43 43 20 协程本质 背景 xff1a 最近因项目关系 xff0c web端 xff0c js异步调用 xff0c 发现跟本门的C 43 43 20 还是有些不一样的 xff0c 本文主要从另外一个角度来看 什么是协程 协程是能暂
  • Manjaro 21安装搜狗输入法

    Manjaro 21安装搜狗输入法 文章目录 Manjaro 21安装搜狗输入法安装输入法Step 1 打开 96 Manjaro Hello 96 点击 96 Application 96 Step 2 切换语言到 96 Chinese
  • Unicode控制字符

    Unicode控制字符 一 前言 在所有主要的Web浏览器中内存中的字符顺序 xff08 逻辑 xff09 与它们显示的顺序 xff08 可视 xff09 是不同的 Unicode 定义了它其中每个字符的方向属性 xff0c 浏览器应用的一
  • tomcat-9.0.36的安装与环境配置

    环境 xff1a 操作系统 xff1a Windows10 64bitTomcat版本 xff1a Tomcat 9 0 36 一 从官网下载tomcat的安装包 1 用浏览器打开Tomcat的官网 官网地址 xff1a https tom
  • 已无线上网的ubuntu机通过网线给其他电脑上网的方法

    首先 xff0c 将ubunt通过无线连上网 用网线将两者连接起来 xff0c 打开ubuntu的有线连接 另一台电脑连接 二者网络地址
  • Pip离线打包与安装

    pip导出与安装 步骤一 xff1a 打包已安装的依赖包 pip freeze gt requirements txt 生成已安装包清单 如本地保留了之前下载的各依赖包 xff0c 直接将各whl tar zip包保存到某个文件夹下 xff
  • Proxmox VE常见问题以及解决办法(持续更新)

    虚拟机出现问题状态为unkonw的解决方法 解决方法 service rrdcached stop rm rf var lib rrdcached service rrdcached start 原帖链接
  • error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found

    错误提醒 错误 1 error MSB8020 The build tools for Visual Studio 2010 Platform Toolset 61 v100 cannot be found To build using t
  • 头文件循环引用验证:#pragma once和#ifndef

    在一个项目中 xff0c 如果两次 xff03 include aaa h xff08 比如bbb h包含了aaa h xff0c 而ccc h即包含bbb h又包含aaa h xff09 就会出错 xff0c 因为相同的类不能定义两次 把
  • 证明,若gcd(n,i) == 1,那么gcd(n,n-i)==1

    证明 xff0c 若gcd n i 61 61 1 那么gcd n n i 61 61 1 解 xff1a 设gcd n i 61 61 1 gcd n n i 61 61 k 61 1 那么n与 n i 的最大公约数为k n k 61 6
  • java 两数组交集/差集/补集 多种方式实现记录

    1 明确概念 首先知道几个单词的意思 xff1a 并集 61 union 交集 61 intersection 补集 61 complement 析取 61 disjunction 减去 61 subtract 1 1 并集 对于两个给定集
  • Webcodecs 遇到的一些坑

    Webcodecs 遇到的一些坑 背景 xff1a 由于需要在web端做一款音视频剪辑软件 xff0c 目前已经做到了软变软解 xff0c 准备介入硬件webcodec解码的时候 xff0c 遇到了一些问题 xff0c 现在把问题整理如下