شاشة كاميرا HAR

تفرض الجهات التنظيمية الحكومية عدة متطلبات لضمان توفير الرؤية الخلفية غير المباشرة معلومات كافية لمناورة المركبة بطريقة دقيقة وفي الوقت المناسب. ويؤثر ذلك في وعي السائق بالمحيط.

بالنسبة إلى أنظمة الرؤية الخلفية المستندة إلى "نظام مراقبة الكاميرا" (CMS)، تطلب "الإدارة الوطنية لسلامة المرور على الطرق السريعة" (NHTSA) استيفاء المتطلبات التالية (الفقرة S6.6.2.3 المُشار إليها من UNECE46):

  • S5.5.3 وقت الاستجابة : تظهر الصورة الخلفية التي تستوفي متطلبات الفقرتَين S5.5.1 (مجال الرؤية) وS5.5.2 (الحجم)، عند اختبارها وفقًا للفقرة S14.2، في غضون ثانيتَين من بدء حدث الرجوع إلى الخلف.

  • S5.5.4 وقت البقاء : لا تظهر الصورة الخلفية التي تستوفي متطلبات الفقرتَين S5.5.1 وS5.5.2 بعد انتهاء حدث الرجوع إلى الخلف.

  • S5.5.5 إيقاف التفعيل : تظل الصورة الخلفية التي تستوفي متطلبات الفقرتَين S5.5.1 وS5.5.2 مرئية أثناء حدث الرجوع إلى الخلف إلى أن يعدّل السائق طريقة العرض أو ينتقل محدّد اتجاه المركبة من وضع الرجوع إلى الخلف.

  • S6.6.2.3.3.5 القطع الأثرية : يجب أن يشير دليل المشغّل إلى القطع الأثرية المحتمَلة وتأثيراتها في الحجب الجزئي لمجال الرؤية والكائنات، ما قد يتطلب من السائق أن يكون متيقظًا ومنتبهًا بشكل خاص.

  • S6.2.2.3.4.1 عدد اللقطات في الثانية : تظهر حركات الكائنات أمام الكاميرا بسلاسة وانسيابية. يبلغ الحد الأدنى لعدد اللقطات في الثانية في النظام 30 لقطة في الثانية على الأقل (ما يعادل 30 هرتز). في ظروف الإضاءة المنخفضة أو أثناء المناورة بسرعة منخفضة، يبلغ الحد الأدنى لعدد اللقطات في الثانية في النظام 15 لقطة في الثانية على الأقل.

  • S6.2.2.3.4.2 وقت تكوين الصورة : يقلّ وقت تكوين الصورة على الشاشة عن 55 ملي ثانية عند درجة حرارة 22 درجة مئوية ± 5 درجات مئوية.

  • S6.2.2.3.4.3 وقت الاستجابة في النظام : يتميّز نظام مراقبة الكاميرا (CMS) بوقت استجابة قصير بما يكفي لعرض المشهد في الوقت نفسه تقريبًا. ويقلّ وقت الاستجابة عن 200 ملي ثانية عند درجة حرارة 22 درجة مئوية ± 5 درجات مئوية.

لقد طرحنا "نظام العرض الموسّع" (EVS) في نظام التشغيل Android Automotive OS (AAOS) للامتثال لهذه المتطلبات على نظام التشغيل AAOS الأساسي. لقد طرحنا خدمة مماثلة لـ المحاكاة الظاهرية على أجهزة AAOS باستخدام أداة العرض عالية التوفّر (HAR)، ما يوضّح أيضًا الامتثال لهذه المتطلبات.

سلسلة معاينة الكاميرا

تتألف سلسلة معاينة الكاميرا من هذه المراحل الخمس:

مراحل مسار معاينة الكاميرا

الشكل 1 : مراحل سلسلة معاينة الكاميرا

يشير مكوّن خدمة الكاميرا إلى منصة "خدمة الكاميرا" وطبقة التجريد التي تتيح للتطبيقات الوصول إلى الكاميرات المتاحة واستخدامها. تعرض وظيفة "خدمة الشاشة" بيانات الصور للمستخدمين. ينفّذ التطبيق رحلات المستخدم المستهدَفة باستخدام "خدمة الكاميرا" و"خدمة الشاشة".

