+++ /dev/null
-#include <stdio.h>\r
-#include "stdafx.h"\r
-#include "Help.h"\r
-#include "EditMain.h"\r
-#include "debug.h"\r
-\r
-\r
-void EditMain(T_EDIT_PARAM *prm){\r
-\r
- GF_Err e;\r
- T_MP4_INFO mi;\r
- T_TS_LIST *ts = NULL;\r
- T_TS_LIST *tsSort = NULL;\r
-\r
- // \8f\89\8aú\89»\r
- gf_sys_init();\r
-\r
- ZeroMemory(&mi, sizeof(T_MP4_INFO));\r
-\r
- // \83^\81[\83Q\83b\83g\83t\83@\83C\83\8b\82Ì\83I\81[\83v\83\93\r
- mi.fp_in = gf_isom_open(prm->p_infile, GF_ISOM_OPEN_READ, NULL);\r
- printf("\93ü\97Í\83t\83@\83C\83\8b... [%s]\n\n", prm->p_infile);\r
-\r
- mi.i_trackCount = gf_isom_get_track_count(mi.fp_in);\r
- \r
- // \8ae\83g\83\89\83b\83N\82Ì\83t\83H\81[\83}\83b\83g\82ð\8eæ\93¾\r
- u32 lst4CC[] = {GF_ISOM_BRAND_AVC1, GF_ISOM_BRAND_MP4V, GF_ISOM_BRAND_XVID};\r
- SearchTrackOf4CC(&mi, lst4CC, 3);\r
-\r
- // \96Ú\93I\82Ì\83g\83\89\83b\83N\82ª\8c©\82Â\82©\82ç\82È\82©\82Á\82½\8fê\8d\87\81B\r
- if (mi.i_trackNo == NULL){\r
- ErrorMessage(MSG_NO_4CC);\r
- goto _ERROR_RET;\r
- }\r
-\r
- // \83T\83\93\83v\83\8b\90\94\82Ì\8eæ\93¾\r
- mi.ui_sampleCount = gf_isom_get_sample_count(mi.fp_in, mi.i_trackNo);\r
- if(mi.ui_sampleCount < 3){\r
- ErrorMessage(MSG_NO_SAMPLE);\r
- goto _ERROR_RET;\r
- }\r
-\r
- ts = new T_TS_LIST[mi.ui_sampleCount + 1];\r
- ZeroMemory(ts, sizeof(T_TS_LIST) * mi.ui_sampleCount);\r
-\r
- // \83T\83\93\83v\83\8b\8fî\95ñ\82ð\8eæ\93¾\82µ\81A\83f\83B\83\8c\83C\83t\83\8c\81[\83\80\94»\92è\81ECTS\8f\87\82É\95À\82Ñ\91Ö\82¦\r
- printf("\83T\83\93\83v\83\8b\8fî\95ñ\8eæ\93¾\92\86...\n");\r
- if(readTsFromFile(&mi, ts))\r
- goto _ERROR_RET;\r
-\r
- // \83s\83N\83`\83\83\95\\8e¦\8f\87\82Å\83\\81[\83g\r
- tsSort = new T_TS_LIST[mi.ui_sampleCount + 1];\r
- memcpy(tsSort, ts, sizeof(T_TS_LIST) * mi.ui_sampleCount);\r
- qsort(tsSort, mi.ui_sampleCount, sizeof(T_TS_LIST), (int(*)(const void*, const void*))CompareTS_PTS);\r
-\r
- // \8dÅ\8fI\83t\83\8c\81[\83\80\82ÌFPS\95â\8a®\r
- u32 i = mi.ui_sampleCount;\r
- tsSort[i].DTS = ts[i-1].DTS + (ts[i-1].DTS - ts[i-2].DTS);\r
- tsSort[i].CTS_Offset = 0;\r
- tsSort[i].CTS = tsSort[i-1].CTS + (tsSort[i-1].CTS - tsSort[i-2].CTS);\r
- tsSort[i].PTS = tsSort[i-1].PTS + (tsSort[i-1].PTS - tsSort[i-2].PTS);\r
- tsSort[i].samples = i+1;\r
-\r
- // \83^\83C\83\80\83X\83P\81[\83\8b\82Ì\8eæ\93¾\r
- mi.i_org_timescale = (int)gf_isom_get_media_timescale(mi.fp_in, mi.i_trackNo);\r
-\r
- // \82±\82Ì\95Ó\82Å\83\82\81[\83h\95ª\8aò\r
- if(prm->i_mode == MODE_IN){\r
- // \83^\83C\83\80\83R\81[\83h\93ü\97Í\r
-\r
- // \8dÅ\8f¬\83t\83\8c\81[\83\80\83\8c\81[\83g\8eæ\93¾\r
- mi.i_org_timerate = getMinimumPTSDiff(&mi, tsSort);\r
- if(prm->i_timerate <= 0) {\r
- int rate = gcd(mi.i_org_timescale, mi.i_org_timerate);\r
- prm->i_timerate = mi.i_org_timerate / rate;\r
- }\r
-\r
- // TimeCode V2 \82Ì\8eæ\82è\8d\9e\82Ý\r
- if (prm->i_tcv == 1){\r
- if(readTimeCodeFromFileV1(&mi, tsSort, prm))\r
- goto _ERROR_RET;\r
- } else if(prm->i_tcv == 2){\r
- if(readTimeCodeFromFile(&mi, tsSort, prm))\r
- goto _ERROR_RET;\r
- } else {\r
- goto _ERROR_RET;\r
- }\r
-\r
- // \92x\89\84\83t\83\8c\81[\83\80\90\94\8eæ\93¾\r
- if(prm->i_delayFrame < 0) {\r
- prm->i_delayFrame = getDelayFlame(&mi, ts);\r
- }\r
- mi.i_delayFrame = prm->i_delayFrame;\r
- mi.i_initDelay = mi.i_delayFrame * (int)(getAveragePTSDiff(&mi, tsSort) / (double)prm->i_timerate + 0.5) * prm->i_timerate;\r
-\r
- // \8c\8b\89Ê\82ð\83R\83s\81[\82µ\82Ä\83s\83N\83`\83\83\8f\87\82É\83\\81[\83g\r
- memcpy(ts, tsSort, sizeof(T_TS_LIST) * mi.ui_sampleCount);\r
- qsort(ts, mi.ui_sampleCount, sizeof(T_TS_LIST), (int(*)(const void*, const void*))CompareTS_Sample);\r
-\r
-\r
- // \8fî\95ñ\82Ì\95\\8e¦\r
- printf("\n");\r
- printf("--- input ---\n");\r
- printf("TimeScale \81F%d\n", mi.i_org_timescale);\r
- printf("TimeRate \81F%d\n", mi.i_org_timerate);\r
- printf("Sample Count \81F%d\n", mi.ui_sampleCount);\r
- printf("Delay Frame \81F%d\n", mi.i_delayFrame);\r
- printf("Delay Time \81F%d\n", mi.i_initDelay);\r
- printf("\n");\r
- printf("--- output ---\n");\r
- printf("TimeScale \81F%d\n", prm->i_timescale);\r
- printf("TimeRate \81F%d\n", prm->i_timerate);\r
- printf("Multiple \81F%lf\n", prm->f_scaleFct);\r
- printf("\n");\r
- printf("\83t\83@\83C\83\8b\8fo\97Í\92\86... [%s]\n", prm->p_outfile);\r
-\r
- u32 readDscIdx = 0;\r
- u32 destTrack = 0;\r
- mi.fp_out = gf_isom_open(prm->p_outfile, GF_ISOM_OPEN_WRITE, NULL);\r
-\r
-\r
- // \8fo\97Í\8aJ\8en\r
- for (int trackIdx=1; trackIdx<=mi.i_trackCount; trackIdx++){\r
- // \83g\83\89\83b\83N\82Ì\83R\83s\81[\r
- gf_isom_clone_track(mi.fp_in, trackIdx, mi.fp_out, true, &destTrack);\r
- // edts\82Ì\8dí\8f\9c\r
- gf_isom_remove_edit_segments(mi.fp_out, destTrack);\r
-\r
- if (trackIdx != mi.i_trackNo){\r
- u32 sampleCount = gf_isom_get_sample_count(mi.fp_in, trackIdx);\r
- for(u32 i=1; i<=sampleCount; i++){\r
- printf("... %5.1f%%\r", (double)i/(double)sampleCount * 100.0);\r
- GF_ISOSample *sample = gf_isom_get_sample(mi.fp_in, trackIdx, i, &readDscIdx);\r
- e = gf_isom_add_sample(mi.fp_out, destTrack, readDscIdx, sample);\r
- gf_isom_sample_del(&sample);\r
- }\r
-\r
- } else {\r
- // \83^\83C\83\80\83X\83P\81[\83\8b\90Ý\92è\r
- e = gf_isom_set_media_timescale(mi.fp_out, destTrack, (u32)prm->i_timescale);\r
- if(e)\r
- printf("!!! \83^\83C\83\80\83X\83P\81[\83\8b\90Ý\92è\8e¸\94s : %d !!!\n", e);\r
-\r
- // DTS\82ð\90Ý\92è\82µ\8fo\97Í\r
- s64 before_dts = -1;\r
- int delta_time = int((prm->i_timerate * prm->f_scaleFct) / (mi.i_delayFrame*2));\r
-\r
- if(delta_time < 1 && prm->b_dc){\r
- ErrorMessage(MSG_MORE_SMALL_TIMERATE);\r
- break;\r
- }\r
-\r
- for(u32 i=0; i<mi.ui_sampleCount; i++){\r
- printf("... %5.1f%%\r", (double)i/(double)mi.ui_sampleCount * 100.0);\r
-\r
- s64 cts = 0;\r
- s64 dts = 0;\r
- int offset = 0;\r
- int dts_delay = 0;\r
- int cts_delay = 0;\r
- int ts_diff = 0;\r
-\r
- cts = ts[i].PTS;\r
- if(!prm->b_dc){\r
- dts_delay = 0;\r
- cts_delay = mi.i_initDelay;\r
- } else {\r
- for(u32 k=MAX(0, i - mi.i_delayFrame); k<i; k++)\r
- ts_diff += (int)(tsSort[k + 1].PTS - tsSort[k].PTS);\r
-\r
- dts_delay = MAX(mi.i_initDelay, ts_diff);\r
- cts_delay = 0;\r
- }\r
-\r
- if(dts_delay < tsSort[i].PTS)\r
- dts = tsSort[i].PTS - dts_delay;\r
-\r
- // \91O\89ñ\82ÌDTS\82æ\82è\82à\92l\82Í\91å\82«\82\82È\82¯\82ê\82Î\82È\82ç\82È\82¢\81B\r
- if(dts <= before_dts)\r
- dts = before_dts + delta_time;\r
-\r
- // CTS_Offset\82Ì\8eZ\8fo\r
- offset = (int)(cts - dts + cts_delay);\r
-\r
- // \83I\83t\83Z\83b\83g\82Ì\8cv\8eZ\82Å\95\89\82É\82È\82Á\82Ä\82µ\82Ü\82Á\82½\8fê\8d\87\r
- if (offset < 0){\r
- dts += offset;\r
- offset = 0;\r
- }\r
-\r
- ts[i].DTS = before_dts = dts;\r
- ts[i].CTS_Offset = offset;\r
-\r
- // \83`\83F\83b\83N\r
- if( (dts + (s64)offset - (s64)ts[0].CTS_Offset) != cts )\r
- printf("!!! \95\\8e¦\83^\83C\83~\83\93\83O\83G\83\89\81[ / Track:%d Frame:%d Target PTS:%I64d (DTS:%I64d, CTS_Offset:%d, Delay:%d) !!!\n", destTrack, i+1, cts, dts, offset, ts[0].CTS_Offset);\r
-\r
- GF_ISOSample *sample = gf_isom_get_sample(mi.fp_in, mi.i_trackNo, i+1, &readDscIdx);\r
- sample->DTS = ts[i].DTS;\r
- sample->CTS_Offset = ts[i].CTS_Offset;\r
- e = gf_isom_add_sample(mi.fp_out, destTrack, readDscIdx, sample);\r
-\r
- if(e)\r
- printf("!!! \83T\83\93\83v\83\8b\8f\91\82«\8d\9e\82Ý\83G\83\89\81[ / Track:%d Frame:%d DTS:%I64d, CTS_Offset:%d Err:%d !!!\n", destTrack, i+1, sample->DTS, sample->CTS_Offset, e);\r
- gf_isom_sample_del(&sample);\r
- }\r
-\r
- // edts\82Ì\91}\93ü\r
- //GF_ISOSample *sample = gf_isom_get_sample_info(mi.fp_out, destTrack, 1, NULL, NULL);\r
- //if(sample->CTS_Offset > 0){\r
- // u64 trackDur = gf_isom_get_track_duration(mi.fp_out, destTrack);\r
- // gf_isom_remove_edit_segments(mi.fp_out, destTrack);\r
- // gf_isom_append_edit_segment(mi.fp_out, destTrack, trackDur, sample->CTS_Offset, GF_ISOM_EDIT_NORMAL);\r
- //}\r
- //gf_isom_sample_del(&sample);\r
- }\r
-\r
- printf("... %d\83g\83\89\83b\83N\8fo\97Í\8fI\97¹\n", trackIdx);\r
- }\r
-\r
- // \8fo\97Í\83t\83@\83C\83\8b\82ð\95Â\82¶\82é\r
- gf_isom_clone_pl_indications(mi.fp_in, mi.fp_out);\r
- gf_isom_clone_root_od(mi.fp_in, mi.fp_out);\r
-\r
- u64 duration = gf_isom_get_duration(mi.fp_out);\r
- gf_isom_make_interleave(mi.fp_out, 0.5);\r
- gf_isom_close(mi.fp_out);\r
-\r
- }\r
- else if (prm->i_mode == MODE_OUT){\r
- // TIMECODE\82Ì\8fo\97Í\r
- if(prm->i_tcv == 2){\r
- FILE *fpout;\r
- if((fpout = fopen(prm->p_outfile, "wb")) != NULL){\r
- fprintf(fpout, "# timecode format v2\r\n");\r
- for(u32 i=0; i<mi.ui_sampleCount; i++){\r
- fprintf(fpout, "%.6lf\r\n", (double)tsSort[i].PTS / (double)mi.i_org_timescale * 1000.0);\r
- }\r
- }\r
- fclose(fpout);\r
- printf("... timecode format v2 \8fo\97Í\8fI\97¹\n");\r
- }\r
- else if(prm->i_tcv == 1){\r
- FILE *fpout;\r
- if((fpout = fopen(prm->p_outfile, "wb")) != NULL){\r
- fprintf(fpout, "# timecode format v1\r\n");\r
- fprintf(fpout, "Assume %.6lf\r\n", getMaximumFps(&mi, tsSort));\r
- u32 stpos = 0;\r
- double fps = 0.0;\r
- double beforFps = (double)mi.i_org_timescale/(double)(tsSort[1].PTS - tsSort[0].PTS);\r
- for(u32 i=0; i<mi.ui_sampleCount; i++){\r
- fps = (double)mi.i_org_timescale/(double)(tsSort[i+1].PTS - tsSort[i].PTS);\r
- if (fps != beforFps){\r
- fprintf(fpout, "%d,%d,%.6lf\r\n",stpos, i-1, beforFps);\r
- beforFps = fps;\r
- stpos = i;\r
- }\r
- }\r
- if(stpos <= mi.ui_sampleCount - 1){\r
- fprintf(fpout, "%d,%d,%.6lf\r\n",stpos, mi.ui_sampleCount - 1, fps);\r
- }\r
- }\r
- fclose(fpout);\r
- printf("... timecode format v1 \8fo\97Í\8fI\97¹\n");\r
- } else {\r
- goto _ERROR_RET;\r
- }\r
- }\r
-\r
-\r
-_ERROR_RET:\r
-\r
- // \83t\83@\83C\83\8b\82ð\95Â\82¶\82Ä\8fI\97¹\r
- gf_isom_close(mi.fp_in);\r
-\r
- if(ts) delete [] ts;\r
- if(tsSort) delete [] tsSort;\r
- // \8dÅ\8fI\r
- gf_sys_close();\r
-}\r
-\r