2,543
社区成员
发帖
与我相关
我的任务
分享
#pragma once
#include "stdio.h"
#pragma pack(push, 1)
struct RMF{
char type[4];
unsigned int size;
short version;
unsigned int fileversion;
unsigned int headNum;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct PROP
{
char object_id[4];
unsigned int size;
short object_version;
unsigned int max_bit_rate;
unsigned int avg_bit_rate;
unsigned int max_packet_size;
unsigned int avg_packet_size;
unsigned int num_packets;
unsigned int duration;
unsigned int preroll;
unsigned int index_offset;
unsigned int data_offset;
short num_streams;
short flags;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct INDEXHEAD
{
char object_id[4];
unsigned int size;
//unsigned char size[4];
short object_version;
unsigned int num_indices;
short stream_number;
unsigned int next_index_header;
};
struct INDEXRECORD
{
short object_version;
unsigned int timestamp;
unsigned int offset;
unsigned int packet_count_for_this_packet;
};
struct DATAHEAD{
char object_id[4];
unsigned int size;
short object_version;
unsigned int num_indices;
unsigned int next_date_header;
};
struct DATARECORD
{
short version;
short size;
short stream_number;
unsigned int timestamp;
char packet_group;
char flags;
};
#pragma pack(pop)
class RMMF
{
void changePoint(void * p, int size)
{
char * pt;
pt = (char *)p;
int size2 = size / 2;
for(int i = 0; i < size2; i++)
{
char temp = pt[i];
pt[i] = pt[size - i - 1];
pt[size - i - 1] = temp;
}
}
public:
RMF* head;
PROP * prop;
INDEXHEAD *indexHead;
INDEXHEAD indexHead2;
RMMF(void)
{
file = NULL;
}
~RMMF(void)
{
if (file != NULL)
fclose(file);
}
// 获得一个数据头
DATAHEAD * GetHead(int offset)
{
DATAHEAD *ret = NULL;
fseek(file, offset, SEEK_SET);
char * buf = new char[sizeof(DATAHEAD)];
int size = fread(buf, sizeof(char), sizeof(char) * sizeof(DATAHEAD), file);
if (size == sizeof(DATAHEAD))
{
ret = (DATAHEAD*)buf;
changePoint(&ret->size, 4);
changePoint(&ret->object_version, 2);
changePoint(&ret->num_indices, 4);
changePoint(&ret->next_date_header, 4);
}
return ret;
}
DATARECORD* GetDataRecord(int offset, int num)
{
DATARECORD *ret = NULL;
fseek(file, offset, SEEK_SET);
char * buf = new char[sizeof(DATARECORD)];
int size = fread(buf, sizeof(char), sizeof(char) * sizeof(DATARECORD), file);
if (size == sizeof(DATARECORD))
{
ret = (DATARECORD*)buf;
changePoint(&ret->version, 2);
changePoint(&ret->size, 2);
changePoint(&ret->stream_number, 2);
changePoint(&ret->timestamp, 4);
}
return ret;
}
// 获得索引的所有数据
INDEXRECORD * GetIndexData(int num)
{
int bufLength = num * sizeof(INDEXRECORD);
char * buf = new char[bufLength];
int size = fread(buf, sizeof(char), bufLength, file);
if (size != bufLength)
{
printf("index data read error!");
return NULL;
}
for(int i = 0; i < num; i++)
{
INDEXRECORD * record = (INDEXRECORD * )(buf + sizeof(INDEXRECORD) * i);
changePoint(&record->object_version, 2);
changePoint(&record->offset, 4);
changePoint(&record->packet_count_for_this_packet, 4);
changePoint(&record->timestamp, 4);
}
return (INDEXRECORD *)buf;
}
void doIndex()
{
int size = sizeof(INDEXHEAD);
char * buf = new char[size];
fseek(file, prop->index_offset, SEEK_SET);
size = fread(buf, sizeof(char), sizeof(char) * sizeof(INDEXHEAD), file);
if (size == sizeof(INDEXHEAD))
{
indexHead = (INDEXHEAD*)buf;
changePoint(&indexHead->size, 4);
changePoint(&indexHead->object_version, 2);
changePoint(&indexHead->num_indices, 4);
changePoint(&indexHead->stream_number, 2);
changePoint(&indexHead->next_index_header, 4);
}
//{
// INDEXRECORD* indexData = this->GetIndexData(indexHead->num_indices);
fseek(file, indexHead->next_index_header, SEEK_SET);
if (fread(&indexHead2, sizeof(INDEXHEAD), 1, file) == 1)
{
changePoint(&indexHead2.size, 4);
changePoint(&indexHead2.object_version, 2);
changePoint(&indexHead2.num_indices, 4);
changePoint(&indexHead2.stream_number, 2);
changePoint(&indexHead2.next_index_header, 4);
}
{
INDEXRECORD* indexData = this->GetIndexData(indexHead2.num_indices);
double start = 0.0;
int i = 0;
for(; i < indexHead2.num_indices; i++)
{
printf("%d ms offset: %d packet:%d \n ", indexData[i].timestamp, indexData[i].offset, indexData[i].packet_count_for_this_packet);
DATARECORD * data= this->GetDataRecord(indexData[i].offset, 1);
printf("%d ms: version: %d size: %d stream_number: %d packet_group: %d flags: %d \n ",
data->timestamp, data->version, data->size, data->stream_number,
data->packet_group, data->flags);
//printf("\"D:\\Program Files\\Real\\Helix Producer Plus\\RealMediaEditor\\rmeditor.exe\" -i \"1.rmvb\" -o \"o%d.rmvb\" -s \"%f\" -e \"%f\"\n", i + 1, start, record->timestamp / 1000.0);
//start = record->timestamp / 1000.0 - 0.01;
}
}
//printf("\"D:\\Program Files\\Real\\Helix Producer Plus\\RealMediaEditor\\rmeditor.exe\" -i \"1.rmvb\" -o \"o%d.rmvb\" -s \"%f\"\n", i + 1, start);
}
FILE * file;
bool open(const char * fileName)
{
file = fopen(fileName, "rb");
this->head = new RMF();
int size = sizeof(RMF);
char * buf = new char[size];
size = fread(buf, sizeof(char), sizeof(char) * sizeof(RMF), file);
if (size != sizeof(RMF))
{
fclose(file);
file = NULL;
return false;
}
else
{
head = (RMF*)buf;
changePoint(&head->size, 4);
changePoint(&head->version, 2);
changePoint(&head->fileversion, 4);
changePoint(&head->headNum, 4);
}
size = sizeof(PROP);
buf = new char[size];
size = fread(buf, sizeof(char), sizeof(char) * size, file);
if (size != sizeof(PROP))
{
fclose(file);
file = NULL;
return false;
}
else
{
prop = (PROP*)buf;
changePoint(&prop->size, 4);
changePoint(&prop->object_version, 2);
changePoint(&prop->max_bit_rate, 4);
changePoint(&prop->avg_bit_rate, 4);
changePoint(&prop->max_packet_size, 4);
changePoint(&prop->avg_packet_size, 4);
changePoint(&prop->num_packets, 4);
changePoint(&prop->duration, 4);
changePoint(&prop->preroll, 4);
changePoint(&prop->index_offset, 4);
changePoint(&prop->data_offset, 4);
changePoint(&prop->num_streams, 2);
changePoint(&prop->flags, 2);
this->doIndex();
DATAHEAD * dataHead = this->GetHead(prop->data_offset);
int offset = prop->data_offset + sizeof(DATAHEAD);
for(int i = 0; i < dataHead->num_indices; i++)
{
DATARECORD * data = this->GetDataRecord(offset, 1);
printf("%d ms: version: %d size: %d stream_number: %d packet_group: %d flags: %d \n ",
data->timestamp, data->version, data->size, data->stream_number,
data->packet_group, data->flags);
offset += data->size;
}
DATAHEAD * dataHead2 = this->GetHead(dataHead->next_date_header);
printf("%d %d", dataHead->num_indices, dataHead->size);
}
return true;
}
};