نمای دوربین HAR

نهادهای نظارتی دولتی الزامات متعددی را اجرا می‌کنند تا اطمینان حاصل شود که دید غیرمستقیم از عقب، اطلاعات کافی برای مانور دقیق و به موقع خودرو را فراهم می‌کند. این امر بر آگاهی راننده از محیط اطراف تأثیر می‌گذارد.

برای سیستم‌های دید عقب مبتنی بر سیستم نظارت دوربین (CMS)، اداره ملی ایمنی ترافیک بزرگراه‌ها (NHTSA) شما را ملزم به رعایت این الزامات می‌کند (S6.6.2.3 ارجاع شده از UNECE46):

  • S5.5.3 زمان پاسخ. تصویر دید عقب که الزامات S5.5.1 (میدان دید) و S5.5.2 (اندازه) را برآورده می‌کند، هنگام آزمایش مطابق با S14.2، ظرف 2.0 ثانیه از شروع یک رویداد پشتیبان نمایش داده می‌شود.

  • 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 زمان تشکیل تصویر. زمان تشکیل تصویر مانیتور در دمای ۲۲ درجه سانتیگراد ± ۵ درجه سانتیگراد کمتر از ۵۵ میلی‌ثانیه است.

  • S6.2.2.3.4.3 تأخیر سیستم. یک سیستم مانیتور دوربین (CMS) تأخیر به اندازه کافی کوتاهی دارد تا تقریباً همزمان صحنه را رندر کند. این تأخیر در دمای ۲۲ درجه سانتیگراد ± ۵ درجه سانتیگراد کمتر از ۲۰۰ میلی‌ثانیه است.

ما سیستم نمای توسعه‌یافته (EVS) سیستم عامل اندروید خودرو (AAOS) را برای رعایت این الزامات در AAOS فلزی خام معرفی کردیم. ما سرویس مشابهی را برای مجازی‌سازی در دستگاه‌های AAOS با رندرکننده با قابلیت دسترسی بالا (HAR) معرفی کردیم که آن نیز انطباق با این الزامات را نشان می‌دهد.

پیش‌نمایش دوربین

این پنج مرحله، خط لوله پیش‌نمایش دوربین را تشکیل می‌دهند:

مراحل پیش‌نمایش دوربین

شکل 1. مراحل خط لوله پیش‌نمایش دوربین.

بلوک سرویس دوربین به پلتفرم سرویس دوربین و لایه انتزاعی آن اشاره دارد که به برنامه‌ها اجازه می‌دهد به دوربین‌های موجود دسترسی داشته باشند و از آنها استفاده کنند. تابع سرویس نمایش، داده‌های تصویری را برای کاربران تجسم می‌کند. برنامه، مسیرهای کاربر هدف را با سرویس دوربین و سرویس نمایش پیاده‌سازی می‌کند.

مسیر اصلی کاربر برای مشاهده عقب خودرو به شرح زیر است:

  1. راننده، انتخابگر جهت (دنده) را در حالت دنده عقب قرار می‌دهد تا سیستم دنده عقب فعال شود.

  2. سیستم رویداد پشتیبان را پخش می‌کند. برنامه پخش را دریافت می‌کند و بلوک ورودی دوربین (سرویس دوربین) و رندرکننده (سرویس نمایش) را مقداردهی اولیه می‌کند.

  3. بلوک ورودی دوربین، پلتفرم سرویس دوربین را مقداردهی اولیه می‌کند و شناسه سرویس را به برنامه برمی‌گرداند.

  4. رندرر، پنجره‌ی نمایش را برای ورودی دوربین از مرحله‌ی ۴ مقداردهی اولیه می‌کند.

  5. برنامه از بلوک ورودی دوربین درخواست می‌کند تا ارسال بافرهای فریم و رویدادها را آغاز کند.

  6. برنامه، بافرهای فریم تحویل داده شده را از طریق فراخوانی‌های برگشتی (غیرهمزمان) در صف قرار می‌دهد. بافرهای فریم متعلق به بلوک ورودی دوربین هستند، بنابراین برنامه نمی‌تواند آنها را تغییر دهد.

  7. برنامه یک بافر فریم را از صف خارج می‌کند (اگر صف خالی نباشد) و نمای کاربر را تشکیل می‌دهد. کاربران می‌توانند برای تغییر محتوا، یک کپی تهیه کنند.

  8. برنامه یک بافر به رندرکننده ارسال می‌کند.

  9. رندرر، محتویات بافر دریافتی را روی صفحه نمایش رسم می‌کند.

  10. اگر رویداد پشتیبان همچنان در حال انجام است، به مرحله ۷ بروید. وقتی رویداد پشتیبان تکمیل شد، برنامه از بلوک ورودی دوربین درخواست می‌کند که ارسال بافرهای فریم و رویدادها را پس از پنهان کردن نمای کاربر متوقف کند.

  11. برنامه به صورت اختیاری دوربین را می‌بندد و رندرکننده را آزاد می‌کند.

