yasea浅析

本文链接:https://www.cnblogs.com/obarong/p/12858893.html

1 简介

Yasea是一个Android流媒体客户端。 它将来自摄像机和麦克风的YUV和PCM数据编码为H.264 / AAC,封装在FLV中并通过RTMP传输。

这篇文章的目的是初步了解yasea的流程,为后续优化做铺垫。

分支:

  • master:主分支,被我修改后,支持min SDK 18.
  • non-gpuimage:
  • android-16: Android API 16+.
  • aac-hev2: for Youtube live broadcast that is not compatible with conventional flash media players.

特性:

2 工程结构

  • app模块:
    • MainActivity:主页
    • AndroidManifest.xml:声明权限
  • library模块:
    • cpp:用Android.mk方式编译C/C++
    • libenc:jni中间层代码
    • libx264:用于H264软编码
    • libyuv:包括YUV缩放和转换功能。
    • com.coremedia.iso:封装MP4
    • com.github.faucamp.simplertmp:SimpleRtmp是用于实现RTMP客户端的简单Java库。
    • com.googlecode.mp4parser:封装MP4
    • com.seu.magicfilter:滤镜
    • net.ossrs.yasea:UI层和业务逻辑层

3 总流程

打开camera,在预览的view加滤镜。在SrsPublisher预览回调,在libenc和libyuv进行YUV转换,用x264软编码或MediaCodec硬编码 ,在SrsMp4Muxer保存MP4,SrsFlvMuxer发送RTMP。

4 功能

预览

  • SrsCameraView:主页,自定义view,初始化camera分辨率、旋转,加滤镜,获取视频原始数据,是RGBA格式。

转换YUV和编码

  • SrsEncoder:声明native方法,转换和编码。我的手机支持COLOR_FormatYUV420SemiPlanar编码,所以要把yuv转成NV12。
  • YUV转换:
    • onSurfaceCreated - onSurfaceChanged - onDrawFrame - mGLIntBufferCache.add, 缓存
    • mGLIntBufferCache.poll - onGetRgbaFrame - hwRgbaFrame - libenc_RGBAToNV12 - convert_to_i420 - ConvertToI420 - I420Scale - ConvertFromI420
  • 视频编码:onProcessedYuvFrame - onEncodedAnnexbFrame - vencoder.queueInputBuffer - vencoder.dequeueOutputBuffer - onEncodedAnnexbFrame
  • 音频编码:onGetPcmFrame - aencoder.queueInputBuffer - aencoder.dequeueOutputBuffer - onEncodedAacFrame

保存MP4

  • SrsMp4Muxer:封装MP4?
  • 视频流:onEncodedAnnexbFrame - writeSampleData - writeVideoSample - writeFrameByte - frameCache.add,record - frameCache.poll - writeSampleData,finishMovie
  • 音频流:onEncodedAacFrame - writeSampleData - writeAudioSample - 同上

发送RTMP

  • SrsPublisher:各种业务逻辑、开关。
  • SrsFlvMuxer:to POST the h.264/avc annexb frame over RTMP.
  • SrsFlvFrame:the muxed flv frame.
  • SrsAllocator.Allocation:分配字节
  • SrsRawH264Stream:the raw h.264 stream, in annexb.
  • SrsFlv:remux the annexb to flv tags.
  • 连接RTMP发送视频流:startPublish - mFlvMuxer.start- connect - publisher.publish - mFlvTagCache.poll - sendFlvTag - publisher.publishVideoData
  • 发送前缓存视频流:onEncodedAnnexbFrame - writeSampleData - writeVideoSample - writeH264SpsPps - writeRtmpPacket - flvTagCacheAdd - mFlvTagCache.add
  • 发送前缓存音频流:onEncodedAacFrame - writeSampleData - writeAudioSample - writeRtmpPacket - 同上

FAQ

  • 为什么要封装flv?
  • 为什么要RGBA转I420再转NV12,而不是直接RGBA转NV12?
  • 可以不加滤镜吗?解:看non-gpuimage分支。
  • ……

参考

begeekmyfriend/yasea: RTMP live streaming client for Android
https://github.com/begeekmyfriend/yasea

SEA(适用于Android的流编码器)通过HTTP-FLV将实时流发布到SRS。

ossrs/srs-sea at feature/deprecated
https://github.com/ossrs/srs-sea/tree/feature/deprecated

yasea 基于 MediaCodec 硬编码 · Issue #31 · begeekmyfriend/yasea
https://github.com/begeekmyfriend/yasea/issues/31

请问摄像头返回的最初的NV21格式的数据在哪里 · Issue #752 · begeekmyfriend/yasea
https://github.com/begeekmyfriend/yasea/issues/752

posted @ 2020-05-09 17:16  奥巴荣  阅读(2998)  评论(0编辑  收藏  举报