大疆视频回传流媒体开发

大疆视频回传流媒体开发

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

首先。大疆的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;
            case OSMO:
                if (DataCameraGetPushStateInfo.getInstance().getVerstion() >= 4) {
                    iframeId = -1;
                } else {
                    iframeId = R.raw.iframe_1280x720_ins;
                }
                break;
            case OSMO_PLUS:
                if (width == 960) {
                    iframeId = R.raw.iframe_960x720_osmo_gop;
                } else if (width==1280) {
                    //for record mode, 1280x720, GDR
                    //DJILog.i(TAG, "Selected Iframe=iframe_1280x720_3s");
                    //                    iframeId = R.raw.iframe_1280x720_3s;
                    iframeId = R.raw.iframe_1280x720_osmo_gop;
                } else if (width == 640){
                    iframeId = R.raw.iframe_640x368_osmo_gop;
                } else {
                    iframeId = R.raw.iframe_1280x720_3s;
                }
                break;
            case OSMO_PRO:
            case OSMO_RAW:
                iframeId = R.raw.iframe_1280x720_ins;
                break;
            case MAVIC_PRO: //product small drone
            case MAVIC_2:
                if (((Aircraft) DJISDKManager.getInstance().getProduct()).getMobileRemoteController() != null) {
                    iframeId = R.raw.iframe_1280x720_wm220;
                } else{
                    iframeId = -1;
                }
                break;
            case Spark:
                switch (width) {
                    case 1280:  // 与P4相同
                        iframeId = R.raw.iframe_1280x720_p4;
                        break;
                    case 1024:
                        iframeId = R.raw.iframe_1024x768_wm100;
                        break;
                    default:
                        iframeId = R.raw.iframe_1280x720_p4;
                        break;
                }
                break;
            case MAVIC_AIR:
                switch (height) {
                    case 960:
                        iframeId = R.raw.iframe_1280x960_wm230;
                        break;
                    case 720:
                        iframeId = R.raw.iframe_1280x720_wm230;
                        break;
                    default:
                        iframeId = R.raw.iframe_1280x720_wm230;
                        break;
                }
                break;
            case PHANTOM_4:
                iframeId = R.raw.iframe_1280x720_p4;
                break;
            case PHANTOM_4_PRO: // p4p
            case PHANTOM_4_ADVANCED: // p4p
                switch (width) {
                    case 1280:
                        iframeId = R.raw.iframe_p4p_720_16x9;
                        break;
                    case 960:
                        iframeId = R.raw.iframe_p4p_720_4x3;
                        break;
                    case 1088:
                        iframeId = R.raw.iframe_p4p_720_3x2;
                        break;
                    case 1344:
                        iframeId = R.raw.iframe_p4p_1344x720;
                        break;
                    case 1440:
                        iframeId = R.raw.iframe_1440x1088_wm620;
                        break;
                    case 1920:
                        switch (height) {
                            case 1024:
                                iframeId = R.raw.iframe_1920x1024_wm620;
                                break;
                            case 800:
                                iframeId = R.raw.iframe_1920x800_wm620;
                                break;
                            default:
                                iframeId = R.raw.iframe_1920x1088_wm620;
                                break;
                        }
                        break;
                    default:
                        iframeId = R.raw.iframe_p4p_720_16x9;
                        break;
                }
                break;
            case MATRICE_600:
            case MATRICE_600_PRO: {
                DataCameraGetPushStateInfo.CameraType cameraType = DataCameraGetPushStateInfo.getInstance().getCameraType();
                if (width == 720 && height == 480) {
                    iframeId = R.raw.iframe_720x480_m600;
                } else if (width == 720 && height == 576) {
                    iframeId = R.raw.iframe_720x576_m600;
                } else {
                    if (width == 1280 && height == 720) {
                        if (cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeGD600) {
                            iframeId = R.raw.iframe_gd600_1280x720;
                        } else if (cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeCV600) {
                            iframeId = R.raw.iframe_1280x720_osmo_gop;
                        } else if (cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeFC350) {
                            iframeId = R.raw.iframe_1280x720_ins;
                        } else {
                            iframeId = R.raw.iframe_1280x720_m600;
                        }
                    } else if (width == 1920 && (height == 1080 || height == 1088)) {
                        iframeId = R.raw.iframe_1920x1080_m600;
                    } else if (width == 1080 && height == 720) {
                        iframeId = R.raw.iframe_1080x720_gd600;
                    } else if (width == 960 && height == 720) {
                        iframeId = R.raw.iframe_960x720_3s;
                    } else {
                        iframeId = -1;
                    }
                }
                break;
            }
            case MATRICE_100: {
                DataCameraGetPushStateInfo.CameraType cameraType = DataCameraGetPushStateInfo.getInstance().getCameraType();
                if (cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeGD600) {

                    if (width == 1280 && height == 720){
                        iframeId = R.raw.iframe_gd600_1280x720;
                    }else {
                        iframeId = R.raw.iframe_1080x720_gd600;
                    }

                } else {
                    iframeId = R.raw.iframe_1280x720_ins;
                }
                break;
            }
            case MATRICE_200:
            case MATRICE_210:
            case MATRICE_210_RTK:
            case INSPIRE_2: //inspire2
                DataCameraGetPushStateInfo.CameraType cameraType = DataCameraGetPushStateInfo.getInstance().getCameraType(0);
                if(cameraType == DataCameraGetPushStateInfo.CameraType.DJICameraTypeGD600) {
                    iframeId = R.raw.iframe_1080x720_gd600;
                } else {
                    if (width == 640 && height == 368) {
                        DJILog.i(TAG, "Selected Iframe=iframe_640x368_wm620");
                        iframeId = R.raw.iframe_640x368_wm620;
                    }
                    if (width == 608 && height == 448) {
                        DJILog.i(TAG, "Selected Iframe=iframe_608x448_wm620");
                        iframeId = R.raw.iframe_608x448_wm620;
                    } else if (width == 720 && height == 480) {
                        DJILog.i(TAG, "Selected Iframe=iframe_720x480_wm620");
                        iframeId = R.raw.iframe_720x480_wm620;
                    } else if (width == 1280 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1280x720_wm620");
                        iframeId = R.raw.iframe_1280x720_wm620;
                    } else if (width == 1080 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1080x720_wm620");
                        iframeId = R.raw.iframe_1080x720_wm620;
                    } else if (width == 1088 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1088x720_wm620");
                        iframeId = R.raw.iframe_1088x720_wm620;
                    } else if (width == 960 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_960x720_wm620");
                        iframeId = R.raw.iframe_960x720_wm620;
                    } else if (width == 1360 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1360x720_wm620");
                        iframeId = R.raw.iframe_1360x720_wm620;
                    } else if (width == 1344 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1344x720_wm620");
                        iframeId = R.raw.iframe_1344x720_wm620;
                    } else if (width == 1440 && height == 1088) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1440x1088_wm620");
                        iframeId = R.raw.iframe_1440x1088_wm620;
                    } else if (width == 1632 && height == 1080){
                        DJILog.i(TAG, "Selected Iframe=iframe_1632x1080_wm620");
                        iframeId = R.raw.iframe_1632x1080_wm620;
                    } else if (width == 1760 && height == 720) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1760x720_wm620");
                        iframeId = R.raw.iframe_1760x720_wm620;
                    } else if (width == 1920 && height == 800) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1920x800_wm620");
                        iframeId = R.raw.iframe_1920x800_wm620;
                    } else if (width == 1920 && height == 1024) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1920x1024_wm620");
                        iframeId = R.raw.iframe_1920x1024_wm620;
                    } else if (width == 1920 && height == 1088) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1920x1080_wm620");
                        iframeId = R.raw.iframe_1920x1088_wm620;
                    } else if (width == 1920 && height == 1440) {
                        DJILog.i(TAG, "Selected Iframe=iframe_1920x1440_wm620");
                        iframeId = R.raw.iframe_1920x1440_wm620;
                    }
                }
                break;
            case PHANTOM_4_PRO_V2:
            case PHANTOM_4_RTK: {
                iframeId = -1;
            }
                break;
            default: //for P3P, Inspire1, etc/
                iframeId = R.raw.iframe_1280x720_ins;
                break;
        }
        return iframeId;
    }

请自行查看。

更新于 2019-6-27

你可能感兴趣的:(androidStudio小白)