#ifndef RM_FORMAT_MOV_H #define RM_FORMAT_MOV_H #if (FILE_FORMAT_MOV) // 기본정보(duration + bitrate) 읽기 + 센서 파서 // 기존 mov_reader.h/cpp + rm_mov_format.h/cpp 통합 버전 #if !defined(BBEXTRACT) #include "../rm_include.h" #include #endif #include "rm_format.h" extern "C" { #include "fileio.h" } #include // 최대 tag 탐색 깊이 #define RM_MOV_MAX_DEPTH 10 // 마지막 탐색된 tag 의 최대 크기 (eg. 3개 trak 에서 mdia->stbl->stsd stsd 가 text 인 tag 탐색시 #if(RM_MODEL == RM_MODEL_TYPE_TB4000 || RM_MODEL == RM_MODEL_TYPE_MH9000) #define RM_MOV_MAX_TAG_VALUE_SIZE 100 #else // 4000 #define RM_MOV_MAX_TAG_VALUE_SIZE 10 #endif // 4000 #if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22) typedef struct _GPS0 { double lat; // 0 double lon; // 8 uint32_t alt; // 16 uint16_t speed; // 20 uint8_t year; // 22 uint8_t month; // 23 uint8_t day; // 24 uint8_t hour; // 25 uint8_t min; // 26 uint8_t sec; // 27 uint8_t degree; // 28 uint8_t status; // 29 uint8_t version; // 30 uint8_t reserved; } GPS0; #elif (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W || RM_MODEL == RM_MODEL_TYPE_BV2000) // #define SENSOR_INTERVAL 1 // 2초 간격으로 저장 // #define SENSOR_FPS 40 // " 40개씩 저장됨 #define MAX_SENSOR_FPS 40 #endif // RM_MODEL_TYPE_NX_DRW22 #if (RM_MODEL == RM_MODEL_TYPE_TB4000) //typedef struct GPSINFOCHUCKTIME_s //{ // unsigned char byYear; // < Years since 1900 // unsigned char byMon; // < Months since January - [0,11] // unsigned char byDay; // < Day of the month - [1,31] // unsigned char byHour; // < Hours since midnight - [0,23] // unsigned char byMin; // < Minutes after the hour - [0,59] // unsigned char bySec; // < Seconds after the minute - [0,59] //} GPSINFOCHUCKTIME; typedef struct _GPSINFOCHUCK_TELEBIT { double dwLat; //< Latitude in NDEG - +/-[degree][min].[sec/60] double dwLon; //< Longitude in NDEG - +/-[degree][min].[sec/60] long lAlt; //< Altitude in meter +-:under/below sea level unsigned short usSpeed; //< Speed unit: km/h unsigned char datetime[6]; // byYear(from 1900), byMon, byDay, byHour, byMin, bySec //GPSINFOCHUCKTIME sUTC; //< UTC of position unsigned char ubDirection; //< Clockwise degree from the North. unsigned char ubFlag; //< Check if the GPS data is valid; unsigned char ubVersion; //< Stuture Version unsigned char ubReserved; } GPSINFOCHUCK_TELEBIT; #endif // 4000 #if (RM_MODEL == RM_MODEL_TYPE_MH9000) #pragma pack(push, 1) typedef struct _gps_chunk_t { char header[4]; // id = "DVAL" unsigned short year; unsigned short mon; unsigned short mday; unsigned short hour; unsigned short min; unsigned short sec; char vehicle_id[16]; char driver_id[16]; char rec_type; // 0:normal, 1:event char event_gsensor; char event_smoke; char event_dsm; char flag_seat_b; char flag_side_b; char flag_wink_l; char flag_wink_r; char flag_foot_b; char flag_gron_b; char blank_a[2]; char flag_smoke; char flag_dsm; char blank_b[2]; unsigned short speed; unsigned short rpm; unsigned short gps_speed; char blank_c[2]; unsigned int latitude; // lat * 100000 unsigned int longitude; // long * 100000 unsigned short gx[10]; // (g x 100) 100ms x 10 = 1sec unsigned short gy[10]; // (g x 100) 100ms x 10 = 1sec unsigned short gz[10]; // (g x 100) 100ms x 10 = 1sec char fw_version[16]; long lAlt; /**< Altitude in meter +-:under/below sea level*/ unsigned char ubDirection; /**< Clockwise degree from the North.*/ } gps_chunk_t; #pragma pack(pop) #endif // MH9000 class MOVFormat { // 재생시간 및 bitrate parser private: VideoReadMode _readMode; // 현재 모드 VideoPreInfo* _preInfo; // 기본 정보 (존재할 경우 ReadMode == PreInfo) bool _isValid; // 센서 관련? // Python.. unsigned int _offset; RMfile _file; private: // parse 중지 bool _stop_parse; // 탐색할 tag 리스트 (최대 depth = 10) int _tag_count; long _tag_list[RM_MOV_MAX_DEPTH]; // 탐색 tag (depth) offset unsigned int _tag_offset_list[RM_MOV_MAX_DEPTH]; // 탐색 tag (depth) size long _tag_size_list[RM_MOV_MAX_DEPTH]; // 탐색 중 확인할 value (자막의 경우 track 중 value 가 txt 인지 확인해야함) char _tag_search_value[RM_MOV_MAX_TAG_VALUE_SIZE]; // 초기화 void init_parser(); void set_tags(const char* tag,...); // 현재 tag value 가 _tag_search_value 와 동일한지 확인 bool check_tag_value(long atom_type, unsigned int offset, long size); // 처음부터 끝까지 depth 0 에서 parse 시작 void parse_all(); // 센서 데이터만 parse //void parse_sensor(); // bitrate 만 parse #if !defined(BBEXTRACT) #if (CHECK_VIDEO_BITRATE) bool parse_bitrate(); #endif // CHECK_VIDEO_BITRATE void parse_avc1(long offset, long size); // H264 Video #endif // #if !defined(BBEXTRACT) bool parse_duration(); bool parse_sensor(); #if (RM_MODEL == RM_MODEL_TYPE_XLDR_88 || SUB_MODEL_CARROT_EMT) bool parse_buffer(uint8_t* buffer,long size); #endif // _tag 로 지정된 tag 의 옵셋 가져오기 void parse(unsigned int offset, unsigned int length, int depth = 0); unsigned int get_tag_list_offset(); #if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22) GPS0* _gps0; int16_t *_zyx; // 20201005 XYZ->ZYX 로 수정요청 #elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS || \ RM_MODEL == RM_MODEL_TYPE_BV2000 || \ RM_MODEL == RM_MODEL_TYPE_XLDR_88 || \ RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \ RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \ RM_MODEL == RM_MODEL_TYPE_FC_DR232W) void* _nmea; // NMEA INFO void* _sens; // _SEN #elif (RM_MODEL == RM_MODEL_TYPE_MH9000) gps_chunk_t* _sens; #elif (RM_MODEL_EMT_KR) void* _nmea; // NMEA INFO #endif #if (RM_MODEL != RM_MODEL_TYPE_MH9000 && !RM_MODEL_EMT_KR) int _gps0Count; #endif // _sens 에 통합 int _gsenCount; #if (RM_MODEL == RM_MODEL_TYPE_BV2000 ||\ RM_MODEL == RM_MODEL_TYPE_KEIYO1 ||\ RM_MODEL == RM_MODEL_TYPE_MBJ5010 ||\ RM_MODEL == RM_MODEL_TYPE_MH9000 || \ RM_MODEL == RM_MODEL_TYPE_FC_DR232W) int _sensorFPS; void process_subtitle(const char* subtitle); #elif (RM_MODEL_EMT_KR) void process_subtitle(const char* subtitle); #endif public: MOVFormat(RMfile in,VideoReadMode mode = VideoReadSensor, VideoPreInfo* info = NULL); static bool duration(RMfile in,VideoPreInfo* info); #if !defined(BBEXTRACT) #if (CHECK_VIDEO_BITRATE) static bool movSize(RMfile in,VideoPreInfo* info); #endif #endif // #if !defined(BBEXTRACT) ~MOVFormat(); #if (RM_MODEL_EMT_KR) QString modelName; #endif bool isValid() { return _isValid; } // MOV 크기와 재생시간 그리고 오디오 bitrate (kb/sec) 를 입력받아 mov bitrate 를 계산한다 #if (CHECK_VIDEO_BITRATE) static int videoBitrate(VideoPreInfo* info) { const double kb = 1000.0; // 1024? const double durationInSec = (double)(info->duration) / 1000.0; double videoSize = (double)(info->movSize); return videoSize * 8.0 / durationInSec / kb; } #endif #if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22) int getGPS(GPS0** gps) { *gps = _gps0; return _gps0Count; } int getSensor(int16_t** sensor) { *sensor = _zyx; return _gsenCount; } #elif (RM_MODEL_EMT_KR) int getNMEA(void** nmea) { *nmea = _nmea; return _gsenCount; } #elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS || \ RM_MODEL == RM_MODEL_TYPE_XLDR_88 || \ RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \ RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \ RM_MODEL == RM_MODEL_TYPE_BV2000 || \ RM_MODEL == RM_MODEL_TYPE_MH9000 | \ RM_MODEL == RM_MODEL_TYPE_FC_DR232W) // MH9000은 sensor 에 통합되어 있음 #if (RM_MODEL != RM_MODEL_TYPE_MH9000) int getGPS(void** nmea) { *nmea = _nmea; return _gps0Count; } #endif // int getSensor(void** sensor) { *sensor = _sens; return _gsenCount; } #if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \ RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \ RM_MODEL == RM_MODEL_TYPE_FC_DR232W || \ RM_MODEL == RM_MODEL_TYPE_BV2000 || \ RM_MODEL == RM_MODEL_TYPE_MH9000) int getSensorFPS() { return _sensorFPS; } #endif #elif (RM_MODEL == RM_MODEL_TYPE_TB4000) GPSINFOCHUCK_TELEBIT* _nmea; // NMEA INFO int getGPS(GPSINFOCHUCK_TELEBIT** nmea) { *nmea = _nmea; return _gps0Count; } #endif }; #endif // #if (FILE_FORMAT_MOV) #endif // RM_FORMAT_MOV_H