رحلة المستخدم الرئيسية للرؤية الخلفية هي:

  1. يضع السائق محدّد الاتجاه (الترس) في وضع الرجوع إلى الخلف لتفعيل حدث الرجوع إلى الخلف.

  2. يبث النظام حدث الرجوع إلى الخلف. يتلقّى التطبيق البث ويضبط مكوّن إدخال الكاميرا (خدمة الكاميرا) وأداة العرض (خدمة الشاشة).

  3. يضبط مكوّن إدخال الكاميرا منصة "خدمة الكاميرا" ويعرض مقبض الخدمة على التطبيق.

  4. تضبط أداة العرض نافذة العرض لإدخال الكاميرا من الخطوة 4.

  5. يطلب التطبيق من مكوّن إدخال الكاميرا بدء إرسال مخازن الإطارات والأحداث.

  6. يضع التطبيق مخازن الإطارات التي تم تسليمها في قائمة الانتظار من خلال معاودة الاتصال (غير متزامن). يملك مكوّن إدخال الكاميرا مخازن الإطارات، لذا لا يمكن للتطبيق تعديلها.

  7. يزيل التطبيق مخزن إطارات من قائمة الانتظار (إذا لم تكن قائمة الانتظار فارغة) ويُنشئ طريقة عرض المستخدم. يمكن للمستخدمين إنشاء نسخة لتعديل المحتوى.

  8. يرسل التطبيق مخزنًا إلى أداة العرض.

  9. ترسم أداة العرض محتويات مخزن تم استلامه على الشاشة.

  10. إذا كان حدث الرجوع إلى الخلف لا يزال قيد المعالجة، انتقِل إلى الخطوة 7. عند اكتمال حدث الرجوع إلى الخلف، يطلب التطبيق من مكوّن إدخال الكاميرا إيقاف إرسال مخازن الإطارات والأحداث بعد إخفاء طريقة العرض عن المستخدم.

  11. يمكن للتطبيق اختياريًا إغلاق الكاميرا وإيقاف أداة العرض.

يوضّح الشكل 1 التدفق. تستخدم هذه الصورة عناصر من QNX Camera Library API لاستخدام منصة "خدمة الكاميرا".

رحلة المستخدم الأساسية لملف HAR

الشكل 2 : رحلة المستخدم الرئيسية لأداة العرض عالية التوفّر (HAR)

يعرِض مكوّن إدخال الكاميرا ثلاث واجهات:

  • CameraManager: تعرِض طرقًا لإدارة أجهزة الكاميرا، على سبيل المثال، يستخدم التطبيق هذه الواجهة لفتح (حجز) جهاز كاميرا مستهدَف.

  • CameraDevice : تعرِض طرقًا للتحكّم في جهاز الكاميرا، على سبيل المثال، بدء مصدر بيانات أو إيقافه.

  • CameraStreamListener : تعرِض طريقة واحدة لتلقّي أحداث مختلفة من كاميرا مستهدَفة.

تصميم

يوضّح هذا القسم تصميم النظام بالتفصيل.

تجربة المستخدم

يمكن للسائق معاينة الكاميرا الخلفية على شاشة لوحة العدادات عند وضع الترس في وضع الرجوع إلى الخلف. تتوقف الشاشة عن معاينة الكاميرا عندما ينقل السائق الترس من وضع الرجوع إلى الخلف.

يمكن تفعيل رحلات مستخدم إضافية. على سبيل المثال، يمكن للسائق معاينة المنطقة غير المرئية في المرايا عند تفعيل إشارة الانعطاف.

بدء معاينة الكاميرا

عند استخدام الكاميرات، يَعرض التطبيق الكاميرات المتاحة ويقيّمها للعثور على أفضل كاميرا للغرض المقصود. على سبيل المثال، للرؤية الخلفية، يبحث التطبيق عن الكاميرا التي تعرض الجانب الخلفي من المركبة من قائمة الكاميرات المتاحة.

