大疆视频回传流媒体开发

大疆视频回传流媒体开发

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

首先。大疆的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
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值