شکل ۱ جریان را نشان می‌دهد. این تصویر از عناصری از API کتابخانه دوربین QNX برای استفاده از پلتفرم سرویس دوربین استفاده می‌کند.

سفر کاربر اولیه HAR

شکل ۲. مسیر کاربر اصلی HAR.

بلوک ورودی دوربین سه رابط را تعریف می‌کند:

  • CameraManager ، متدهایی را برای مدیریت دستگاه‌های دوربین تعریف می‌کند؛ برای مثال، برنامه از این رابط برای باز کردن (رزرو) یک دستگاه دوربین هدف استفاده می‌کند.

  • CameraDevice متدهایی را برای کنترل یک دستگاه دوربین تعریف می‌کند؛ برای مثال، شروع یا توقف یک جریان داده.

  • CameraStreamListener یک متد واحد برای دریافت رویدادهای مختلف از دوربین هدف تعریف می‌کند.

طراحی

این بخش جزئیات طراحی سیستم را شرح می‌دهد.

تجربه کاربری

راننده می‌تواند هنگام قرار دادن دنده عقب در صفحه نمایش داشبورد، پیش‌نمایش دوربین عقب را مشاهده کند. وقتی راننده دنده را به عقب می‌برد، نمایش دوربین در صفحه نمایش متوقف می‌شود.

می‌توان سفرهای اضافی کاربر را فعال کرد. برای مثال، راننده می‌تواند هنگام فعال شدن چراغ راهنما، ناحیه‌ای را که در آینه‌ها قابل مشاهده نیست، پیش‌نمایش کند.

شروع پیش‌نمایش دوربین

هنگام استفاده از دوربین‌ها، برنامه دوربین‌های موجود را فهرست و ارزیابی می‌کند تا بهترین دوربین را برای هدف مورد نظر پیدا کند. به عنوان مثال، برای دید عقب، برنامه از لیست دوربین‌های موجود، دوربینی را که قسمت عقب خودرو را نشان می‌دهد، جستجو می‌کند.

این برنامه با بررسی ویژگی‌های هر دوربین، به عنوان مثال، موقعیت مکانی، جهت لنز، نرخ فریم، وضوح خروجی و فرمت خروجی، این موضوع را ارزیابی می‌کند. اگر چندین دوربین ویژگی‌های مورد نیاز یکسانی داشته باشند، برنامه ممکن است ویژگی‌های اضافی مانند میدان دید و فاصله کانونی را نیز بررسی کند.

این تصویر ترتیب شروع پیش‌نمایش دوربین با پیکربندی دوربین ثابت را نشان می‌دهد:

پیش‌نمایش دوربین را با پیکربندی ثابت دوربین شروع کنید

شکل ۳. شروع پیش‌نمایش دوربین با پیکربندی ثابت دوربین

توقف پیش‌نمایش دوربین

برنامه پس از پایان رویداد پشتیبان، ارائه دید عقب را متوقف می‌کند. برای جلوگیری از نمایش صفحه خالی یا تصویر ثابت، برنامه ابتدا نمای را از کاربر پنهان می‌کند و سپس از بلوک ورودی دوربین درخواست می‌کند که ارسال رویدادها را متوقف کند.

