大疆视频回传流媒体开发

本文介绍了作者在外聘项目中进行大疆视频回传流媒体开发的挑战和经验。大疆SDK的视频Buffer处理方式有所改变,需要处理开头的数据、去除冗余,并结合I帧进行解码。开发者需注意SDK更新带来的变化,以及获取I帧的新方法。
摘要由CSDN通过智能技术生成

大疆视频回传流媒体开发

最近,去了广东省电力设计院做实习生。外聘的那个项目经理让我一个实习生做流媒体这一块。。我也是醉。没办法,硬着头皮上呗。还好找到了一个开源的流媒体解决方案。改改他们的代码。就能用了。但是大疆回传的视频流还是很坑爹的。

首先。大疆的SDK使用要用USB连着他那个手柄。我了个大艹。连着这个手柄我就不能逐步调试了啊。简直设计脑残。嗯。吐槽完了。

1.现在大疆SDK经过更新。这个回传的videoBuffer的开头就有数据。数据不会再分隔在两个videoBuffer中了。
2.数据没有 0x00 0x00 0x00 0x01 0x09的开头了。一上来就是数据。
3.数据后边有大量冗余。全是0x00。只用读出他给的大小就好。就是那个Size参数
4.读出无冗余的数据后,把他官网说的I帧(raw文件夹下的),拼在这些数据前面,就完成了
5.之后你拿到这个数据,该推送到RTP就推送,该解码就解码。
6.不得不说大疆还是很坑爹的。你更新了数据格式也不说。又不能逐步调试。


嗯。时间过去了三年,DJI SDK也不知道更新了多少版。我也从一个Android实习改做后端,现在又改做架构。
刚刚查看了一下,现在获取I帧的方式与以前不同了,也许是DJI的机型增多,变焦的也出了,不能手动下载I帧文件了。

可以看他的Github

现在对于解码的描述在这个文件里:DJIVideoStreamDecoder.java

以下是对步骤说明的一些摘抄:

/**
 * This class is a helper class for hardware decoding. Please follow the following steps to use it:
 *
 * 1. Initialize and set the instance as a listener of NativeDataListener to receive the frame data.
 *
 * 2. Send the raw data from camera to ffmpeg for frame parsing.
 *
 * 3. Get the parsed frame data from ffmpeg parsing frame callback and cache the parsed framed data into the frameQueue.
 *
 * 4. Initialize the MediaCodec as a decoder and then check whether there is any i-frame in the MediaCodec. If not, get
 * the default i-frame from sdk resource and insert it at the head of frameQueue. Then dequeue the framed data from the
 * frameQueue and feed it(which is Byte buffer) into the MediaCodec.
 *
 * 5. Get the output byte buffer from MediaCodec, if a surface(Video Previewing View) is configured in the MediaCodec,
 * the output byte buffer is only need to be released. If not, the output yuv data should invoke the callback and pass
 * it out to external listener, it should also be released too.
 *
 * 6. Release the ffmpeg and the MediaCodec, stop the decoding thread.
 */

现在的I帧被内置在了SDK的raw文件里,刚刚给出的类里现在有个getIframeRawId函数,是直接从SDK里获取I帧的,使用一个一个的Switch-Case和If判别R.raw的ID,得到资源ID。

    /**
     * Get the resource ID of the IDR frame.
     * @param pModel Product model of connecting DJI product.
     * @param width Width of current video stream.
     * @return Resource ID of the IDR frame
     */
    public int getIframeRawId(Model pModel, int width) {
   
        int iframeId = R.raw.iframe_1280x720_ins;

        switch(pModel) {
   
            case PHANTOM_3_ADVANCED:
            case PHANTOM_3_STANDARD:
                if (width == 960) {
   
                    //for photo mode, 960x720, GDR
                    iframeId = R.raw.iframe_960x720_3s;
                } else if (width == 640){
   
                    iframeId = R.raw.iframe_640x368_osmo_gop;
                } else {
   
                    //for record mode, 1280x720, GDR
                    iframeId = R.raw.iframe_1280x720_3s;
                }
                break;
            case INSPIRE_1: {
   
                DataCameraGetPushStateInfo.CameraType cameraType = DataCameraGetPushStateInfo.getInstance().getCameraType();
                if (cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeCV600) {
    //ZENMUSE_Z3
                    if (width == 960) {
   
                        //for photo mode, 960x720, GDR
                        iframeId = R.raw.iframe_960x720_3s;
                    } else if (width == 640){
   
                        iframeId = R.raw.iframe_640x368_osmo_gop;
                    } else {
   
                        //for record mode, 1280x720, GDR
                        iframeId = R.raw.iframe_1280x720_3s;
                    }
                }
                break;
            }
            case Phantom_3_4K:
                switch(width) {
   
                    case 640:
                        //for P3-4K with resolution 640*480
                        iframeId = R.raw.iframe_640x480;
                        break;
                    case 848:
                        //for P3-4K with resolution 848*480
                        iframeId = R.raw.iframe_848x480;
                        break;
                    case 896:
                        iframeId = R.raw.iframe_896x480;
                        break;
                    case 960:
                        //DJILog.i(TAG, "Selected Iframe=iframe_960x720_3s");
                        //for photo mode, 960x720, GDR
                        iframeId = R.raw.iframe_960x720_3s;
                        break;
                    default:
                        iframeId = R.raw.iframe_1280x720_3s;
                        break;
                }
                break
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值