UnaNancyOwen
9/10/2019 - 4:18 PM

record.hpp

/*
 This is C++ wrapper for Record API of Azure Kinect Sensor SDK.
 
 Copyright (c) 2019 Tsukasa Sugiura <t.sugiura0204@gmail.com>
 Licensed under the MIT license.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
*/
#ifndef K4A_RECORD_HPP
#define K4A_RECORD_HPP

#include <k4a/k4a.hpp>
#include <k4arecord/record.h>

namespace k4a
{
    class record
    {
    public:
        record( k4a_record_t handle = nullptr ) noexcept : m_handle( handle ) {}

        record( record&& other ) noexcept : m_handle( other.m_handle )
        {
            other.m_handle = nullptr;
        }

        record( const record& ) = delete;

        ~record()
        {
            flush();
            close();
        }

        record& operator=( const record& ) = delete;

        record& operator=( record&& other ) noexcept
        {
            if( this != &other )
            {
                flush();
                close();
                m_handle = other.m_handle;
                other.m_handle = nullptr;
            }

            return *this;
        }

        operator bool() const noexcept
        {
            return m_handle != nullptr;
        }

        void close() noexcept
        {
            if( m_handle )
            {
                k4a_record_close( m_handle );
                m_handle = nullptr;
            }
        }

        void flush()
        {
            if( m_handle )
            {
                k4a_record_flush( m_handle );
            }
        }

        void write_custom_track_data( const char* track_name, const uint64_t device_timestamp_usec, uint8_t* custom_data, const size_t custom_data_size )
        {
            k4a_result_t result = k4a_record_write_custom_track_data( m_handle, track_name, device_timestamp_usec, custom_data, custom_data_size );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to write imu sample!" );
            }
        }

        void write_imu_sample( const k4a_imu_sample_t& imu_sample )
        {
            k4a_result_t result = k4a_record_write_imu_sample( m_handle, imu_sample );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to write imu sample!" );
            }
        }

        void write_capture( const k4a::capture& capture )
        {
            k4a_result_t result = k4a_record_write_capture( m_handle, capture.handle() );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to write capture!" );
            }
        }

        void write_header()
        {
            k4a_result_t result = k4a_record_write_header( m_handle );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to write header!" );
            }
        }

        void add_custom_subtitle_track( const char* track_name, const char* codec_id, const uint8_t* codec_context, const size_t codec_context_size, const k4a_record_subtitle_settings_t* track_settings )
        {
            k4a_result_t result = k4a_record_add_custom_subtitle_track( m_handle, track_name, codec_id, codec_context, codec_context_size, track_settings );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to add custom subtitle track!" );
            }
        }

        void add_custom_video_track( const char* track_name, const char* codec_id, const uint8_t* codec_context, const size_t codec_context_size, const k4a_record_video_settings_t* track_settings )
        {
            k4a_result_t result = k4a_record_add_custom_video_track( m_handle, track_name, codec_id, codec_context, codec_context_size, track_settings );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to add custom video track!" );
            }
        }

        void add_attachment( const char* attachment_name, const uint8_t* buffer, const size_t buffer_size )
        {
            k4a_result_t result = k4a_record_add_attachment( m_handle, attachment_name, buffer, buffer_size );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to add attachment!" );
            }
        }

        void add_imu_track()
        {
            k4a_result_t result = k4a_record_add_imu_track( m_handle );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to add imu_track!" );
            }
        }

        void add_tag( const char* name, const char* value )
        {
            k4a_result_t result = k4a_record_add_tag( m_handle, name, value );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to add tag!" );
            }
        }

        static record create( const char* path, const k4a::device& device, const k4a_device_configuration_t& device_configuration )
        {
            k4a_record_t handle = nullptr;
            k4a_result_t result = k4a_record_create( path, device.handle(), device_configuration, &handle );

            if( K4A_RESULT_SUCCEEDED != result )
            {
                throw error( "Failed to create recorder!" );
            }

            return record( handle );
        }

    private:
        k4a_record_t m_handle;
    };

} // namespace k4a

#endif