این تصویر ترتیبی را برای متوقف کردن جریان داده از دستگاه دوربین هدف نشان می‌دهد:

توقف پخش داده‌ها از دستگاه دوربین هدف

Figure 4. Stop data stream from target camera device.

خطاها

یک دستگاه دوربین می‌تواند به طور غیرمنتظره ارسال یک بافر فریم جدید را متوقف کند. برای تشخیص چنین حوادثی، بلوک ورودی دوربین ممکن است یک تایمر را پیاده‌سازی کند که با ورود یک فریم جدید منقضی می‌شود و هنگام انقضای این تایمر، اعلانی ارسال کند.

وقتی برنامه یک اعلان دریافت می‌کند، به کاربر اطلاع می‌دهد که پیش‌نمایش دوربین دیگر فعال نیست و با بستن دستگاه دوربین و باز کردن مجدد آن، سعی می‌کند پیش‌نمایش دوربین را بازیابی کند. شکل 5 نحوه مدیریت زمان انقضا توسط برنامه را نشان می‌دهد:

مدیریت زمان انقضا

شکل ۵. مدیریت وقفه زمانی (جریان داده معلق).

بلوک ورودی دوربین می‌تواند حوادثی غیر از جریان داده‌ی معلق را گزارش دهد و جزئیات بیشتری را در بافرها جاسازی کند. تولیدکنندگان اصلی تجهیزات (OEM) می‌توانند از این فراداده‌ی رویداد برای مدیریت حوادث در پلتفرم خود استفاده کنند.

فعالیت‌ها

این API توسط برنامه‌هایی که روی میزبان اجرا می‌شوند و نمایشگر صفحه کیلومترشمار را از طریق HAR (بلوک‌های آبی در نمودار زیر) مدیریت می‌کنند، استفاده می‌شود.

نمودار سیستم در شکل ۵ نشان داده شده است:

نمودار سیستم

شکل ۶. نمودار سیستم.

خدمات

انتظار می‌رود فراخوانی‌های API در چارچوب فرآیند فراخوانی اجرا شوند.

رابط‌های برنامه‌نویسی کاربردی (API)

این API جدید فقط برای برنامه‌هایی در نظر گرفته شده است که پیش‌نمایش‌های دوربین روی صفحه نمایش داشبورد را از طریق HAR مدیریت می‌کنند. این API از طریق لایه انتزاعی پلتفرم در دسترس است و به صورت پویا پیوند برقرار می‌کند.

رابط 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() ‎ یک جریان داده را با پلتفرم Camera Service آغاز می‌کند، یک ارجاع ضعیف به شیء شنونده‌ی فراخوانی‌کننده نگه می‌دارد تا خاتمه‌ی غیرمنتظره‌ی فراخوانی‌کننده را تشخیص دهد.

وقتی کلاینت کار خود را با یک بافر فریم تمام می‌کند، باید با فراخوانی متد 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

حریم خصوصی

ویژه حریم خصوصی:

  • این API نیازی به پیاده‌سازی برای جمع‌آوری، ثبت یا ذخیره اطلاعات شخصی قابل شناسایی (PII) ندارد. با این حال، از آنجا که داده‌های تصاویر گرفته شده (یا فراداده‌های مرتبط) می‌توانند حاوی PII باشند، برنامه‌ای که از API استفاده می‌کند باید رضایت صریح کاربر را دریافت کند.

  • کاربران نمی‌توانند دستگاه‌های دوربین را برای پیش‌نمایش روی صفحه نمایش داشبورد کنترل کنند زیرا دوربین‌ها نقش‌های حیاتی ایمنی دارند. تولیدکنندگان اصلی تجهیزات (OEM) هنگام راه‌اندازی یا از راننده رضایت کاربر را دریافت می‌کنند.

  • این API از کلاینت‌های دوربین پس‌زمینه پشتیبانی نمی‌کند. بنابراین، نشانگر حریم خصوصی که به کاربران اطلاع می‌دهد که دستگاه دوربین در حال ضبط داده‌ها است، خارج از محدوده است.