【音视频 | Ogg】libogg库详细介绍以及使用——附带libogg库解析.opus文件的C源码

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍libogg库,并给出ligogg库使用的例子🍭
😎金句分享😎:🍭子曰:不患人之不己知,患不知人也。——《论语·学而篇》。意思是,不要担心别人不了解自己,只需要担心自己不了解别人。🍭

本文未经允许,不得转发!!!

相关文章:
1、RFC3533 :Ogg封装格式版本 0(The Ogg Encapsulation Format Version 0)
2、Ogg封装格式详解——包含Ogg封装过程、数据包(packet)、页(page)、段(segment)等
3、libogg库详解介绍以及使用——附带libogg库解析.opus文件的C源码

目录

  • 🎄一、libogg库概述
  • 🎄二、libogg库编译
    • ✨2.1 编译环境如下:
    • ✨2.2 libogg编译
  • 🎄三、libogg库简单介绍
    • ✨3.1 ogg.h 头文件
    • ✨3.2 libogg 库函数解析
  • 🎄四、Ogg封装格式使用 libogg 库解码——C语言代码
  • 🎄五、总结


在这里插入图片描述

🎄一、libogg库概述

Ogg是一种多媒体容器格式,是Xiph.org多媒体编解码器的原生文件和流格式。与所有Xiph.org技术一样,它是一种开放的格式,任何人都可以免费使用。

libogg库包含创建、解码和处理ogg比特流的必要功能。最新版本稳定版本更新到1.3.4,开发版本更新到1.3.5,libogg库的下载链接:https://xiph.org/downloads/
在这里插入图片描述

在这里插入图片描述

🎄二、libogg库编译

本文下载的是libogg-1.3.5.tar.gz

✨2.1 编译环境如下:

$ uname -a
Linux ubuntu 4.4.0-128-generic #154~14.04.1-Ubuntu SMP Fri May 25 14:58:51 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:        14.04
Codename:       trusty$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.4' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4) 

✨2.2 libogg编译

tar zxvf libogg-1.3.5.tar.gz
cd libogg-1.3.5/
./configure --prefix=`pwd`/result_gcc
make && make install

在这里插入图片描述

🎄三、libogg库简单介绍

✨3.1 ogg.h 头文件

libogg库的所有结构体和函数都定义在 ogg.h 头文件中,并且大概分为5个部分:

  • 1、结构体;
  • 2、比特流打包函数;
  • 3、Ogg编码相关函数;
  • 4、Ogg解码相关函数;
  • 5、通用函数。

头文件内容如下:

/*********************************************************************                                                                  ** THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   ** USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     ** GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE ** IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       **                                                                  ** THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             ** by the Xiph.Org Foundation http://www.xiph.org/                  **                                                                  *********************************************************************function: toplevel libogg include********************************************************************/
#ifndef _OGG_H
#define _OGG_H#ifdef __cplusplus
extern "C" {
#endif#include <stddef.h>
#include <ogg/os_types.h>typedef struct {void *iov_base;size_t iov_len;
} ogg_iovec_t;typedef struct {long endbyte;int  endbit;unsigned char *buffer;unsigned char *ptr;long storage;
} oggpack_buffer;/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/typedef struct {unsigned char *header;long header_len;unsigned char *body;long body_len;
} ogg_page;/* ogg_stream_state contains the current encode/decode state of a logicalOgg bitstream **********************************************************/typedef struct {unsigned char   *body_data;    /* bytes from packet bodies */long    body_storage;          /* storage elements allocated */long    body_fill;             /* elements stored; fill mark */long    body_returned;         /* elements of fill returned */int     *lacing_vals;      /* The values that will go to the segment table */ogg_int64_t *granule_vals; /* granulepos values for headers. Not compactthis way, but it is simple coupled to thelacing fifo */long    lacing_storage;long    lacing_fill;long    lacing_packet;long    lacing_returned;unsigned char    header[282];      /* working space for header encode */int              header_fill;int     e_o_s;          /* set when we have buffered the last packet in thelogical bitstream */int     b_o_s;          /* set after we've written the initial pageof a logical bitstream */long    serialno;long    pageno;ogg_int64_t  packetno;  /* sequence number for decode; the framingknows where there's a hole in the data,but we need coupling so that the codec(which is in a separate abstractionlayer) also knows about the gap */ogg_int64_t   granulepos;} ogg_stream_state;/* ogg_packet is used to encapsulate the data and metadata belongingto a single raw Ogg/Vorbis packet *************************************/typedef struct {unsigned char *packet;long  bytes;long  b_o_s;long  e_o_s;ogg_int64_t  granulepos;ogg_int64_t  packetno;     /* sequence number for decode; the framingknows where there's a hole in the data,but we need coupling so that the codec(which is in a separate abstractionlayer) also knows about the gap */
} ogg_packet;typedef struct {unsigned char *data;int storage;int fill;int returned;int unsynced;int headerbytes;int bodybytes;
} ogg_sync_state;/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/extern void  oggpack_writeinit(oggpack_buffer *b);
extern int   oggpack_writecheck(oggpack_buffer *b);
extern void  oggpack_writetrunc(oggpack_buffer *b,long bits);
extern void  oggpack_writealign(oggpack_buffer *b);
extern void  oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
extern void  oggpack_reset(oggpack_buffer *b);
extern void  oggpack_writeclear(oggpack_buffer *b);
extern void  oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void  oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
extern long  oggpack_look(oggpack_buffer *b,int bits);
extern long  oggpack_look1(oggpack_buffer *b);
extern void  oggpack_adv(oggpack_buffer *b,int bits);
extern void  oggpack_adv1(oggpack_buffer *b);
extern long  oggpack_read(oggpack_buffer *b,int bits);
extern long  oggpack_read1(oggpack_buffer *b);
extern long  oggpack_bytes(oggpack_buffer *b);
extern long  oggpack_bits(oggpack_buffer *b);
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);extern void  oggpackB_writeinit(oggpack_buffer *b);
extern int   oggpackB_writecheck(oggpack_buffer *b);
extern void  oggpackB_writetrunc(oggpack_buffer *b,long bits);
extern void  oggpackB_writealign(oggpack_buffer *b);
extern void  oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
extern void  oggpackB_reset(oggpack_buffer *b);
extern void  oggpackB_writeclear(oggpack_buffer *b);
extern void  oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void  oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
extern long  oggpackB_look(oggpack_buffer *b,int bits);
extern long  oggpackB_look1(oggpack_buffer *b);
extern void  oggpackB_adv(oggpack_buffer *b,int bits);
extern void  oggpackB_adv1(oggpack_buffer *b);
extern long  oggpackB_read(oggpack_buffer *b,int bits);
extern long  oggpackB_read1(oggpack_buffer *b);
extern long  oggpackB_bytes(oggpack_buffer *b);
extern long  oggpackB_bits(oggpack_buffer *b);
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);/* Ogg BITSTREAM PRIMITIVES: encoding **************************/extern int      ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
extern int      ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,int count, long e_o_s, ogg_int64_t granulepos);
extern int      ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
extern int      ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
extern int      ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
extern int      ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);/* Ogg BITSTREAM PRIMITIVES: decoding **************************/extern int      ogg_sync_init(ogg_sync_state *oy);
extern int      ogg_sync_clear(ogg_sync_state *oy);
extern int      ogg_sync_reset(ogg_sync_state *oy);
extern int      ogg_sync_destroy(ogg_sync_state *oy);
extern int      ogg_sync_check(ogg_sync_state *oy);extern char    *ogg_sync_buffer(ogg_sync_state *oy, long size);
extern int      ogg_sync_wrote(ogg_sync_state *oy, long bytes);
extern long     ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
extern int      ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
extern int      ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
extern int      ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
extern int      ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);/* Ogg BITSTREAM PRIMITIVES: general ***************************/extern int      ogg_stream_init(ogg_stream_state *os,int serialno);
extern int      ogg_stream_clear(ogg_stream_state *os);
extern int      ogg_stream_reset(ogg_stream_state *os);
extern int      ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
extern int      ogg_stream_destroy(ogg_stream_state *os);
extern int      ogg_stream_check(ogg_stream_state *os);
extern int      ogg_stream_eos(ogg_stream_state *os);extern void     ogg_page_checksum_set(ogg_page *og);extern int      ogg_page_version(const ogg_page *og);
extern int      ogg_page_continued(const ogg_page *og);
extern int      ogg_page_bos(const ogg_page *og);
extern int      ogg_page_eos(const ogg_page *og);
extern ogg_int64_t  ogg_page_granulepos(const ogg_page *og);
extern int      ogg_page_serialno(const ogg_page *og);
extern long     ogg_page_pageno(const ogg_page *og);
extern int      ogg_page_packets(const ogg_page *og);extern void     ogg_packet_clear(ogg_packet *op);#ifdef __cplusplus
}
#endif#endif  /* _OGG_H */