يقيّم التطبيق ذلك من خلال فحص خصائص كل كاميرا، على سبيل المثال، الموقع واتجاه العدسة وعدد اللقطات في الثانية ودقة العرض وتنسيق الإخراج. إذا كانت عدة كاميرات تتضمّن الخصائص المطلوبة نفسها، قد يفحص التطبيق خصائص إضافية، مثل مجال الرؤية والمسافة البؤرية.

تعرض هذه الصورة تسلسلاً لبدء معاينة الكاميرا باستخدام إعدادات كاميرا ثابتة:

بدء معاينة الكاميرا باستخدام إعدادات ثابتة للكاميرا

الشكل 3 : بدء معاينة الكاميرا باستخدام إعدادات كاميرا ثابتة

إيقاف معاينة الكاميرا

يتوقف التطبيق عن توفير الرؤية الخلفية عند انتهاء حدث الرجوع إلى الخلف. لتجنُّب عرض شاشة فارغة أو صورة ثابتة، يخفي التطبيق طريقة العرض عن المستخدم أولاً ثم يطلب من مكوّن إدخال الكاميرا إيقاف إرسال الأحداث.

تعرض هذه الصورة تسلسلاً لإيقاف مصدر بيانات من جهاز كاميرا مستهدَف:

إيقاف بث البيانات من جهاز الكاميرا المستهدَف

الشكل 4 : إيقاف مصدر بيانات من جهاز كاميرا مستهدَف

الأخطاء

يمكن أن يتوقف جهاز الكاميرا بشكل غير متوقّع عن إرسال مخزن إطارات جديد. لرصد هذه الحالات، قد ينفّذ مكوّن إدخال الكاميرا مؤقتًا تنتهي صلاحيته عند وصول إطار جديد ويرسل إشعارًا عند انتهاء صلاحية هذا المؤقت.

عندما يتلقّى التطبيق إشعارًا، يُعلم المستخدم بأنّ معاينة الكاميرا لم تعُد مباشرة ويحاول استعادة معاينة الكاميرا من خلال إغلاق جهاز الكاميرا وفتحه مرة أخرى. يوضّح الشكل 5 كيفية تعامل التطبيق مع انتهاء المهلة:

التعامل مع انتهاء المهلة

الشكل 5 : التعامل مع انتهاء المهلة (مصدر البيانات المعلق)

يمكن أن يُبلغ مكوّن إدخال الكاميرا عن حوادث أخرى غير مصدر البيانات المعلق ويضمّن المزيد من التفاصيل في المخازن. يمكن لمصنّعي المعدات الأصلية استخدام بيانات الأحداث الوصفية هذه للتعامل مع الحوادث على منصتهم.

الأنشطة

تستخدم التطبيقات التي تعمل على المضيف واجهة برمجة التطبيقات وتدير شاشة لوحة العدادات من خلال أداة العرض عالية التوفّر (HAR) (المربّعات الزرقاء في الرسم البياني أدناه).

يوضّح الشكل 5 رسمًا بيانيًا للنظام:

مخطط النظام

الشكل 6 : رسم بياني للنظام

الخدمات

من المفترض أن يتم تشغيل طلبات البيانات من واجهة برمجة التطبيقات في سياق عملية الاستدعاء.

واجهات برمجة التطبيقات

لا يُقصد بواجهة برمجة التطبيقات الجديدة إلا التطبيقات التي تدير معاينات الكاميرا على شاشة لوحة العدادات من خلال أداة العرض عالية التوفّر (HAR). تتوفر واجهة برمجة التطبيقات من خلال الـ طبقة تجريد المنصة وترتبط ديناميكيًا.

تعرِض واجهة CameraInputBlock طرقًا لضبط وظيفة الكاميرا والحصول على مدير مكوّن الإدخال. يستخدم التطبيق مثيلاً تم عرضه من CameraManager لإدارة أجهزة الكاميرا.

// This class represents a camera input block for the application that manages the
// instrument cluster display with Harry.
public class CameraInputBlock : public InputBlock {
    public:
        // Clean up the resources.
        virtual ~CameraInputBlock();

