解码器

为什么需要“二次”解码器

浪尽此生 提交于 2019-12-01 16:05:38
参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!   上一篇随笔说了解决TCP粘包、半包的一次解码器都是继承的 ByteToMessageDecoder ,而 ByteToMessageDecoder 主要是将原始数据流(可能存在粘包、半包问题的数据流)转换为用户数据(是一个字节数组)。所以我们需要二次解码器(都是直接继承 MessageToMessageDecoder )将字节数组转换成Java对象。    有人会问能否将两次解码合二为一?这里是不建议的,首先没有分层感,不够清晰,其次就是耦合性太高,Java是最忌讳耦合性高的方案的。 常用的“二次”编解码方式有哪些?    Java序列化(占空间,其他语言不支持),Marshaling,XML(也是占用比较大),JSON(比XML占空间小,但是没有XML那么通用性),MessagePack(比JSON占用空间还小,却没有它可读性好),Protobuf,其他... 如此多的编解码方式该如何选择呢?首先考虑到的是编码后占用空间,因为编解码的作用很大情况下是为了存储和传输。其次是编解码的速度,再一个就是是否追求可读性,最后一个就是多语言支持,例如MessagePack。综上所述比较合适的有JSON,MessagePack和Protobuf

接口调用简单、多平台支持的RTSP-Server组件EasyRTSPServer如何修正多网卡多IP情况下解码器不能解码显示问题

浪子不回头ぞ 提交于 2019-12-01 10:06:31
EasyRTSPServer修正多网卡多IP情况下解码器不能解码显示问题 提出问题: 海康NVR接入正常,但接入海康解码器出不来图像。 分析问题: 海康解码器是以rtp over udp的方式进行取流,如果运行streamingServer的PC,网络设置为以下两种情况,则都可以正常上墙显示 : 本机仅设置一个IP,且和解码器在同一网段; 本机有两个IP, 如192.168.xx.xx 和 190.168.xx.xx,解码器网段为190.168.xx.xx; 当同一网卡设置了以下不同网段的IP,则会出现解码器不能解码上墙的问题,如: 192.168.100.8 192.168.5.8 190.168.100.1 190.168.12.8 经过分析,在setupDatagramSocket函数中,bind时填写的地址为0.0.0.0,而本机中有多个ip,猜想是因为在发送udp数据时,系统随机选用一个ip与解码器通信,导致解码器没有收到数据。 解决问题: 注: 必须将sps、pps、关键帧数据分开发送,否则海康解码器只能接收但不解码显示; 在setupDatagramSocket函数中增加参数 int clientSock, 用于获取当前解码器和streamingserver通信的ip, 将其绑定, 如下: int setupDatagramSocket

ijkplayer系列13:video_refresh_thread