✨3.2 libogg 库函数解析

下面简单介绍在Ogg封装格式解码过程中需要用到的库函数,需要了解更多库函数解释的可以参考:https://xiph.org/ogg/doc/libogg/reference.html

int      ogg_sync_init(ogg_sync_state *oy);
功能:将 ogg_sync_state *结构体 初始化为已知状态
参数:ogg_sync_state *
long     ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
功能: 将同步到比特流中的下一页,并返回关于我们前进或跳过了多少字节的信息。
返回值:-n:跳过的字节;0:页没准备好,需要更多的字节,且没跳过字节;n:页的总字节数n
char    *ogg_sync_buffer(ogg_sync_state *oy, long size);
功能:分配数据缓冲区
int      ogg_sync_wrote(ogg_sync_state *oy, long bytes);
功能:告知添加了多少字节
int      ogg_page_bos(const ogg_page *og);
功能:起始页返回1//--------------------------------------
int      ogg_page_eos(const ogg_page *og);
功能:结束页返回1//--------------------------------------
ogg_int64_t  ogg_page_granulepos(const ogg_page *og);
功能:获取页的 granule position//--------------------------------------
int      ogg_page_serialno(const ogg_page *og);
功能:获取流的序列号//--------------------------------------
long     ogg_page_pageno(const ogg_page *og);
功能:获取页的序号//--------------------------------------
int      ogg_page_packets(const ogg_page *og);
功能:获取页的的包(段segment)个数
int      ogg_stream_init(ogg_stream_state *os,int serialno);
功能:初始化ogg_stream_state结构,并分配适当的内存以准备编码或解码//--------------------------------------
int      ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
功能:将一个完整的页面添加到比特流中。//--------------------------------------
int      ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
功能:数据已经被提交到ogg_stream_state之后。每次连续调用该函数都会返回从这些数据段构建的下一个完整数据包。//--------------------------------------
int      ogg_stream_clear(ogg_stream_state *os);
功能:这个函数清除并释放ogg_stream_state结构使用的内部内存,但不释放结构本身。在同一个结构上多次调用ogg_stream_clear是安全的。

在这里插入图片描述

🎄四、Ogg封装格式使用 libogg 库解码——C语言代码

在 上篇文章 第五小节 ,笔者用C语言写了一个读取Ogg文件的测试程序,现在,这里使用ligogg库再实现一个Ogg封装格式文件读取的程序。

解码程序步骤:

  • 1、打开文件;
  • 2、调用 ogg_sync_init 初始化一个ogg_sync_state结构体;
  • 3、获取一页数据,并处理;
    • 3.1、根据序列号初始化一个比特流 ogg_stream_init
    • 3.2、把页数据给到比特流 ogg_stream_pagein
    • 3.3、获取数据包 ogg_stream_packetout
    • 3.4、释放比特流;
  • 4、关闭文件