        // A method inherited from InputBlock class. This method initializes
        // CameraInputBlock instance; e.g. checking the platform camera service
        // is live.
        //
        // @return CAMERA_EPERM if the platform camera service is not
        //                      available.
        //         CAMERA_OK otherwise.
        virtual CameraError init() override;

        // A method inherited from InputBlock class. This method release all
        // resources held by this CameraInputBlock instance.
        virtual void release() override;

        // This method returns a CameraManager instance. The caller uses
        // this instance to manage camera devices.
        //
        // @param out If this method is successful, this points to a valid
        //            CameraManager instance.
        // @return CAMERA_EACCESS when we fail to create CameraManager instance
        //         to return.
        //         CAMERA_OK otherwise.
        virtual CameraError getCameraManager(
            std::shared_ptr<CameraManager>* out) = 0;

    private:
        // Handle to manage camera devices.
        std::shared_ptr<CameraManager> mMgr;

        // Handle to manage camera devices that have been opened by clients.
        std::set<CameraDevice> mCameras;
};

يعرِض صف CameraManager طرقًا لفتح الكاميرات (أو امتلاكها) وإيقافها عندما ينتهي التطبيق من استخدام هذه الكاميرا. يمكن للتطبيق فتح أكثر من كاميرا واحدة واستخدام مصادرها لإنشاء مجال رؤية أوسع أو تجربة عرض متعددة.

// This pure virtual class declares methods to manage camera devices.
public class CameraManager {
    public:
        // This method returns a list of CameraDescriptor objects representing
        // available cameras.
        //
        // @param out A list of CameraDescriptor instances. This list may be
        //            empty if the platform camera service does not list any
        //            camera.
        // @return CAMERA_EACCESS if we failed to build a camera list.
        //         CAMERA_OK otherwise.
        virtual CameraError getCameraList(
            std::vector<CameraDescriptor>* out) = 0;

        // Open a camera device associated with a given string identifier.
        //
        // @param ID A string identifier of a camera device to request.
        // @param out A pointer to CameraDevice shared pointer object. This
        //            is null when we fail to open a target device.
        // @return CAMERA_ENODEV if no camera is associated with a given id.
        //         CAMERA_EACCESS if it fails to open a target device.
        //         CAMERA_OK otherwise.
        virtual CameraError open(
            std::string ID, std::shared_ptr<CameraDevice>* out) = 0;

        // Close a camera device associated with a given string identifier.
        // This method is assumed to be always successful.
        //
        // @param id A string identifier of a camera device to close.
        virtual void close(std::string id) = 0;
};

إذا لم تتمكّن التطبيقات من رصد الكاميرات التي يجب استخدامها، يمكنها اختيار الكاميرا التي تعمل بشكل أفضل في السياق. تعرِض CameraManager::getCameraList() قائمة بمثيلات CameraDescriptor التي توفّر خصائص كل كاميرا.

يمثّل صف CameraDevice جهاز كاميرا واحدًا ويعرِض طرقًا لبدء مصدر بياناته وإيقافه. إذا لم تكن خصائص الكاميرا معروفة بشكل ثابت، يحصل العملاء عليها من واصفها ويحلّلونها.

على سبيل المثال، يمكن للعميل الحصول على قائمة بإعدادات مصدر البيانات التي يقدّمها جهاز الكاميرا المستهدَف من بياناته الوصفية واختيار الإعدادات التي تتضمّن أفضل السمات (على سبيل المثال، عدد اللقطات في الثانية والدقة وتنسيق الإخراج).

// This class represents a single camera device.
public class CameraDevice {
    public:
        // Start a data stream that attributes are matching to given
        // configuration best.
        // If a selected configuration is not given (null), a data stream is
        // initiated in its default configuration and return.
        //
        // @param configuration Selected attributes of the imagery data stream.
        // @param listener An object to listen to an active data stream.
        // @param effective Actual attributes of started data stream.
        // @return CAMERA_EINVAL if a listener object is invalid.
        //         CAMERA_EIO if we failed to start a video stream.
        //         CAMERA_OK otherwise.
        virtual CameraError start(
                std::shared_ptr<CameraStreamConfiguration>& configuration,
                std::shared_ptr<CameraStreamListener>& listener,
                std::shared_ptr<CameraStreamConfiguration>* effective) = 0;