限于喜欢 提交于 2019-11-30 04:26:12
ffp_video_thread 这个线程用来处理视频解码。解码的调用流程如下: 以上可以看出,解码流程主动分为以下三部分: 初始化解码器。 开启解码器,如果配置了硬解则会尝试去创建硬解码器,没有配置硬解或者尝试创建硬解码器失败则创建软解码器。 启动解码线程,可以发现硬解和软解最终进入的方法是不同的,后面我们会针对两者分别解析。 我们先来看下decoder_init(): static void decoder_init(Decoder *d, AVCodecContext *avctx, PacketQueue *queue, SDL_cond *empty_queue_cond) { memset(d, 0, sizeof(Decoder)); d->avctx = avctx; // 保存数据来源的队列引用,这个队列存储了从流中读取的未解码的帧数据 d->queue = queue; d->empty_queue_cond = empty_queue_cond; d->start_pts = AV_NOPTS_VALUE; // 将当前时间点(系统启动至今的毫秒数)作为第一帧解码的时间点 d->first_frame_decoded_time = SDL_GetTickHR(); d->first_frame_decoded = 0; SDL_ProfilerReset(&d

Netty源码分析 (九)----- 拆包器的奥秘

感情迁移 提交于 2019-11-30 02:47:03
Netty 的解码器有很多种,比如基于长度的,基于分割符的,私有协议的。但是,总体的思路都是一致的。 拆包思路:当数据满足了 解码条件时,将其拆开。放到数组。然后发送到业务 handler 处理。 半包思路: 当读取的数据不够时,先存起来,直到满足解码条件后,放进数组。送到业务 handler 处理。 拆包的原理 在没有netty的情况下,用户如果自己需要拆包,基本原理就是不断从TCP缓冲区中读取数据,每次读取完都需要判断是否是一个完整的数据包 1.如果当前读取的数据不足以拼接成一个完整的业务数据包,那就保留该数据,继续从tcp缓冲区中读取,直到得到一个完整的数据包 2.如果当前读到的数据加上已经读取的数据足够拼接成一个数据包,那就将已经读取的数据拼接上本次读取的数据,够成一个完整的业务数据包传递到业务逻辑,多余的数据仍然保留,以便和下次读到的数据尝试拼接 netty中拆包的基类 netty 中的拆包也是如上这个原理,在每个SocketChannel中会一个 pipeline ,pipeline 内部会加入解码器,解码器都继承基类 ByteToMessageDecoder,其 内部会有一个累加器,每次从当前SocketChannel读取到数据都会不断累加,然后尝试对累加到的数据进行拆包,拆成一个完整的业务数据包,下面我们先详细分析下这个类 看名字的意思是:将字节转换成消息的解码器

QMediaPlayer问题

自闭症网瘾萝莉.ら 提交于 2019-11-29 10:18:28
QT 的播放器并没有解码器存在,所以需要自己去下载,例如 LAVFilters 解码器 https://github.com/Nevcairiel/LAVFilters/releases 下载解码器的时候注意位数,解码器位数必须和构建的项目位数对应。 当你的工程是32位的时候,如果下载了64位的会一直提示 DirectShowPlayerService::doRender: Unresolved error code 0x80040266 MinGW 32Bit 下载32Bit解码器 MSVC 64Bit 下载64Bit解码器 来源: https://blog.csdn.net/qq_17813937/article/details/100780745

FFmpeg浅读之AVPacket

穿精又带淫゛_ 提交于 2019-11-28 22:41:25
一直想写点分析FFmpeg的文章,一来让自己回头总结下知识,二是分享分享自己的经验。音视频在我才工作的时候是个很冷门的技术,那个时候流行java开发,智能手机的解码能力还挺堪忧更别说编码了。好在音视频有一个最棒的开源项目FFmpeg。 FFmpeg项目基本是目前所有音视频项目的基石,但是FFmpeg有一个问题就是太庞大。一开始接触音视频的同学可能比较蒙圈,一上来就看这么大的项目都不知道从何入手。不过没关系相信看完我的FFmpeg解析系列应该对这个库有一定的认识。 基础数据 音视频的处理基本围绕着两种数据 原始的数据 原始数据可以看作是图像或者音频原始采集数据,这些是未经过编码的。如我们平时开发时麦克风采集的PCM数据,亦或者是摄像头采集的YUV数据。 编码的数据 编码数据顾名思义就是编码过的数据,原始数据通过一定的运算就变成了编码的数据,我们常说的AAC/MP3或者H264都是编码数据 在FFmpeg里也是围绕着这两个基础数据来进行操作,FFmpeg使用AVPacket来承载编码的数据,用AVFrame来承载原始数据.所以这里就很有必要先说说这两个基础数据在FFmpeg里的实现。 AVPacket AVPacket 定义在avcodec.h里面我们先看看他的定义 typedef struct AVPacket{ AVBufferRef *buf; int64_t pts;

Java 8中的Base64编码和解码

霸气de小男生 提交于 2019-11-28 22:21:32
转自: https://juejin.im/post/5c99b2976fb9a070e76376cc Java 8会因为将lambdas,流,新的日期/时间模型和Nashorn JavaScript引擎引入Java而被记住。有些人还会记得Java 8,因为它引入了各种小但有用的功能,例如Base64 API。什么是Base64以及如何使用此API?这篇文章回答了这些问题。 什么是Base64? Base64 是一种二进制到文本编码方案,通过将二进制数据转换为基数-64表示,以可打印的 ASCII 字符串格式表示二进制数据。每个Base64数字恰好代表6位二进制数据。 Base64请求评论文件 在 RFC 1421 中首次描述了Base64(但没有命名) :Internet电子邮件的隐私增强:第一部分:消息加密和认证过程 。后来,它在 RFC 2045中 正式呈现为Base64 :多用途Internet邮件扩展(MIME)第一部分:Internet消息体的格式 ,随后在 RFC 4648:Base16,Base32和Base64数据编码中 重新访问。 Base64用于防止数据在传输过程中通过信息系统(例如电子邮件)进行修改,这些信息系统可能不是8-bit clean(它们可能是8位值)。例如,您将图像附加到电子邮件消息,并希望图像到达另一端而不会出现乱码

123

大城市里の小女人 提交于 2019-11-28 22:15:25
主要语义分割网络调研 介绍 图像的语义分割是将输入图像中的每个像素分配一个语义类别,以得到像素化的密集分类。虽然自 2007 年以来,语义分割/场景解析一直是计算机视觉社区的一部分,但与计算机视觉中的其他领域很相似,自 2014 年 Long等人 首次使用全卷积神经网络对自然图像进行端到端分割,语义分割才产生了大的突破。 网络架构 一般的语义分割架构可以被认为是一个 编码器-解码器 网络。 编码器 通常是一个预训练的分类网络,像 VGG、ResNet,然后是一个 解码器 网络。这些架构不同的地方主要在于 解码器 网络。 解码器 的任务是将 编码器 学习到的可判别特征(较低分辨率)从语义上投影到像素空间(较高分辨率),以获得密集分类。 不同于分类任务中网络的最终结果(对图像分类的概率)是唯一重要的事,语义分割不仅需要在像素级有判别能力,还需要有能将编码器在不同阶段学到的可判别特征投影到像素空间的机制。不同的架构采用不同的机制(跳跃连接、金字塔池化等)作为解码机制的一部分。 Fully Convolution Networks (FCNs) 全卷积网络 Fully Convolutional Networks for Semantic Segmentation(2015) 作者将当前分类网络(AlexNet, VGG net 和 GoogLeNet)修改为全卷积网络

【音视频】FFmpeg打开视频 | 保存图片

你说的曾经没有我的故事 提交于 2019-11-28 20:50:23
1、初始化FFmpeg av_register_all(); //初始化FFMPEG 调用了这个才能正常使用编码器和解码器   但是这个函数如今已经没什么用了,它的就是把你定义和系统初始化的编码器和解码器连接起来而已,然后就没有了。   现在解码器和编码器的初始化都是通过定义全局变量来初始化的。与原来相比,唯一的改变就是使用数组替换链表完成解码器和编码器的初始化。 ## 参考文章: https://www.jianshu.com/p/ebb219ec1c0f 2、分配一个AVFormatContext,FFMPEG所有的操作都要通过这个AVFormatContext数据结构来进行 AVFormatContext *pFormatCtx = avformat_alloc_context();   AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。   此结构包含了一个视频流的格式内容:AVInputFormat(or AVOutputFormat同一时间AVFormatContext内只能存在其中一个),和AVStream、AVPacket这几个重要的数据结构以及一些其他的相关信息,比如title,author,copyright等。还有一些可能在编解码中会用到的信息,诸如:duration, file_size, bit_rate等。 3

netty的解码器与粘包和拆包

可紊 提交于 2019-11-27 23:42:08
tcp是一个“流”的协议,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。 假设客户端分别发送数据包D1和D2给服务端,由于服务端一次性读取到的字节数是不确定的,所以可能存在以下4种情况。 1.服务端分2次读取到了两个独立的包,分别是D1,D2,没有粘包和拆包; 2.服务端一次性接收了两个包,D1和D2粘在一起了,被成为TCP粘包; 3.服务端分2次读取到了两个数据包,第一次读取到了完整的D1和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为拆包; 4.服务端分2次读取到了两个数据包,第一次读取到了部分D1,第二次读取D1剩余的部分和完整的D2包; 5.如果此时服务端TCP接收滑动窗非常小,而数据包D1和D2都很大,很有可能发送第五种可能,即服务端多次才能把D1和D2接收完全,期间多次发生拆包情况。 由于底层的TCP无法理解上层的业务逻辑,所以在底层是无法确保数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,归纳如下: 1.消息定长,例如每个报文的大小为固定长度200字节,如果不够,空位补空格; 2.在包尾增加回车换行符进行分割; 3.将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体长度)的字段