如何在 Cocoa OpenGL 程序中显示原始 YUV 帧

2023-12-07

我被分配的任务是编写一个程序,该程序获取示例原始 YUV 文件并将其显示在 Cocoa OpenGL 程序中。

我是一名实习生,我几乎不知道如何开始。我一直在阅读维基百科和有关 YUV 的文章,但我找不到任何关于如何打开原始 YUV 文件、提取数据并将其转换为 RGB 并将其显示在视图窗口中的好的源代码。

本质上,我需要任务的以下方面的帮助 -如何从示例YUV文件中提取YUV数据 -如何将YUV数据转换为RGB色彩空间 -如何在 OpenGL 中显示 RGB 颜色空间。 (这个我想我可以随着时间的推移弄清楚,但我真的需要前两点的帮助)

请告诉我要使用的类,或者指出我可以学习 YUV 图形/视频显示的地方


我已经用 CCD 相机捕获的 YUV 帧完成了此操作。不幸的是,有许多不同的 YUV 格式。我相信苹果公司使用的那个GL_YCBCR_422_APPLE从技术上讲,纹理格式是 2VUY422。要将图像从 IIDC Firewire 相机生成的 YUV422 帧转换为 2VUY422,我使用了以下命令:

void yuv422_2vuy422(const unsigned char *theYUVFrame, unsigned char *the422Frame, const unsigned int width, const unsigned int height) 
{
    int i =0, j=0;
    unsigned int numPixels = width * height;
    unsigned int totalNumberOfPasses = numPixels * 2;
    register unsigned int y0, y1, y2, y3, u0, u2, v0, v2;

    while (i < (totalNumberOfPasses) )
    {
        u0 = theYUVFrame[i++]-128;
        y0 = theYUVFrame[i++];
        v0 = theYUVFrame[i++]-128;
        y1 = theYUVFrame[i++];
        u2 = theYUVFrame[i++]-128;
        y2 = theYUVFrame[i++];
        v2 = theYUVFrame[i++]-128;
        y3 = theYUVFrame[i++];

        // U0 Y0 V0 Y1 U2 Y2 V2 Y3

        // Remap the values to 2VUY (YUYS?) (Y422) colorspace for OpenGL
        // Y0 U Y1 V Y2 U Y3 V

        // IIDC cameras are full-range y=[0..255], u,v=[-127..+127], where display is "video range" (y=[16..240], u,v=[16..236])

        the422Frame[j++] = ((y0 * 240) / 255 + 16);
        the422Frame[j++] = ((u0 * 236) / 255 + 128);
        the422Frame[j++] = ((y1 * 240) / 255 + 16);
        the422Frame[j++] = ((v0 * 236) / 255 + 128);
        the422Frame[j++] = ((y2 * 240) / 255 + 16);
        the422Frame[j++] = ((u2 * 236) / 255 + 128);
        the422Frame[j++] = ((y3 * 240) / 255 + 16);
        the422Frame[j++] = ((v2 * 236) / 255 + 128);
    }
}

为了高效显示 YUV 视频源,您可能希望使用Apple 的客户端存储扩展,您可以使用类似以下内容进行设置:

glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);

glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, videoImageWidth * videoImageHeight * 2, videoTexture);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);

glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, videoImageWidth, videoImageHeight, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);    

这使您可以在每帧显示在屏幕上之前快速更改客户端视频纹理中存储的数据。

要绘制,您可以使用如下代码:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         
glEnable(GL_TEXTURE_2D);

glViewport(0, 0, [self frame].size.width, [self frame].size.height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
NSRect bounds = NSRectFromCGRect([self bounds]);
glOrtho( (GLfloat)NSMinX(bounds), (GLfloat)NSMaxX(bounds), (GLfloat)NSMinY(bounds), (GLfloat)NSMaxY(bounds), -1.0, 1.0);

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 1);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, videoImageWidth, videoImageHeight, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0f, videoImageHeight);

    glTexCoord2f(0.0f, videoImageHeight);
    glVertex2f(0.0f, 0.0f);

    glTexCoord2f(videoImageWidth, videoImageHeight);
    glVertex2f(videoImageWidth, 0.0f);

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

如何在 Cocoa OpenGL 程序中显示原始 YUV 帧 的相关文章