        // Stop a data stream.
        virtual void stop() = 0;

        // Get a camera descriptor.
        //
        // @param desc A set of attributes that defines this camera device.
        // @return CAMERA_ENODATA if a descriptor is not available.
        //         CAMERA_OK otherwise.
        CameraError getDescriptor(std::shared_ptr<CameraDescriptor>* desc) = 0;

        // Return a consumed buffer to the camera device. A client of active
        // stream must return a frame buffer explicitly by calling this method.
        virtual void doneWithFrame(std::shared_ptr<FrameBuffer>& buffer) = 0;

    private:
        // Describe this camera device.
        CameraDescriptor mDescriptor;

        // A weak reference to a listening client.
        std::weak_ptr<CameraStreamListener> mClient;
};

// This class declares attributes that characterize a camera device.
public class CameraDescriptor {
    public:
        // Unique std::string object to identify a single camera device.
        std::string mId;

        // A set of stream configurations this camera device is capable of. A
        // camera must have at least one stream configuration.
        std::set<CameraStreamConfiguration> mConfigurations;

        // Are more attributes needed to exist, such as locations, lens
        // facing directions, and intrinsic/extrinsic parameters?
};

// This class declares attributes that characterize an imagery data stream.
public class CameraStreamConfiguration {
    public:
        // Width of output of this stream in pixels.
        unsigned int mWidthInPixels;

        // Height of output of this stream in pixels.
        unsigned int mHeightInPixels;

        // An average number of frames per second.
        double mFrameRate;

        // A format of this stream's output. A client could calculate a
        // byte-per-pixel (bpp) from this.
        CameraColorFormat mFormat;
};

// This class represents a listener/callback object to listen to frames and
// events.
public class CameraStreamListener {
    public:
        // A listener method to receive various stream events including a new
        // frame buffer.
        //
        // @param event CameraStreamEvent object that represents a single event
        //              such as an arrival of a new frame buffer, camera stream
        //              is terminated, and so forth.
        virtual void onEvent(std::shared_ptr<CameraStreamEvent>* event) = 0;
};

تتلقّى CameraDevice::start() ثلاث وسيطات:

  • إعداد مصدر البيانات الذي اختاره المتصل

  • مستمع لتلقّي أحداث مصدر البيانات

  • مؤشر إلى إعداد مصدر بيانات فعّال ننصح بشدة أن يفحص المتصل هذه القيمة للتعامل مع مخازن الإطارات القادمة على النحو المطلوب.

عندما تبدأ CameraDevice::start() مصدر بيانات باستخدام منصة "خدمة الكاميرا"، تحتفظ بمرجع ضعيف إلى عنصر المستمع الخاص بالمتصل لرصد الإنهاء غير المتوقّع للمتصل.

عندما ينتهي العميل من استخدام مخزن إطارات، يجب أن يُعلم جهاز الكاميرا بأنّه لم يعُد بحاجة إلى مخزن الإطارات من خلال استدعاء طريقة CameraDevice::doneWithFrame().

عند بدء مصدر البيانات، يتلقّى العميل رسائل الأحداث. إحدى الرسائل الشائعة هي مخزن إطارات جديد. من خلال دالة معاودة الاتصال المسجّلة، يتلقّى العميل حدث kNewFrameBuffer الذي يحتوي على بيانات الصور بالإضافة إلى البيانات الوصفية لمخزن الإطارات. تعرِض StreamEventType المزيد من الأنواع للتعامل مع أحداث مصدر البيانات الأخرى. مثل مصدر البيانات المتوقف أو المعلق.

// This class lists events possibly occurring while a data stream is active.
enum class CameraStreamEventType {
    // A delivery of a new frame buffer.
    kNewFrameBuffer,
    // A data stream has been stopped.
    kStreamStopped,
    // No new frame buffer arrives for a while.
    kStreamHang,
    // Add more.
    ...
};

// This class represents a single instance of StreamEventType.
public class CameraStreamEvent {
    public:
        // Return a type of this event.
        //
        // @return CameraStreamEventType enum value.
        CameraStreamEventType getType() { return mType; }