程序使用的 48000Hz-s16le-1ch-ChengDu.opus ,是opus编码的Ogg封装文件。

程序编译需要了解前面编译好的ligogg库和头文件,参考:

gcc liboggDec.c ../../libogg-1.3.5/result_gcc/lib/libogg.a -I ../../libogg-1.3.5/result_gcc/include/

Ogg文件解码程序如下,虽然并没有完整解析出音频,但可以加深对libogg库的理解:

// ligoggDec.c
// gcc liboggDec.c ../../libogg-1.3.5/result_gcc/lib/libogg.a -I ../../libogg-1.3.5/result_gcc/include/
/*
* ogg_sync_init:将结构体初始化为已知状态* ogg_sync_pageseek: 将同步到比特流中的下一页,并返回关于我们前进或跳过了多少字节的信息。返回值:-n:跳过的字节;0:页没准备好,需要更多的字节,且没跳过字节;n:页的总字节数n* ogg_sync_buffer:分配数据缓冲区* ogg_sync_wrote:告知添加了多少字节* ogg_page_serialno:获取序列号* ogg_page_bos:起始页* ogg_page_eos:结束页* ogg_page_pageno:获取页号* ogg_page_granulepos:获取页 granule pos* ogg_page_packets:获取该页 段 (segment)个数* ogg_stream_init:初始化ogg_stream_state结构,并分配适当的内存以准备编码或解码* ogg_stream_pagein:将一个完整的页面添加到比特流中。* ogg_stream_packetout:数据已经被提交到ogg_stream_state之后。每次连续调用该函数都会返回从这些数据段构建的下一个完整数据包。* ogg_stream_clear:这个函数清除并释放ogg_stream_state结构使用的内部内存,但不释放结构本身。在同一个结构上多次调用ogg_stream_clear是安全的。
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>#include "ogg/ogg.h"#define CHUNK 4096ogg_sync_state g_ogsync;
ogg_page g_page;// 获取下一页数据 2023-11-03 10:31:28
static int get_next_page(FILE *f, ogg_sync_state *ogsync, ogg_page *page,ogg_int64_t *written)
{int ret;char *buffer;size_t bytes;while((ret = ogg_sync_pageseek(ogsync, page)) <= 0) {if(ret < 0) {/* unsynced, we jump over bytes to a possible capture - we don't need to read more just yet */printf("WARNING: Hole in data (%d bytes) found at approximate offset %" PRId64 " bytes. Corrupted Ogg.\n", -ret, *written);continue;}/* zero return, we didn't have enough data to find a whole page, read */buffer = ogg_sync_buffer(ogsync, CHUNK);bytes = fread(buffer, 1, CHUNK, f);if(bytes == 0) {ogg_sync_wrote(ogsync, 0);return 0;}ogg_sync_wrote(ogsync, (long)bytes);*written += bytes;}return 1;
}int main()
{FILE *file = fopen("48000Hz-s16le-1ch-ChengDu.opus", "rb");if(!file) {printf("fopen error\n");return -1;}ogg_sync_init(&g_ogsync);ogg_int64_t written;while (get_next_page(file, &g_ogsync, &g_page, &written)){int packets = ogg_page_packets(&g_page);printf("page_num:%03lu; ",ogg_page_pageno(&g_page));printf("Oggs:%c %c %c %c; ",g_page.header[0],g_page.header[1],g_page.header[2],g_page.header[3]);printf("type=%d, granule_position:%08lld, seg_num=%d; ", g_page.header[5],(long long)ogg_page_granulepos(&g_page), packets);// 准备bit流ogg_stream_state streamState;ogg_packet packet;ogg_stream_init(&streamState, ogg_page_serialno(&g_page)); // 给定一个流序列号,初始化 streamStateogg_stream_pagein(&streamState, &g_page); // 将页数据给到 比特流int i = 0;for(i=0; i<packets; i++){ogg_stream_packetout(&streamState, &packet);if(packet.bytes >= 19 && memcmp(packet.packet, "OpusHead", 8)==0){printf("OpusHead; ");}}printf("\n");ogg_stream_clear(&streamState);}return 0;
}

Ogg编码程序,这里就不给了,需要的话,可以去看看opus-tool工具的源码。

在这里插入图片描述

🎄五、总结

本文介绍了ligogg-1.3.5库的下载、编译,以及个别库函数的用法,最后给出一个Ogg封装格式的解码程序代码。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/180830.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uni-app小程序使用vant

步骤一&#xff1a;安装 Vant Weapp # 通过 npm 安装 npm i vant/weapp -S --production# 通过 yarn 安装 yarn add vant/weapp --production# 安装 0.x 版本 npm i vant-weapp -S --production步骤二&#xff1a;在根目录下创建“wxcomponents”文件夹 步骤三&#xff1a;找…

分享86个工作总结PPT,总有一款适合您

分享86个工作总结PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;https://pan.baidu.com/s/12aRTr5NKG5YTnMnwNbqOrQ?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易。知…

利用 docker 实现JMeter分布式压测

为什么需要分布式&#xff1f; 在工作中经常需要对一些关键接口做高QPS的压测&#xff0c;JMeter是由Java 语言开发&#xff0c;没创建一个线程&#xff08;虚拟用户&#xff09;&#xff0c;JVM默认会为每个线程分配1M的堆栈内存空间。受限于单台试压机的配置很难实现太高的并…

计算机组成与体系结构

计算机组成与体系结构&#xff08;2-4分&#xff09; 课程摘要 计算机组成结构 CPU组成 骚戴理解&#xff1a; 指令寄存器&#xff08;IR&#xff09;存放的是从内存中取得指令&#xff0c;就像个中间站一样&#xff0c;不过是存放指令的中间站程序计数器&#xff08;PC&…

在Photoshop中如何校正倾斜的图片

在Photoshop中如何校正倾斜的图片呢&#xff1f;今天就教大家如何操作。 将需要操作的图片拉到PS软件中&#xff0c;自动形成项目。 点击上方“滤镜”中的“镜头校正”。 进入“镜头校正”窗口&#xff0c;点击左侧的“拉直工具”。文章源自设计学徒自学网-http://www.sx1c.co…

Java日期比较大小的3种方式及拓展

目录 一、字符串String的日期比较 二、数值型long比较 三、日期型Date直接比较 四、Date型日期的获取方式 五、Calendar获取年月日【拓展】 一、字符串String的日期比较 String型的日期通过compareTo()来比较&#xff0c;因为String实现了comparable接口 endDate.compare…

006 Linux 进程的概念 | 获取进程的PID

前言 本文将会向您进程的概念&#xff0c;程序与进程的区别&#xff0c;如何获取进程的标识符-pid 文章重点 1.描述进程——PCB 进程与程序的区别 CPU对进程列表的处理 2.获取进程PID 描述进程-PCB 进程概念 课本概念&#xff1a;程序的一个执行实例或正在执行的程序 内核…

C语言,数据结构指针,结构构体操作符 •,->,*的区别,看这篇就够了

在朋友们学习指针和数据结构这一章的时候&#xff0c;对各种操作符云里雾里。当你看到这么文章之后你就会明白了。 一 • 和 ->运算符 • 运算符&#xff1a;是结构变量访问结构体成员时用的操作符 -> 运算符&#xff1a;这是结构体指针访问结构体成员时调用的运算符。 …

基于java+springboot+vue的游戏道具管理系统

项目介绍 本论文主要论述了如何使用JAVA语言开发一个游戏道具管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述校园出入管理系统的当前背景以及系统开…

02-React组件与模块

组件与模块 前期准备 安装React官方浏览器调试工具&#xff0c;浏览器扩展搜索即可 比如红色的React就是本地开发模式 开启一个用React写的网站&#xff0c;比如美团 此时开发状态就变成了蓝色 组件也能解析出来 何为组件&模块 模块&#xff0c;简单来说就是JS代…

音视频rtsp rtmp gb28181在浏览器上的按需拉流

按需拉流是从客户视角来看待音视频的产品功能&#xff0c;直观&#xff0c;好用&#xff0c;为啥hls flv大行其道也是这个原因&#xff0c;不过上述存在的问题是延迟没法降到实时毫秒级延迟&#xff0c;也不能随心所欲的控制。通过一段时间的努力&#xff0c;结合自己闭环技术栈…

使用合成数据训练语义分割模型

计算机视觉应用现在在各个科技领域无处不在。 这些模型高效且有效&#xff0c;研究人员每年都会尝试新想法。 新的前沿是试图消除深度学习的最大负担&#xff1a;需要大量的标记数据。 正如本文所述&#xff0c;此问题的解决方案是使用合成数据。 从这些研究中获益最多的计算机…

FMC+DAM驱动LVGL刷屏

前提条件 使用FMC驱动LCD刷屏 LVGL移植 开启DMA 需要开启MEMTOMEMDMA。 开启MPU 有MPU时需要 使能I-cache D-cache时 使用DMA传输数据时要保证数据的完整行和准确性 修改代码 逻辑 等待DMA传输完成然后再刷屏。 修改 在DMA初始化函数中最后添加 注册DMA传输完成调用函…

k8s:二进制搭建 Kubernetes v1.20

目录 1 操作系统初始化配置 2 部署 etcd 集群 2.1 准备签发证书环境 2.2 生成Etcd证书 3 部署 docker引擎 4 部署 Master 组件 5 部署 Worker Node 组件 k8s集群master01&#xff1a;192.168.30.105 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集…

05-流媒体-RTMP协议介绍

05-流媒体-RTMP协议介绍 1.RTMP概述 RTMP是一种常见的流媒体协议,是基于TCP/IP协议模型的应用层协议,工作在TCP协议上,端口是1935。通过TCP三次握手保证传输的可靠。 2.握手 2.1 握手过程 RTMP基于传输层TCP连接后,通过RTMP握手协议来完成RTMP连接。客户端和服务端各发…

将Series中每个值v替换为v在Series中升序排列时的位置值s.rank()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将Series中每个值v 替换为v在Series中 升序排列时的位置值 s.rank() 选择题 下列代码执行三次排名索引a的名次值分别为&#xff1f; import pandas as pd s pd.Series([3,2,0,3],index list…

分享96个工作总结PPT,总有一款适合您

分享96个工作总结PPT&#xff0c;总有一款适合您 工作总结PPT下载链接&#xff1a;https://pan.baidu.com/s/18AriuVGxwINHrmgndX74dw?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易…

【kafka】记一次kafka基于linux的原生命令的使用

环境是linux&#xff0c;4台机器&#xff0c;版本3.6&#xff0c;kafka安装在node 1 2 3 上&#xff0c;zookeeper安装在node2 3 4上。 安装好kafka&#xff0c;进入bin目录&#xff0c;可以看到有很多sh文件&#xff0c;是我们执行命令的基础。 启动kafka&#xff0c;下面的…

python 深度学习 解决遇到的报错问题9

本篇继python 深度学习 解决遇到的报错问题8-CSDN博客 目录 一、can only concatenate str (not "int") to str 二、cant convert np.ndarray of type numpy.object_. The only supported types are: float64, float32, float16, complex64, complex128, int64, in…

74HC138逻辑芯片

文章目录 74系列逻辑芯片——74HC138基础信息描述特征应用范围 功能信息封装引脚基本电路 扩展性能分析 74系列逻辑芯片——74HC138 基础信息 描述 74HC138器件设计用于需要极短传播延迟时间的高性能存储器解码或数据路由应用&#xff1b;在高性能存储系统中&#xff0c;可使用…