随机推荐

  • 如何序列化java中实现的链表?

    我在网上读到 通过将派生对象声明为瞬态 可以省略派生对象的序列化 但是 在链表的情况下 链接是对象之间的内存引用 那么 我应该将其转换为数组并存储数组表示形式吗 Java 序列化的方式如下LinkedList 它获取所有元素并将它们写入Ob
  • 列表 - 如何查找某个项目出现的次数[重复]

    这个问题在这里已经有答案了 可能的重复 如何计算Python中列表项的出现次数 我正在进行一项民意调查 为此 我正在使用 Python 而我所坚持的部分是试图弄清楚如何计算特定事物 例如 杂货店 出现的次数 例如 民意调查 您最常在哪里看到
  • geohash 和最大距离

    前 6 个字符匹配的两个 geohash 两个 geohash 之间的距离最大为 0 61km 前 5 个字符匹配的两个 geohash 两个 geohash 之间的距离最大为 2 5km 问 5 位长度的给定 geohash 的任何一对边
  • CodeIgniter:解析位于 javascript 中的动态语言标题

    我有一个需要本地化的 JavaScript 代码 即 function js proc var some data this text needs to be translated dynamically at runtime 所以我这样重
  • 设置“可见性”后未获取“RelativeLayout get Height()”

    我想要的是 当我单击仪表板按钮时 它将像滑动抽屉一样打开 打开后再次单击它 它将关闭 我使用这个自定义抽屉是因为 SlidingDrawer 已弃用 现在的问题是 它工作正常 除了第一次单击按钮时 它会打开得非常快 没有任何动画 但会正常关
  • 有没有办法在Python Selenium中通过属性查找元素?

    我得到了这样的 html 片段
  • 使用 WMI 和 C# 的 CPU 使用率

    如何使用 WMI 在 C 中检索当前 CPU 使用情况 我看过很多使用性能计数器的帖子 但我需要一个可以与远程计算机一起使用的解决方案 我还找到了一个VB解决方案here 但如果可能的话 我更愿意在 C 中完成此任务 至少可以说 WMI 的
  • Rust 不接收来自 C++ 的 UDP 消息

    我正在使用 UDP 创建服务器 客户端范例 但 Rust 服务器未接收 C 客户端消息 我已经能够成功地进行 Rust 服务器 Rust 客户端和 C 服务器 Rust 客户端通信 这让我相信我的 C 代码存在问题 或者在将 C 缓冲区发送
  • 为什么 x86-64 汇编中参数存储在寄存器中而不是堆栈中?

    在 x86 32 汇编中 参数存储在堆栈中 但在 x86 64 中 参数存储在寄存器中 这是什么原因呢 访问 CPU 寄存器比访问 RAM 快得多 由于 64 位 CPU 有更多通用寄存器 与 64 位无关 只是因为它们更新 更大 因此使用
  • 如何使用有效的 CSS 来定位 IE7 和 IE8?

    我想使用符合 W3C 的 CSS 来定位 IE7 和 IE8 有时修复一个版本的 CSS 并不能修复另一个版本的 CSS 我怎样才能实现这个目标 使用 HTML 和 CSS 明确定位 IE 版本 无需破解 如果您不想对 CSS 进行修改 请
  • 构建Word字段

    除了将文本插入和解析到空白 Word 字段之外 是否有任何方法可以使用 VBA 以编程方式将用户定义的字段和字段代码构建到我自己的模板中 此外 有没有办法让这些字段显示在可用字段列表中 我最近开发了一个使用 Word 的 MACROBUTT
  • 使用后台线程从 url 加载注释。移动或缩放地图视图之前不会显示图钉

    我使用后台线程从 url 加载注释 在移动或缩放地图视图之前 图钉不会显示 我如何更新我的视图 我的观点确实出现了 void viewDidAppear BOOL animated super viewDidAppear animated
  • static const int 和 static int const 有什么区别?

    In this answer使用的OP static int const var 5 在条件编译控制的上下文中 使用之间有区别吗static const int and static int const 例如 static const in
  • 检测 pygtk 中的 ctrl+click 按钮

    我想检测当用户单击按钮时是否按住 ctrl 点击 信号似乎没有向回调传递足够的信息来解决这个问题 如果您可以连接到button press event or button release event代替clicked the event传递
  • Android 对位图的噪点效果

    我正在编写一些函数来在位图上添加噪点效果 我发现类似的问题 向绘图添加噪点效果 位图输出Bitmap Bitmap createBitmap bitmap getWidth bitmap getHeight Bitmap Config AR
  • 反转字符串时间和空间复杂度

    我编写了不同的 python 代码来反转给定的字符串 但是 无法确定其中哪一个是有效的 有人可以指出这些算法在时间和空间复杂度上的差异吗 def reverse 1 s result for i in s result i result r
  • Rails 视图下拉列表中的日期格式

    我可以帮助您格式化视图中下拉列表中的日期字段 我的日期显示带有时间戳 我希望它们显示为 mm dd yyyy 在我的模型中 我有一个从表中选择日期字段的方法 def self get event dates event dates Ugra
  • 使用 mutate 和 for 循环(按变量名前缀)对多组变量进行 R rowSums

    我有多个变量按前缀 par fri gp 等 分组在一起 其中有 29 个组 每个变量的值为 0 或 1 我需要做的是对这些组 即 partner 1 Partner 2 等 求和 如果 rowSums 0 则使每个变量为 NA 例如 我的
  • 风险管理:如果已经做多,则不要下新订单

    如果该标志已经指示长 则不应有新的指示长的标志 如果标志不指示长计算表达式 longCondition if strategy long false rsi lt 30 and close gt moving avg shortCondit
  • 如何在 Cocoa OpenGL 程序中显示原始 YUV 帧

    我被分配的任务是编写一个程序 该程序获取示例原始 YUV 文件并将其显示在 Cocoa OpenGL 程序中 我是一名实习生 我几乎不知道如何开始 我一直在阅读维基百科和有关 YUV 的文章 但我找不到任何关于如何打开原始 YUV 文件 提