        // Return a pointer to data associated with this event.
        //
        // @return A shared pointer object of the buffer that contains data for
        //         this event.
        std::shared_ptr<void> getData() { return mData; }

    private:
        // Describe a type of this event.
        CameraStreamEventType mType;

        // A pointer to the data buffer.
        std::shared_ptr<void> mData;
};

// This class inherits StreamEvent class and has additional fields to represent
// the frame buffer.
public class FrameBufferEvent : public CameraStreamEvent {
    public:
        // Return an identifier of this frame buffer.
        //
        // @return A unique integer value to identify this frame buffer.
        int getBufferID() { return mBufferID; }

        // Give access to frame buffer metadata.
        //
        // @return A shared pointer to the buffer that contains data besides
        //         the imagery data.
        std::shared_ptr<void> getMetadata() { return mMetadata; }

    private:
        // Unique integer to identify this buffer.
        int mBufferID;

        // A pointer to metadata of this frame buffer.
        std::shared_ptr<void> mMetadata;
};

يعرض هذا النموذج تنفيذًا لواجهة CameraInputBlock وتطبيقها:

CameraError getCameraManager(std::shared_ptr<CameraManager>* out) {
    // During an instantiation, CameraManager will retrieve a list of camera
    // devices from the platform camera service and identify their attributes.
    *out = std::make_shared<CameraManager>();
    return CAMERA_OK;
}

// This method returns a list of CameraDescriptor objects representing available
// cameras.
CameraError CameraManager::getCameraList(std::vector<CameraDescriptor>* out) {
    if (mCameraList.size() < 1) {
        // Query a list of cameras and get their attributes.
    }
    *out = mCameraList;
    return CAMERA_OK;
}

// Open a camera device associated with a given string identifier.
CameraError CameraManager::open(std::string id, std::shared_ptr<CameraDevice>* out) {
    if (!mCameraList.contains(id)) {
        // We cannot identify any camera with a given value.
        return CAMERA_NODEV;
    }

    // During a construction, CameraDevice will obtain a handle of a target
    // camera device from the platform camera service.
    std::shared_ptr<CameraDevice> h = std::make_shared<CameraDevice>(id);
    if (!h) {
        // We fail to open a camera device.
        return CAMERA_EACCESS;
    }

    *out = h;
    return CAMERA_OK;
}

// Close a camera device associated with a given string identifier. This method
// is assumed to be always successful.
void CameraManager::close(std::string id) {
    if (!mCameraList.contains(id)) {
        // We ignore calls with unknown identifiers.
        return;
    }

    // mCameraList.remove() returns an object removed from the list.
    std::shared_ptr<CameraDevice> device = mCameraList.remove(id);

    // Ensure a device stops streaming.
    device->stop();
}

// Start a data stream that attributes are matching to given configuration
// best.
// If a selected configuration is not given (null), a data stream will be
// initiated in its default configuration and return.
CameraError CameraDevice::start(
        std::shared_ptr<CameraStreamConfiguration>& configuration,
        std::shared_ptr<CameraStreamListener>& listener,
        std::shared_ptr<CameraStreamConfiguration>* effective) {
    if (!listener) {
        return CAMERA_EINVAL;
    }

    // selectStreamConfiguration examines this camera's stream configurations
    // and returns the one closest to the selected configuration.
    CameraStreamConfiguration config = selectStreamConfiguration(configuration);

    // mDevice refers to the camera handle for the platform camera service. We
    // may need to translate CameraStreamConfiguration for the platform service.
    mDevice->configure(
        configuration.mWidth, configuration.mHeight, configuration.mFormat);

    // Start a data stream with a callback object.
    if (!mDevice->startStream(mCallback)) {
        // We failed to start a data stream.
        return CAMERA_EIO;
    }

    return CAMERA_OK;
}

// Stop a data stream.
void CameraDevice::stop() {
    if (!mDevice) {
        // Nothing to do if we don't have a valid camera handle for the
        // platform camera service.
        return;
    }

    mDevice->stopStream();
}

