first commit

This commit is contained in:
2026-02-21 17:11:31 +09:00
commit 18b4338361
4001 changed files with 365464 additions and 0 deletions

View File

@@ -0,0 +1,263 @@
#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