🌐 English

    MediaObserver Interface#

    Playback and recording components process events through a user-defined Observer object derived from MediaObserver.

    oasis::MediaObserver is defined in OasisMedia.h as follows:

    class MediaObserver : public std::enable_shared_from_this<MediaObserver>
    {
    public:
        MediaObserver();
        virtual ~MediaObserver();
    
        //recording or playing started and stopped
        virtual void onStarted(void *user_data, const char *file_path);
        virtual void onStopped(void *user_data, media_report_reason_t reason, void *details);
        //recording a new file
        virtual void onFileChanged(void *user_data, const char *new_file_path);
        virtual void onFileDeleted(void *user_data, const char *deleted_file_path);
        virtual void onError(void *user_data, media_report_reason_t reason, void *details);
    
        //periodic report every 1 second.
        virtual void onInfo(void *user_data, MediaInfo *info);
        virtual void onInfoEx(void *user_data, MediaInfoEx *info);
    
        //player paused and resumed
        virtual void onPaused(void *user_data, MediaInfo *info);
        virtual void onResumed(void *user_data, MediaInfo *info);
    
        //event recording started and completed(aborted)
        virtual void onEventRecordingStarted(void *user_data, media_report_reason_t reason, const char *file_path);
        virtual void onEventRecordingCompleted(void *user_data, media_report_reason_t reason, const char *file_path);
    
        //motion recording started and completed(aborted)
        virtual void onMotionRecordingStarted(void *user_data, media_report_reason_t reason, const char *file_path);
        virtual void onMotionRecordingCompleted(void *user_data, media_report_reason_t reason, const char *file_path);
    
        virtual void queryNewFilePath(void *user_data, recording_mode_t file_type, bool rear_camera_on, bool sound_on, std::string &file_path);
    
        virtual void onSnapshotCompleted(void *user_data, uint32_t snapshot_id, int32_t camera_id, int error, const std::vector<char> &jpeg_image_data, const struct timeval &timestamp);
    };
    

    Note

    MediaObserver::onPaused and MediaObserver::onResumed are called during recording file playback.

    Header File#

    OasisMedia.h

    Functions#

    void onStarted ( void * user_data , const char * file_path )
    OasisMedia.h
    Called after recording starts.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    file_path  The path to the recording file.
    void onStopped ( void * user_data , media_report_reason_t reason , void * details )
    OasisMedia.h
    Called after recording stops.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason for stopping.
    details  Detailed data corresponding to the reason for stopping. The type is defined based on the reason value.

    General media_report_reason_t constant values are as follows:

    Reason Constant Value Meaning details
    kMediaReportGenericError -1 General error. nullptr
    kMediaReportNoError 0 No error has occurred. nullptr

    For the recording component, media_report_reason_t constant values are as follows:

    Reason Constant Value Meaning details
    kRecording​All​Files​Recorded 201 Completed all recordings. nullptr
    kRecording​Error​Not​Ready 400 Requested to start recording when recording is not ready. nullptr
    kRecording​Error​Already​Started 401 Recording has already started. nullptr
    kRecording​Error​Writer​Preparation​Failed 402 Failed to prepare the recording file. nullptr
    kRecording​Error​Writer​Start​Failed 403 Failed to start writing the recording file. nullptr
    kRecording​Error​Source​Start​Failed 404 Failed to start the camera device. nullptr
    kRecording​Error​Not​Prepared 405 State is not prepared (not used). nullptr
    kRecording​Error​Not​Started 406 State is not started (not used). nullptr
    kRecording​Error​Disk​Almost​Full 407 The disk is almost full (not used). nullptr
    kRecording​Error​No​Disk​Mount 408 Not mounted (not used). nullptr
    kRecording​Error​File​I​O 409 File I/O error. nullptr
    kRecording​Error​Resume​Failed 410 Failed to restart recording. nullptr
    kRecording​Error​Media​Data​Timeout 411 Video data has not been generated for a certain period of time. int32_t camera_id
    kRecording​Error​Index​Table​Overflow 412 The index table capacity of the file has been exceeded. nullptr
    kRecording​Error​Event​Writer​Preparation​Failed 430 Failed to prepare the event recording file. nullptr
    kRecording​Error​Event​Writer​Start​Failed 431 Failed to start the event recording file. nullptr
    kRecording​Error​Motion​Writer​Preparation​Failed 450 Failed to prepare the motion recording file. nullptr
    kRecording​Error​Motion​Writer​Start​Failed 451 Failed to start the motion recording file. nullptr
    kRecording​Error​Media​Cache​Read​Error​Begin 460 Initial failure occurred while reading the media cache. nullptr
    kRecording​Error​Media​Cache​Read​Error​End 461 Failure while reading the media cache has ended. nullptr
    kSnapshot​Error​Timeout 600 Snapshot timeout occurred. nullptr

    For the playback component, media_report_reason_t constant values are as follows:

    Reason Constant Value Meaning details
    kPlaying​End​Of​File​Reached 200 Playback of the recording file has ended. nullptr
    kPlaying​Error​File​Not​Found 500 Recording file cannot be found. nullptr
    kPlaying​Error​File​Ext​Not​Supported 501 Unsupported recording file extension. nullptr
    kPlaying​Error​Source​Not​Ready 502 Recording file is not ready. nullptr
    kPlaying​Error​No​Tracks 503 No tracks to play. nullptr
    kPlaying​Error​Sound​Not​Ready 504 Audio is not ready. nullptr
    kPlaying​Error​Sound​Decoder​Not​Ready 505 Audio decoder is not ready. nullptr
    kPlaying​Error​Video​Renderer​Not​Ready 506 Video renderer is not ready. nullptr
    kPlaying​Error​Video​Decoder​Not​Ready 507 Video decoder is not ready. nullptr
    kPlaying​Error​Video​Track​Not​Ready 508 Video track is not ready. nullptr
    kPlaying​Error​Subtitle​Source​Not​Ready 509 Caption source is not ready. nullptr
    kPlaying​Error​Text​Track​Not​Ready 510 Text track is not ready. nullptr
    kPlaying​Error​Text​Decoder​Not​Ready 511 Text decoder is not ready. nullptr
    kPlaying​Error​Text​Renderer​Not​Ready 512 Text renderer is not ready. nullptr
    kPlaying​Error​Video​Renderer​Start​Failed 513 Cannot start the video renderer. nullptr
    kPlaying​Error​Audio​Renderer​Start​Failed 514 Cannot start the audio renderer. nullptr
    kPlaying​Error​Text​Renderer​Start​Failed 515 Cannot start the text renderer. nullptr
    kPlaying​Error​Sound​Device​Busy 516 Audio device is busy. nullptr
    kPlaying​Error​Display​Layer​Not​Ready 517 Display layer is not ready. nullptr
    kPlaying​Error​Zero​Duration 518 Playback duration is 0 seconds. nullptr
    kPlaying​Error​Video​Setup​Exception 519 Video initialization error. nullptr
    kPlaying​Error​Audio​Setup​Exception 520 Audio initialization error. nullptr
    kPlaying​Error​Adas​Not​Ready 521 ADAS is not ready. nullptr
    kPlaying​Error​Adas​Start​Failed 522 ADAS start error. nullptr
    void onFileChanged ( void * user_data , const char * new_file_path )
    OasisMedia.h
    Called when recording restarts with a new file. If file-duration-secs elapses during recording or the allocated file size is exceeded, recording automatically restarts with a new file. The new file path can be changed when MediaObserver::queryNewFilePath is called.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    new_file_path  The new recording file path.
    void onFileDeleted ( void * user_data , const char * deleted_file_path )
    OasisMedia.h
    Called after the oldest file is deleted from the folder when the number of recording files is limited.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    deleted_file_path  The path of the deleted recording file.
    void onError ( void * user_data , media_report_reason_t reason , void * details )
    OasisMedia.h
    Called when an error occurs during recording. The user can call stopRecording in a separate thread to stop recording, or restart recording after resolving the error problem.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason for stopping.
    details  Detailed data corresponding to the reason for stopping. The type is defined based on the reason value.

    Note

    kRecordingErrorMediaCacheReadErrorBegin ~ kRecordingErrorMediaCacheReadErrorEnd occurs when data required for recording cannot be read from the media cache. If recording continues while ignoring this, all data within the range of the time occurrence will be filled with "0" values. In the case of video, a green screen may be visible during playback, and in the case of audio, silence occurs.

    void onInfo ( void * user_data , MediaInfo * info )
    OasisMedia.h
    Called at 1-second intervals after recording starts when report-media-info-ex is set to "0" and the Recorder object is created via createRecorder.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    info  The status information.
    void onInfoEx ( void * user_data , MediaInfoEx * info )
    OasisMedia.h
    Called at 1-second intervals after recording starts when report-media-info-ex is set to "1" and the Recorder object is created via createRecorder.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    info  The status information.
    void onEventRecordingStarted ( void * user_data , media_report_reason_t reason , const char * file_path )
    OasisMedia.h
    Called when event recording starts.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason generated when recording starts.
    file_path  The absolute path of the event recording file.
    void onEventRecordingCompleted ( void * user_data , media_report_reason_t reason , const char * file_path )
    OasisMedia.h
    Called when event recording ends.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason generated when recording completes.
    file_path  The absolute path of the event recording file.
    void onMotionRecordingStarted ( void * user_data , media_report_reason_t reason , const char * file_path )
    OasisMedia.h
    Called when motion recording starts.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason generated when recording starts.
    file_path  The absolute path of the motion recording file.
    void onMotionRecordingCompleted ( void * user_data , media_report_reason_t reason , const char * file_path )
    OasisMedia.h
    Called when motion recording ends.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    reason  A constant value indicating the reason generated when recording completes.
    file_path  The absolute path of the motion recording file.
    void queryNewFilePath ( void * user_data , recording_mode_t file_type , bool rear_camera_on , bool sound_on , std::string & file_path )
    OasisMedia.h
    Called to verify the new recording file path before starting a new recording. The user can modify and return a new recording file name or path if necessary.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    file_type  One of the values kRecordingModeNormal(0) or kRecordingModeSniffing(1).
    rear_camera_on  true if the rear camera is also recording.
    sound_on  true if audio is also recording.
    file_path  IN OUT The absolute path of the new recording file. A modified absolute path can be returned. The folder location of the automatically generated absolute file path is the normal-folder-path key value applied when creating the recording object or changing parameters.
    void onSnapshotCompleted ( void * user_data , uint32_t snapshot_id , int32_t camera_id , int error , const std::vector<char> & file_path , const struct timeval & timestamp )
    OasisMedia.h
    Called when snapshot generation terminates or an error occurs after calling takeRecordingSnapshot of the recording component.
    Parameters
    user_data  The user_data parameter value received when calling startRecording.
    snapshot_id  The snapshot_id value received when calling takeRecordingSnapshot.
    camera_id  The target snapshot camera ID received when calling takeRecordingSnapshot.
    error  The error value. It has the value kMediaReportNoError(0) if the snapshot is successful.
    file_path  The JPEG file data generated by the snapshot. Valid only when error is 0. The user can save this data to a file in a separate thread.
    timestamp  The timestamp when the snapshot was generated.

    Structures#

    struct TimeShiftStat
    OasisMedia.h
    Event/motion recording status information.
    Member Type & Name
    Description
    bool recording
    Event/motion recording is in progress.
    int32_t maxSamples
    The maximum number of samples.
    int32_t curSamples
    The current number of samples.
    int32_t curSize
    The total size of the current number of samples.
    uint32_t video1Length
    The main video data length.
    uint32_t video2Length
    The other video data length.
    uint32_t metaLength
    The metadata length.
    uint32_t audioLength
    The audio data length.
    uint32_t fileLength
    The current event/motion recording file size.
    struct RecordingStat
    OasisMedia.h
    Normal recording status information.
    Member Type & Name
    Description
    int32_t maxSamples
    The maximum number of normal recording samples.
    int32_t curSamples
    The current number of normal recording samples.
    uint32_t video1Length
    The main video data length.
    uint32_t video2Length
    The other video data length.
    uint32_t metaLength
    The metadata length.
    uint32_t audioLength
    The audio data length.
    uint32_t fileLength
    The recording file size saved up to the current point.
    TimeShiftStat motionStat
    The motion recording status.
    struct OffsStat
    OasisMedia.h
    Oasis File System (OFFS) status information.
    Member Type & Name
    Description
    int32_t qNormalCount
    The normal recording queue length. It increases when the recording object requests writing normal recording data to OFFS, and decreases when OFFS finishes writing.
    int32_t qEventCount
    The event recording queue length. It increases when the recording object requests writing event or motion recording data to OFFS, and decreases when OFFS finishes writing.
    ssize_t qNormalSize
    The total length of data accumulated in the normal recording queue, measured in bytes.
    ssize_t qEventSize
    The total length of data accumulated in the event recording queue, measured in bytes.
    int32_t cacheHits
    When using the read cache, this represents the number of hits when the cache entry is utilized upon a read request from the application to OFFS. An increase in the hit count implies that using the cache is effective to that extent.
    int32_t checkDuration
    The check duration. Status information checks are usually performed at 1-second intervals.
    int32_t inSize
    The total write request size requested to OFFS that occurred during the check duration.
    int32_t outSize
    The size actually written to the disk by OFFS during the check duration. By comparing inSize and outSize, you can verify whether data is being accumulated; if data accumulates, writing performance improvements for the SD card are required.
    int32_t elapsedSum
    The total time taken for OFFS to perform write operations, measured in milliseconds. This can be referenced to check writing performance. For example, you can verify the total time taken to write a 1-minute long recording file.
    OasisMedia.h
    Media cache status information.
    Member Type & Name
    Description
    uint32_t hits_
    The number of media cache hits. The hit count increases if data temporarily stored in memory actually exists.
    uint32_t nohits_
    The number of media cache misses. If temporarily stored data in memory is overwritten by other media data over time, the miss count increases when the desired media data cannot be obtained. It is necessary to increase the media cache data size or adjust the properties that affect the amount of data generated during recording (frame rate, resolution, bitrate, encoding quality, etc.).
    uint32_t total_buffer_count_
    The total number of allocated media buffers. Used by each component to preserve information (size, location, type, etc.) in the media data.
    uint32_t free_buffer_count_
    The number of available media buffers.
    uint32_t get_buffer_count_
    The number of media buffer acquisition requests. This value increases when a component successfully acquires a media buffer upon request to use it.
    uint32_t put_buffer_count_
    The number of media buffer return requests. This value increases when a component returns a media buffer.
    int32_t check_duration_
    The check duration. Status information checks are usually performed at 1-second intervals.
    int32_t in_size_
    The total data size stored in the media cache, measured in bytes. It increases steadily while saving one recording file.
    struct MediaInfo
    OasisMedia.h
    Passed as a parameter in the MediaObserver::onInfo event invocation callback function.
    Member Type & Name
    Description
    bool sniffing
    true if Sniffing mode. false if normal recording mode.
    int64_t durationUs
    The file recording (playback) duration up to the current point. In the case of timelapse recording, it is the actual total file playback duration.
    int64_t currentTimestampUs
    Identical to the durationUs value.
    TimeShiftStat timeshiftStat
    Event/motion recording status information.
    struct MediaInfoEx
    OasisMedia.h
    Passed as a parameter in the MediaObserver::onInfoEx event invocation callback function. report-media-info-ex must be set to "1" when creating the recording object.
    Member Type & Name
    Description
    bool sniffing
    true if Sniffing mode. false if normal recording mode.
    int64_t durationUs
    The file recording (playback) duration up to the current point. In the case of timelapse recording, it is the actual total file playback duration.
    int64_t currentTimestampUs
    Identical to the durationUs value.
    TimeShiftStat timeshiftStat
    Event/motion recording status information.
    RecordingStat writerStat
    Recording write status information.
    OffsStat offsStat
    File system status information.
    MediaCacheStat mediaCacheStat
    Media cache status information.

    Example#

    Users of the recording component define a class with MediaObserver as a base class, and pass it as a parameter when calling the oasis::startRecording function. Below is an example of creating MyRecordingObserver and passing it to oasis::startRecording.

    std::shared_ptr<MyRecordingObserver> recording_observer = std::make_shared<MyRecordingObserver>();
    RecorderRef recorder = createRecorder(parameters);
    startRecording(recorder, recording_observer, nullptr /*user_data*/);
    

    Below is an example of outputting MediaInfoEx to the console. The dumpInfoEx function is used in other example code resources.

    void bytesToString(size_t size, char *size_string)
    {
        if(size >= 1024*1024) {
            sprintf(size_string, "%.2fMB", (double)size/1048576);
        } else if(size >= 1024) {
            sprintf(size_string, "%.2fKB", (double)size/1024);
        } else {
            sprintf(size_string, "%dB", size);
        }
    }
    
    void dumpInfoEx(MediaInfoEx* info)
    {
        int h, m, s, u;
        char normal_qsize[128], event_qsize[128], in_size[128], out_size[128], cache_in_size[128];
        char video1_size[128], video2_size[128], meta_size[128], audio_size[128], file_size[128];
        parseUsec(info->durationUs, h, m, s, u);
    
        TRACE0("Recording duration \033[33m%02d:%02d:%02d.%06d\033[0m, wq#%d(%d), eq#%d(%d), meq#%d(%d), nohits#%u, mb.avail#%d/%d (free mem %.3fMB, cpu %.2f%%)\r\n", h, m, s, u, info->writerStat.curSamples, info->writerStat.maxSamples, info->timeshiftStat.curSamples, info->timeshiftStat.maxSamples, info->writerStat.motionStat.curSamples, info->writerStat.motionStat.maxSamples, info->mediaCacheStat.nohits_, info->mediaCacheStat.free_buffer_count_, info->mediaCacheStat.total_buffer_count_, (double)oasis::getFreeMemorySize()/1024.0/1024.0, getCPUUsage());
    
        //offs state
        bytesToString(info->offsStat.qNormalSize, normal_qsize);
        bytesToString(info->offsStat.qEventSize, event_qsize);
    
        bytesToString(info->offsStat.inSize, in_size);
        bytesToString(info->offsStat.outSize, out_size);
    
        bytesToString(info->mediaCacheStat.in_size_, cache_in_size);
    
    
        TRACE0("    cache: during %d msec, in %s\r\n", info->mediaCacheStat.check_duration_, cache_in_size);
        TRACE0("    offs: n#%d, e#%d, nz#%s, ez#%s, during %d msec: in %s out %s elapsed %d msec \r\n", info->offsStat.qNormalCount, info->offsStat.qEventCount, normal_qsize, event_qsize, info->offsStat.checkDuration, in_size, out_size, info->offsStat.elapsedSum);
    
        //print recording stat in details
        bytesToString(info->writerStat.video1Length, video1_size);
        bytesToString(info->writerStat.video2Length, video2_size);
        bytesToString(info->writerStat.metaLength, meta_size);
        bytesToString(info->writerStat.audioLength, audio_size);
        bytesToString(info->writerStat.fileLength, file_size);
        TRACE0("    %s: video1 %s, video2 %s, meta %s, audio %s, file %s\n", info->sniffing?"sniffing":"recording", video1_size, video2_size, meta_size, audio_size, file_size);
    
        if(info->writerStat.motionStat.recording) {
            bytesToString(info->writerStat.motionStat.video1Length, video1_size);
            bytesToString(info->writerStat.motionStat.video2Length, video2_size);
            bytesToString(info->writerStat.metaLength, meta_size);
            bytesToString(info->writerStat.audioLength, audio_size);
            bytesToString(info->writerStat.fileLength, file_size);
            TRACE0("    motion: video1 %s, video2 %s, meta %s, audio %s, file %s\n", video1_size, video2_size, meta_size, audio_size, file_size);
        }
    
        if(info->timeshiftStat.recording) {
            bytesToString(info->timeshiftStat.video1Length, video1_size);
            bytesToString(info->timeshiftStat.video2Length, video2_size);
            bytesToString(info->timeshiftStat.metaLength, meta_size);
            bytesToString(info->timeshiftStat.audioLength, audio_size);
            bytesToString(info->timeshiftStat.fileLength, file_size);
            TRACE0("    event: video1 %s, video2 %s, meta %s, audio %s, file %s\n", video1_size, video2_size, meta_size, audio_size, file_size);
        }
    }