// Get a camera descriptor.
CameraError CameraDevice::getDescriptor(std::shared_ptr<CameraDescriptor>* desc) {
    if (!mDescriptor) {
        return CAMERA_ENODATA;
    }

    *desc = *mDescriptor;
    return CAMERA_OK;
}

// Return a consumed buffer to the camera device. A client of active stream
// must return a frame buffer explicitly by calling this method.
void CameraDevice::doneWithFrame(std::shared_ptr<FrameBuffer>& buffer) {
    if (!mBufferRecords.contains(buffer.getId())) {
        // Ignore a call with unknown frame buffer.
        return;
    }

    // Simply remove from the record.
    (void)mBufferRecords.remove(buffer.getId());
}

// This method handles gear-shift events.
void Application::handleGearShift(GearSelection selection) {
    switch (selection) {
        case GEAR_SELECTION_REVERSE:
            // Upon the reverse gear selection, we are going to start a video
            // stream and show its preview on the instrument cluster display.
            (void)startStream(mCameraInputBlock);

            // FIXME: Exact method to control the camera preview window on the
            // instrument display is to be determined.
            show(mRearVisibilityWindow);
            break;

        default:
            // Upon all other gear selection, we are going to stop a video
            // stream (if it's running) and hide the preview.
            stopStream(mCameraInputBlock);

            // FIXME: Exact method to control the camera preview window on the
            // instrument display is to be determined.
            hide(mRearVisibilityWindow);
            break;
    }
}

bool Application::startStream(std::shared_ptr<CameraInputBlock> handle) {
    return handle->start(std::bind(&Application::handleStreamCallback, this);
}

void Application::stopStream(std::shared_ptr<CameraInputBlock> handle) {
    handle->stop();
}

// This method handles a stream callback.
void Application::handleStreamCallback(StreamEvent& event) {
    switch (event.getType()) {
        case StreamEventType::kNewFrameBuffer:
            // Handle a new frame buffer. We may just enqueue it for the
            // future or forward to CameraInputBlock client.
            break;

        case StreamEventType::kStreamStopped:
            // Handle as an incident if this event is not expected.
            break;

        // More cases to be added.
    }
}

void Application::handleNewFrameBuffer(StreamEvent& event) {
    // Enqueue a new frame buffer for the further processing. A buffer
    // must be returned explicitly by calling
    // CameraDevice.doneWithFrame(FrameBuffer&) method.
}

void Application::handleStreamEvent(StreamEvent& event) {
    // Handle a received stream event except a new frame buffer's
    // arrival; e.g. a video stream is terminated unexpectedly.
}

الأداء

تستوفي الرؤية الخلفية هذه اللوائح الحكومية.

القيمة اللائحة التنظيمية
وقت الاستجابة CFR 571.111 S5.5.3
عدد اللقطات في الثانية UNECE R46 6.2.2.3.4
وقت تكوين الصورة UNECE R46 6.2.2.3.4.2
وقت الاستجابة في النظام UNECE R46 6.2.2.3.4.3

الخصوصية

في ما يتعلق بالخصوصية:

  • لا تطلب واجهة برمجة التطبيقات من عمليات التنفيذ جمع معلومات تكشف الهوية الشخصية أو تسجيلها أو تخزينها. ومع ذلك، بما أنّ بيانات الصور التي تم التقاطها (أو البيانات الوصفية المرتبطة بها) قد تحتوي على معلومات تكشف الهوية الشخصية، يجب أن يحصل التطبيق الذي يستخدم واجهة برمجة التطبيقات على موافقة المستخدم الصريحة.

  • لا يمكن للمستخدمين التحكّم في أجهزة الكاميرا لمعاينتها على شاشة لوحة العدادات لأنّ الكاميرات تؤدي أدوارًا مهمة للسلامة. يحصل مصنّعو المعدات الأصلية على موافقة المستخدم أثناء الإعداد أو من السائق.

  • لا تتوافق واجهة برمجة التطبيقات هذه مع عملاء الكاميرا في الخلفية. لذلك، فإنّ مؤشر الخصوصية الذي يُعلم المستخدمين بأنّ جهاز الكاميرا يلتقط البيانات خارج النطاق.