📄 video_file_creator.c
字号:
if (g_video_enc_status.FSAL_STATUS != FSAL_OK)
{
VIDEO_ASSERT(0);
g_video_enc_status.FSAL_ERROR_FILE = &mp4_files.MEDIA_META_FILE;
return FSAL_ERROR;
}
g_video_enc_status.FSAL_STATUS = FSAL_Read(&mp4_files.MEDIA_META_FILE, (kal_uint8 *)&vos_length, 4);
if (g_video_enc_status.FSAL_STATUS != FSAL_OK)
{
VIDEO_ASSERT(0);
g_video_enc_status.FSAL_ERROR_FILE = &mp4_files.MEDIA_META_FILE;
return FSAL_ERROR;
}
for (i = 0; i < file_creat_struct->frame_number - 1; i++)
{
result = mpeg4_get_frame_timestamp_from_meta_file(i + 1, vos_length, &temp);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
stts_time = (temp - temp_prev);
if ((stts_time & 0xf0000000) != 0) /*impossible happen, if happen, fix tricky bug,*/
stts_time = pre_duration;
*duration += stts_time;
pre_duration = stts_time;
temp_prev = temp;
}
}
return MEDIA_STATUS_OK;
}
MEDIA_STATUS_CODE video_enc_check_meta_file_is_enough(STFSAL * video_file, STFSAL * meta_file, STFSAL * audio_file)
{
kal_uint32 file_size;
kal_uint32 video_file_size;
MEDIA_STATUS_CODE result;
kal_uint32 vos_length;
kal_uint32 total_frames;
if ((video_file == NULL) || (meta_file == NULL))
{
g_video_enc_status.VIDEO_STATUS = VIDEO_ENC_FILE_CANT_MERGE;
VIDEO_ASSERT(0);
return VIDEO_ERROR;
}
g_video_enc_status.FSAL_STATUS = FSAL_GetFileSize(video_file, &video_file_size);
if (g_video_enc_status.FSAL_STATUS != FSAL_OK)
{
VIDEO_ASSERT(0);
g_video_enc_status.FSAL_ERROR_FILE = video_file;
return FSAL_ERROR;
}
g_video_enc_status.FSAL_STATUS = FSAL_GetFileSize(meta_file, &file_size);
if (g_video_enc_status.FSAL_STATUS != FSAL_OK)
{
VIDEO_ASSERT(0);
g_video_enc_status.FSAL_ERROR_FILE = meta_file;
return FSAL_ERROR;
}
if ((file_size >= 0x18) && (video_file_size > 0x20))
{
result = video_enc_get_vos_length(meta_file, &vos_length);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
file_size = file_size - ((vos_length + 0x18 + 3) / 4) * 4;
total_frames = file_size / 8;
if (total_frames < 1)
{
g_video_enc_status.VIDEO_STATUS = VIDEO_ENC_FILE_CANT_MERGE;
VIDEO_ASSERT(0);
return VIDEO_ERROR;
}
}
else
{
g_video_enc_status.VIDEO_STATUS = VIDEO_ENC_FILE_CANT_MERGE;
VIDEO_ASSERT(0);
return VIDEO_ERROR;
}
return MEDIA_STATUS_OK;
}
MEDIA_STATUS_CODE video_enc_generate_META_file(MP4_FILE_CREATE_STRUCT * file_creat_struct, STFSAL * real_meta_file, MP4_FILE_INFO * video_file_info)
{
t_rtc test_time;
kal_uint32 i;
kal_uint32 temp;
kal_uint32 create_time;
kal_uint32 duration;
kal_uint32 mp4_file_pos;
kal_uint32 avg_frame_lentgh;
MEDIA_STATUS_CODE result;
kal_uint32 length_tmp;
kal_uint32 temp_prev;
kal_uint32 pre_duration = 0;
kal_uint32 stts_time;
kal_uint32 stts_count;
kal_uint32 stts_entry_count;
kal_uint32 stts_entry_addr;
#if 0
/* under construction !*/
#endif
if (file_creat_struct->frame_number < 1)
{
g_video_enc_status.VIDEO_STATUS = VIDEO_ENC_FILE_CANT_MERGE;
VIDEO_ASSERT(0);
return VIDEO_ERROR;
}
test_time.rtc_year = 4;
test_time.rtc_mon = 2;
test_time.rtc_day = 15;
test_time.rtc_hour = 12;
test_time.rtc_min = 5;
test_time.rtc_sec = 5;
if (file_creat_struct->time_scale <= file_creat_struct->frame_rate)
{
VIDEO_ASSERT(0);
g_video_enc_status.VIDEO_STATUS = VIDEO_ENC_NOT_SUPPORT;
return VIDEO_ERROR;
}
/*Initialize*/
for (i = 0; i < MAX_ATOM_TYPE_NUMBER; i++)
{
video_file_info->FC_ATOM[i].pos = 0xffffffff;
}
mp4_file_pos = 0;
/** mdat **/
mp4_crt_write_int(mp4_file_pos, 0x2E, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "mdat", 4, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x01808080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0E118080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x8009051F, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0F808080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x020001C0, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x10126104, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x1FC00000, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x1FC00000, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x44282282, real_meta_file);
mp4_crt_write_short(mp4_file_pos, 0x9F80, real_meta_file);
//moov size
video_file_info->FC_ATOM[moov].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "moov", 4, real_meta_file);
/* moov->mvhd size*/
mp4_crt_write_int(mp4_file_pos, 0x6c, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "mvhd", 4, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); //version + flags
create_time = mpeg4_cratetime_translate(&test_time);
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //create time,just for test
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //modification time, just for test
mp4_crt_write_int(mp4_file_pos, file_creat_struct->time_scale, real_meta_file); //time scale
result = video_enc_get_total_duration(file_creat_struct, &duration);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
file_creat_struct->total_duration = (kal_uint32)VIDEO_ANYBASE_TO_MS(duration, file_creat_struct->time_scale);
mp4_crt_write_int(mp4_file_pos, duration, real_meta_file); //duration
mp4_crt_write_int(mp4_file_pos, 0x00010000, real_meta_file);
mp4_crt_write_short(mp4_file_pos, 0x0100, real_meta_file);
// mp4_crt_write_zero_group(mp4_file_pos,16,real_meta_file);
mp4_crt_write_zero_group(mp4_file_pos, 10, real_meta_file);
pre_defined_hr(&mp4_file_pos, real_meta_file);
mp4_crt_write_zero_group(mp4_file_pos, 24, real_meta_file);
if (file_creat_struct->short_header == 0)
{
mp4_crt_write_int(mp4_file_pos, 0x04, real_meta_file);
}
else
{
mp4_crt_write_int(mp4_file_pos, 0x10000, real_meta_file);
}
/** moov->iods **/
if (file_creat_struct->short_header == 0)
{
mp4_crt_write_int(mp4_file_pos, 0x2A, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "iods", 4, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x10808080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x19004FFF, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0xFFFF03FF, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0E808080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x04000000, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x020E8080, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x80040000, real_meta_file);
mp4_crt_write_short(mp4_file_pos, 0x0003, real_meta_file);
}
/** moov->video trak **/
video_file_info->FC_ATOM[trak].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "trak", 4, real_meta_file);
/** moov->trak->tkhd **/
mp4_crt_write_int(mp4_file_pos, 0x5c, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "tkhd", 4, real_meta_file);
if (file_creat_struct->short_header == 0)
{
mp4_crt_write_int(mp4_file_pos, 0x1, real_meta_file);
} // version+flag
else
{
mp4_crt_write_int(mp4_file_pos, 0x7, real_meta_file);
} // version+flag
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //create time
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //modification time
mp4_crt_write_int(mp4_file_pos, 1, real_meta_file); //Track ID
mp4_crt_write_int(mp4_file_pos, 0, real_meta_file); //Reserved
mp4_crt_write_int(mp4_file_pos, duration, real_meta_file);
mp4_crt_write_zero_group(mp4_file_pos, 16, real_meta_file);
result = pre_defined_hr(&mp4_file_pos, real_meta_file);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
if (file_creat_struct->short_header == 0)
{
mp4_crt_write_int(mp4_file_pos, 0x01400000, real_meta_file); //Pre-defined
mp4_crt_write_int(mp4_file_pos, 0x00f00000, real_meta_file); //Pre-defined
}
else
{
mp4_crt_write_int(mp4_file_pos, file_creat_struct->frame_width << 16, real_meta_file); //Pre-defined
mp4_crt_write_int(mp4_file_pos, file_creat_struct->frame_height << 16, real_meta_file); //Pre-defined
}
/** moov->trak->mdia **/
video_file_info->FC_ATOM[mdia].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "mdia", 4, real_meta_file);
/** moov->trak->mdhd **/
mp4_crt_write_int(mp4_file_pos, 0x20, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "mdhd", 4, real_meta_file);
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); // version+flag
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //create time
mp4_crt_write_int(mp4_file_pos, file_creat_struct->create_time, real_meta_file); //modification time
mp4_crt_write_int(mp4_file_pos, file_creat_struct->time_scale, real_meta_file); //time scale
mp4_crt_write_int(mp4_file_pos, duration, real_meta_file); //time duration
if (file_creat_struct->short_header == 0)
{
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file); // language+quality
}
else
{
mp4_crt_write_int(mp4_file_pos, 0x55C40000, real_meta_file); // language+quality
}
/** moov->trak->hdlr **/
mp4_crt_write_int(mp4_file_pos, 0x21, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "hdlr", 4, real_meta_file);
mp4_crt_write_zero_group(mp4_file_pos, 8, real_meta_file); //predefined, component type
mp4_crt_write_char_group(mp4_file_pos, "vide", 4, real_meta_file);
mp4_crt_write_zero_group(mp4_file_pos, 13, real_meta_file); //reserved
/** moov->trak->minf **/
video_file_info->FC_ATOM[minf].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0x0, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "minf", 4, real_meta_file);
/** moov->trak->minf->vmhd **/
mp4_crt_write_int(mp4_file_pos, 20, real_meta_file); //size
mp4_crt_write_char_group(mp4_file_pos, "vmhd", 4, real_meta_file); //vmhd
mp4_crt_write_int(mp4_file_pos, 1, real_meta_file); // version+flag
mp4_crt_write_zero_group(mp4_file_pos, 8, real_meta_file); //Predefined
/** moov->trak->minf->dinf **/
mp4_crt_write_int(mp4_file_pos, 36, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "dinf", 4, real_meta_file); //dinf
mp4_crt_write_int(mp4_file_pos, 0x01C, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "dref", 4, real_meta_file); //dref
mp4_crt_write_int(mp4_file_pos, 0, real_meta_file); // version+flag
mp4_crt_write_int(mp4_file_pos, 1, real_meta_file); // number of entries
mp4_crt_write_int(mp4_file_pos, 12, real_meta_file); //size
mp4_crt_write_char_group(mp4_file_pos, "url ", 4, real_meta_file); //type = url
mp4_crt_write_int(mp4_file_pos, 1, real_meta_file); // version+flag
/** moov->trak->minf->stbl **/
video_file_info->FC_ATOM[stbl].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "stbl", 4, real_meta_file); //stbl
/** moov->trak->minf->stbl->stsd **/
video_file_info->FC_ATOM[stsd].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0, real_meta_file);
mp4_crt_write_char_group(mp4_file_pos, "stsd", 4, real_meta_file); //stsd
mp4_crt_write_int(mp4_file_pos, 0, real_meta_file); //version, flags
mp4_crt_write_int(mp4_file_pos, 1, real_meta_file); //number of entries
if (file_creat_struct->short_header == 0)
{
kal_uint32 max_frame_length;
kal_uint32 frame_length_sum_per_second;
video_file_info->FC_ATOM[s263].pos = 0xffffffff;
video_file_info->FC_ATOM[mp4v].pos = mp4_file_pos;
mp4_crt_write_int(mp4_file_pos, 0xad, real_meta_file); //<==position??
mp4_crt_write_char_group(mp4_file_pos, "mp4v", 4, real_meta_file);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -