264 lines
6.7 KiB
C++
264 lines
6.7 KiB
C++
#ifndef RM_FORMAT_AVI_H
|
|
#define RM_FORMAT_AVI_H
|
|
|
|
#if (FILE_FORMAT_AVI)
|
|
|
|
#if !defined(BBEXTRACT)
|
|
#include "../rm_include.h"
|
|
#include <QString>
|
|
#endif
|
|
#include "rm_format.h"
|
|
|
|
|
|
#pragma once
|
|
|
|
#include <stdio.h>
|
|
#include <vector>
|
|
#include <stdint.h>
|
|
|
|
#ifdef _MSC_VER
|
|
#define strncasecmp _strnicmp
|
|
#define strcasecmp _stricmp
|
|
#endif
|
|
|
|
extern "C" {
|
|
#include "fileio.h"
|
|
}
|
|
|
|
// DEBUG 용
|
|
#define DEBUG_AVI_FORMAT 0
|
|
#define USE_AVI_DUMP 0
|
|
#define DEBUG_AVI_JUNK 0
|
|
#define DEBUG_AVI_INFO 0
|
|
#define DEBUG_AVI_HEADER 0 // 메인헤더
|
|
#define DEBUG_AVI_STREAM_HEADER 0 // 스트림 헤더
|
|
#define DEBUG_AVI_MOVI 0 // 스트림 데이터 리스트
|
|
|
|
// http://www.econote.co.kr/main/view_post.asp?post_seq_no=49407 정리 잘 되어 있음
|
|
// AVI RIFF 구조는
|
|
// RIFF
|
|
// - hdrl(LIST)
|
|
// - avih : AVI 파일 전체 기본 정보
|
|
// - strl (LIST)
|
|
// - strh (vids) : 영상 스트림 헤더
|
|
// - strf " 포멧
|
|
// - strl (LIST)
|
|
// - strh (auds) : 음성 스트림 헤더
|
|
// - strf " 포멧
|
|
// - strl (LIST)
|
|
// - strh (txts) : 자막 스트림 헤더
|
|
// - strf " 포멧
|
|
// - IDIT
|
|
// - INFO(LIST) : 정보
|
|
// -ISFT : 업체정보
|
|
// - movi(LIST) : 실제 데이터
|
|
// - 00dc/b : 음성패킷 (c:압축,b:비압축)
|
|
// - 00wb/c : 영상패킷 (")
|
|
// - 00tx : 자막
|
|
// - idx1: 프레임의 위치 (binary 로 01wb,flag,offset,size ..... 00dc,flat,offset,size..
|
|
|
|
#define MAX_VIDEO_STREAM_COUNT 4
|
|
|
|
// TimeScale 등이 0 라 재생시간 처리에 문제가 생김
|
|
|
|
// avi 정보 (AVI Header,'avih')
|
|
typedef struct _AVIHeader
|
|
{
|
|
int TimeBetweenFrames;
|
|
int MaximumDataRate;
|
|
int PaddingGranularity;
|
|
int Flags;
|
|
int TotalNumberOfFrames;
|
|
int NumberOfInitialFrames;
|
|
int NumberOfStreams;
|
|
int SuggestedBufferSize;
|
|
int Width;
|
|
int Height;
|
|
int TimeScale;
|
|
int DataRate;
|
|
int StartTime;
|
|
int DataLength;
|
|
} AVIHeader;
|
|
|
|
// str(eam) 정보 (Stream Header,'strh') / Video('vids')
|
|
typedef struct _STRHeader
|
|
{
|
|
char DataType[5];
|
|
char DataHandler[5];
|
|
int Flags;
|
|
int Priority;
|
|
int InitialFrames;
|
|
int TimeScale;
|
|
int DataRate;
|
|
int StartTime;
|
|
int DataLength;
|
|
int SuggestedBufferSize;
|
|
int Quality;
|
|
int SampleSize;
|
|
|
|
} stream_header_t;
|
|
|
|
// str(eam) 포멧 (Stream Format,'strf') / Video('vids')
|
|
typedef struct _STRFormat
|
|
{
|
|
int header_size;
|
|
int image_width;
|
|
int image_height;
|
|
int number_of_planes;
|
|
int bits_per_pixel;
|
|
int compression_type;
|
|
int image_size_in_bytes;
|
|
int x_pels_per_meter;
|
|
int y_pels_per_meter;
|
|
int colors_used;
|
|
int colors_important;
|
|
int *palette;
|
|
|
|
} stream_format_t;
|
|
|
|
// str(eam) 정보 (Stream Header,'strh') / Audio('auds')
|
|
typedef struct _STRHeaderAudio
|
|
{
|
|
int format_type;
|
|
int number_of_channels;
|
|
int sample_rate;
|
|
int bytes_per_second;
|
|
int block_size_of_data;
|
|
int bits_per_sample;
|
|
int byte_count_extended;
|
|
|
|
}stream_header_auds_t;
|
|
|
|
// str(eam) 포멧 (Stream Format,'strf') / Video('auds')
|
|
typedef struct _STRFormatAudio
|
|
{
|
|
int header_size;
|
|
int format;
|
|
int channels;
|
|
int samples_per_second;
|
|
int bytes_per_second;
|
|
int block_size_of_data;
|
|
int bits_per_sample;
|
|
int extended_size;
|
|
|
|
} stream_format_auds_t;
|
|
|
|
// 인덱스 구조 ('idx1')
|
|
typedef struct _AVIDX
|
|
{
|
|
char ckid[5];
|
|
int dwFlags;
|
|
int dwChunkOffset;
|
|
int dwChunkLength;
|
|
} index_entry_t;
|
|
|
|
|
|
|
|
|
|
class AVIRiff
|
|
{
|
|
private:
|
|
VideoReadMode _readMode; // 현재 모드
|
|
VideoPreInfo* _preInfo; // 기본 정보 (존재할 경우 ReadMode == PreInfo)
|
|
bool _isValid; // 센서 관련?
|
|
|
|
|
|
public:
|
|
|
|
#if (SENSOR_AVI_SUBTITLE)
|
|
QList<char*>* subtitles; // 자막 센서 포멧
|
|
#endif
|
|
|
|
|
|
AVIRiff(RMfile in,VideoReadMode mode = VideoReadSensor, VideoPreInfo* info = NULL);
|
|
|
|
|
|
static bool duration(RMfile in,VideoPreInfo* info);
|
|
#if (CHECK_VIDEO_BITRATE)
|
|
static bool movSize(RMfile in,VideoPreInfo* info);
|
|
#endif
|
|
~AVIRiff();
|
|
|
|
bool isValid()
|
|
{
|
|
return _isValid;
|
|
}
|
|
|
|
// MOV 크기와 재생시간 그리고 오디오 bitrate (kb/sec) 를 입력받아 mov bitrate 를 계산한다
|
|
#if (CHECK_VIDEO_BITRATE)
|
|
static int videoBitrate(VideoPreInfo* info, double audioBitrate = 256) {
|
|
|
|
const double kb = 1000.0; // 1024?
|
|
const double durationInSec = (double)(info->duration) / 1000.0;
|
|
double audioSize = durationInSec * audioBitrate * kb / 8.0; // kb SEC
|
|
double videoSize = (double)(info->movSize) - audioSize;
|
|
return videoSize * 8.0 / durationInSec / kb;
|
|
}
|
|
#endif
|
|
|
|
#if (AVI_CHUNHO_SENSOR_FORMAT_1)
|
|
uint8_t* _gps_buffer;
|
|
size_t _gps_buffer_size;
|
|
uint8_t* _sensor_buffer;
|
|
size_t _sensor_buffer_size;
|
|
|
|
void getChunckData(uint8_t** gps,size_t* gps_size,uint8_t** sensor,size_t* sensor_size)
|
|
{
|
|
*gps = _gps_buffer;
|
|
*sensor = _sensor_buffer;
|
|
*gps_size = _gps_buffer_size;
|
|
*sensor_size = _sensor_buffer_size;
|
|
}
|
|
#endif
|
|
typedef enum
|
|
{
|
|
UNDEFINED_STREAM = 0,
|
|
VIDEO_STREAM,
|
|
AUDIO_STREAM,
|
|
TXT_STREAM,
|
|
} AVI_STREAM_TYPE;
|
|
|
|
RMfile _file;
|
|
|
|
AVIHeader _avi_header; // 파일헤더
|
|
|
|
stream_header_t _audioStreamHeader;
|
|
stream_format_auds_t _audioStreamFormat;
|
|
|
|
int _videoStreamCount; // 현재까지 로딩된 입력된 스트림 인덱스
|
|
stream_header_t _videoStreamHeaders[MAX_VIDEO_STREAM_COUNT]; // N개
|
|
stream_format_t _videoStreamFormat[MAX_VIDEO_STREAM_COUNT];
|
|
|
|
stream_header_t _txtStreamHeader; // TXT 스트림 헤더
|
|
|
|
int parse_riff();
|
|
int hex_dump_chunk(int chunk_len);
|
|
|
|
#if (DEBUG_AVI_FORMAT)
|
|
int parse_idx1(int chunk_len);
|
|
#endif
|
|
|
|
int read_avi_header(); // 메인 헤더
|
|
|
|
#if (SENSOR_AVI_SUBTITLE)
|
|
int add_subtitle(long chunkSize); // 자막 처리
|
|
#endif
|
|
|
|
void print_data_handler(unsigned char *handler); // Data Handler 출력 (DEBUG)
|
|
|
|
int read_stream_header(stream_header_t *stream_header);
|
|
int read_stream_format(stream_format_t *stream_format);
|
|
int read_stream_format_auds(stream_format_auds_t *stream_format);
|
|
|
|
//int read_strd_format(long strdSize);
|
|
//int add_subtitle(long chunkSize);
|
|
|
|
int parse_hdrl(unsigned int size);
|
|
int parse_hdrl_list();
|
|
int parse_movi_list(unsigned int size);
|
|
|
|
};
|
|
|
|
#endif // #if (FILE_FORMAT_AVI)
|
|
#endif // RM_FORMAT_AVI_H
|