博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Kotlin/Native应用程序开发指南
阅读量:6684 次
发布时间:2019-06-25

本文共 2457 字,大约阅读时间需要 8 分钟。

在这篇博文中,我们将讨论Kotlin/Native应用程序的开发。在这里,我们使用音频/视频解码器和进行渲染,来开发个简易的视频播放器。希望此文可以成为能对Kotlin/Native开发者有价值的开发指南,同时该文也会解释使用该平台的预期机制。

\\

在本教程中,我们主要关注的是Kotlin/Native,我们只会粗略地介绍一下如何开发视频层。您可以参阅这篇名为的优秀教程,以了解如何用C语言实现它。如果您的兴趣点在于比较C语言的编码与Kotlin/Native编码的不同之处,我建议您从本教程开始。

\\

理论上,每一个视频播放器的工作都相当简单:读入带有交错的视频帧和音频帧的输入流,解码并显示视频帧,同时与音频流同步。通常,这一工作由多个线程完成,执行流解码、播放视频和音频。要准确的做到这些,需要线程同步和特定的实时保证,如果音频流没有被及时解码,播放声音听起来会很不稳定,如果视频帧没有及时显示,影像看起来会很不流畅。

\\

Kotlin/Native不鼓励您使用线程,也不提供在线程之间共享Kotlin对象的方法。然而,我们相信在Kotlin/Native中并发的软实时编程很容易实现,所以我们决定从一开始就以并发的方式来设计我们的播放器。来看看我们是怎么做到的吧。

\\

Kotlin/Native计算并发性是围绕构建的。Worker是比线程更高级的并发性概念,不像对象共享和同步,它允许对象传输,因此每一时刻只有一个workers可以访问特定对象。这意味着,访问对象数据时不需要同步,因为多个访问永远不能同时进行。workers可以接收执行请求,这些请求可以接受对象并根据需要执行任务,然后将结果返回给需要计算结果的人。这样的模型确保了许多典型的并发编程错误(例如对共享数据的不同步访问,或者由未排序的锁导致的死锁)不再出现。

\\

让我们看看,它是如何转化为视频播放器架构的。我们需要对某些容器格式进行解码,比如、或者 ,它对交叉音频和视频流进行多路分解、解码,然后将解压缩的音频提供给。解压后的视频帧应与声音播放同步。为了达到这个目标,worker概念的出现也便是理所当然的了。我们为生成一个worker,并在需要的时候向它请求和数据。在多核机器上,这意味着解码可以与播放并行进行。因此,解码器是一个来自UI线程和音频线程的数据生成器。

\\

无论何时我们需要获取下一个音频或视频数据块时,我们都依赖于全能的函数。它将调度大量的工作给特定的worker执行,以便提供输入参数和返回实例,这些可能被挂起,直到任务被目标worker执行完。Future对象可能被销毁,因此产生的对象将直接从worker线程返回到请求程序线程。

\\

Kotlin/Native运行时理论上讲是线性的,所以当运行多个线程时,需要在做其他操作之前调用函数,我们在音频线程回调中也是这样做的。为了简化音频播放,我们将音频帧重新采样到两个通道,并以。

\\

视频帧可以被解码成,当然它会有个默认值,同时它的位深度依赖于用户桌面默认设置。还请注意下Kotlin/Native特有的操作C指针的方法,即

\\
\private val resampledAudioFrame: AVFrame =\        disposable(create = ::av_frame_alloc, dispose = ::av_frame_unref).pointed\...\with (resampledAudioFrame) {\    channels = output.channels\    sample_rate = output.sampleRate\    format = output.sampleFormat\    channel_layout = output.channelLayout.signExtend()\}
\\

我们声明resampledAudioFrame作为由FFMPEG API调用avframealloc()和avframeunref()创建的C程序中的一次性资源。然后,我们将它所指向的值设置成它所期望的字段。需要注意的是,我们可以将FFMPEG(如)声明的定义作为Kotlin的常量。但是,由于它们没有类型信息,并且默认情况下是Int类型的,如果某个字段具有不同的类型(比如channellayout),那便需要调用适配器函数。这是编译器的内在特性,它会。

\\

在设置完解码器后,我们开始。这没有什么特别的,只是检索下一个帧,将它,并在屏幕上显示这个纹理。至此,视频帧便被渲染了。音频线程回调是由处理的,它从解码器中获取下一个采样缓冲区,并将其反馈给音频引擎。

\\

音频/视频同步是必须要保证的,它可以确保我们没有太多的未播放的音频帧。真正的多媒体播放器应该依赖于,我们只计算它,但永远不会使用。这里有一个有趣的地方

\\
\val ts = av_frame_get_best_effort_timestamp(audioFrame.ptr) * \  av_q2d(audioCodecContext.time_base.readValue())
\\

它展示了如何使用api接收C语言的结构体。它是在libavutil/rational.h中声明的

\\
\static inline double av_q2d(AVRational a){\    return a.num / (double) a.den;\}
\\

因此,要通过值传递它,我们首先需要在字段上使用readValue()。

\\

总结来说,多亏了FFMPEG库,我们才能用较少的代价便实现了一个支持多种输入格式的简易音频/视频播放器。这里我们还讨论了Kotlin/Native中基于C语言的互操作性相关的基础知识,以及更容易使用和维护的并发方法。 

\\

英文原文链接

\\

感谢对本文的审校。

转载地址:http://xsaao.baihongyu.com/

你可能感兴趣的文章
网页图表Highcharts实践教程之认识Highcharts
查看>>
LPC2103学习之GPIO
查看>>
管理岗是什么鬼?
查看>>
创建一个当前时间凌晨
查看>>
Python 学习笔记 - 多进程和进程池
查看>>
日志切割实例
查看>>
CentOS安装中文汉字输入法ibus
查看>>
【环境配置】DOSBox运行TT打字软件
查看>>
Android中处理Touch Icon的方案
查看>>
RHEL7.1配置本地yum源
查看>>
Mybatis Generator最完整配置详解
查看>>
Hash学习
查看>>
PHP按符号截取字符串的指定部分
查看>>
在Blender导出格式为STL
查看>>
我的友情链接
查看>>
酒有两不喝,财有两不发,忙有三不帮,亲有三不走!
查看>>
IPFS 服务的Python访问
查看>>
DllMain详解
查看>>
Class bytes found but defineClass()failed for error when deploying EAR
查看>>
IIS7.0安装的FTP建账号
查看>>