OSDN Git Service

stop using trunk directory in rectool
[rec10/rec10-git.git] / tstools / DtsEdit / src / common.cpp
1 #include "stdafx.h"\r
2 #include "help.h"\r
3 #include "debug.h"\r
4 \r
5 // \8dÅ\91å\8cö\96ñ\90\94\82Ì\8eæ\93¾\r
6 int gcd( int a, int b) {\r
7     while (1) {\r
8         int c = a % b;\r
9         if( !c )\r
10             return b;\r
11         a = b;\r
12         b = c;\r
13     }\r
14 }\r
15 \r
16 int CompareU64(const u64 *a, const u64 *b)\r
17 {\r
18         s64 diff = (s64)(*a - *b);\r
19         return (diff > 0 ? 1: diff == 0 ? 0: -1);\r
20 }\r
21 \r
22 int CompareTS_PTS(const T_TS_LIST *a, const T_TS_LIST *b)\r
23 {\r
24         s64 diff = (s64)(a->PTS - b->PTS);\r
25         return (diff > 0 ? 1: diff == 0 ? 0: -1);\r
26 }\r
27 \r
28 int CompareTS_Sample(const T_TS_LIST *a, const T_TS_LIST *b)\r
29 {\r
30         int diff = (int)(a->samples - b->samples);\r
31         return (diff > 0 ? 1: diff == 0 ? 0: -1);\r
32 }\r
33 \r
34 \r
35 int SearchTrackOf4CC(T_MP4_INFO *mi, u32 *List4CC, int ListCount){\r
36         u32     tgTrack = NULL;\r
37         u32 tg4CC = NULL;\r
38         for (int i = 1; i <= mi->i_trackCount; i++){\r
39                 tg4CC = gf_isom_get_media_subtype(mi->fp_in, i, 1);\r
40                 if (tg4CC == GF_ISOM_SUBTYPE_MPEG4)\r
41                         tg4CC = gf_isom_get_mpeg4_subtype(mi->fp_in, i, 1);\r
42 \r
43                 DPRINTF("FOUR CC %s \r\n", gf_4cc_to_str(tg4CC));\r
44 \r
45                 for (s32 k=0; k<ListCount; k++){\r
46                         if (tg4CC == List4CC[k]){\r
47                                 tgTrack = i;\r
48                                 break;\r
49                         }\r
50                 }\r
51 \r
52                 if (tgTrack){\r
53                         mi->i_trackNo = tgTrack;\r
54                         mi->ui_4cc = tg4CC;\r
55                         break;\r
56                 }\r
57         }\r
58 \r
59         return 0;\r
60 }\r
61 \r
62 \r
63 int readTsFromFile(T_MP4_INFO *mi, T_TS_LIST *ts){\r
64         int ret = 0;\r
65 \r
66         for(u32 i=0; i<mi->ui_sampleCount; i++){\r
67                 GF_ISOSample *sample = gf_isom_get_sample_info(mi->fp_in, mi->i_trackNo, i+1, NULL, NULL);\r
68 \r
69                 if(!sample){\r
70                         ret = ErrorMessage(MSG_NO_SAMPLE);\r
71                         break;\r
72                 }\r
73 \r
74                 ts[i].DTS                       = sample->DTS;\r
75                 ts[i].CTS_Offset        = sample->CTS_Offset;\r
76                 ts[i].CTS                       = sample->DTS + sample->CTS_Offset;\r
77                 ts[i].PTS                       = ts[i].CTS - ts[0].CTS_Offset;\r
78                 ts[i].samples           = i+1;\r
79                 gf_isom_sample_del(&sample);\r
80         }\r
81 \r
82         return ret;\r
83 }\r
84 \r
85 \r
86 int getDelayFlame(T_MP4_INFO *mi, T_TS_LIST *ts){\r
87         int delay = 0;\r
88         int maxDelay = 0;\r
89         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
90                 if(ts[i-1].CTS > ts[i].CTS){\r
91                         delay++;\r
92                         maxDelay = MAX(maxDelay, delay);\r
93                 } else {\r
94                         delay = 0;\r
95                 }\r
96         }\r
97 \r
98         return maxDelay;\r
99 }\r
100 \r
101 \r
102 int getMinimumPTSDiff(T_MP4_INFO *mi, T_TS_LIST *ts){\r
103         int min_diff = INT_MAX;\r
104         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
105                 int diff = (int)(ts[i].PTS - ts[i-1].PTS);\r
106                 min_diff = MIN(min_diff, diff);\r
107         }\r
108         return min_diff;\r
109 }\r
110 \r
111 int getMaximumPTSDiff(T_MP4_INFO *mi, T_TS_LIST *ts){\r
112         int max_diff = 0;\r
113         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
114                 int diff = (int)(ts[i].PTS - ts[i-1].PTS);\r
115                 max_diff = MAX(max_diff, diff);\r
116         }\r
117         return max_diff;\r
118 }\r
119 \r
120 double getAveragePTSDiff(T_MP4_INFO *mi, T_TS_LIST *ts){\r
121         double avr_diff = 0.0;\r
122         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
123                 double diff = (double)(ts[i].PTS - ts[i-1].PTS);\r
124                 avr_diff += diff / (double)(mi->ui_sampleCount-1);\r
125         }\r
126         return avr_diff;\r
127 }\r
128 \r
129 double getAverageFps(T_MP4_INFO *mi, T_TS_LIST *ts){\r
130         double base_fps = (double)mi->i_org_timescale / (double)(ts[1].PTS - ts[0].PTS);\r
131         double sum_fps = 0;\r
132         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
133                 sum_fps += ((double)mi->i_org_timescale / (double)(ts[i].PTS - ts[i-1].PTS)) - base_fps;\r
134         }\r
135         return ((sum_fps / (double)mi->ui_sampleCount) + base_fps);\r
136 }\r
137 \r
138 double getMaximumFps(T_MP4_INFO *mi, T_TS_LIST *ts){\r
139         double max_fps = 0;\r
140         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
141                 double fps = (double)mi->i_org_timescale / (double)(ts[i].PTS - ts[i-1].PTS);\r
142                 max_fps = MAX(max_fps, fps);\r
143         }\r
144         return max_fps;\r
145 }\r
146 \r
147 \r
148 \r
149 int readTimeCodeFromFile(T_MP4_INFO *mi, T_TS_LIST *ts, T_EDIT_PARAM *prm){\r
150         FILE *fpin;\r
151         int err = 0;\r
152 \r
153         if((fpin = fopen(prm->p_tcfile, "rb")) != NULL){\r
154                 printf("timecode\8eæ\8d\9e\92\86...\n");\r
155 \r
156                 char buf1[256], buf2[256], buf3[256], buf4[256];\r
157 \r
158                 /* read header */\r
159                 fscanf(fpin, "%s %s %s %s", buf1, buf2, buf3, buf4);\r
160                 if(     _stricmp(buf2, "timecode") != 0 ||\r
161                         _stricmp(buf3, "format") != 0 ||\r
162                         _stricmp(buf4, "v2") != 0\r
163                 ){\r
164                         err = ErrorMessage(MSG_NO_V2);\r
165                 } else {\r
166                         u32             i                       = 0;\r
167                         double  timeStamp       = 0;\r
168                         bool    enough          = false;\r
169                         double  *timeList       = new double[mi->ui_sampleCount];\r
170 \r
171                         // \83t\83@\83C\83\8b\82ð\93Ç\82Ý\8d\9e\82Ý\r
172                         while( fscanf(fpin, "%lf", &timeStamp) != EOF ){\r
173                                 timeList[i] = timeStamp;\r
174                                 i++;\r
175                                 if (mi->ui_sampleCount <= i){\r
176                                         enough = true;\r
177                                         break;\r
178                                 }\r
179                         }\r
180 \r
181                         if (!enough) {\r
182                                 err = ErrorMessage(MSG_NO_ENOUGH_FRAME);\r
183                         } else {\r
184 \r
185                                 double min_timeStamp = INT_MAX;\r
186                                 // \8dÅ\8f¬\83^\83C\83~\83\93\83O\82ð\8eæ\93¾\r
187                                 for(i=0; i<mi->ui_sampleCount - 1; i++){\r
188                                         double tmp = timeList[i+1] - timeList[i];\r
189                                         if(tmp > 0.0){\r
190                                                 int true_fps = (int)((double)prm->i_timerate / tmp + 0.5);\r
191                                                 if( true_fps > 0)\r
192                                                         tmp = (double)prm->i_timerate / (double)(true_fps);\r
193                                         }\r
194                                         min_timeStamp = MIN(min_timeStamp, tmp);\r
195                                 }\r
196                                 // \83G\83\89\81[\89ñ\94ð\r
197                                 double max_fps = 1000.0 / MAX(min_timeStamp, 1.0);\r
198                                 int timescale = int(max_fps * (double)prm->i_timerate * prm->f_mlt + 0.5);\r
199 \r
200                                 // timescale\96¢\8ew\92è\82Ì\8fê\8d\87\r
201                                 if(prm->i_timescale <= 0){\r
202                                         prm->i_timescale = timescale;\r
203                                         prm->f_scaleFct = prm->f_mlt;\r
204                                 } else {\r
205                                         prm->f_scaleFct = ((double)prm->i_timescale / (double)timescale) * prm->f_mlt;\r
206                                 }\r
207 \r
208                                 double timerate = prm->i_timerate;\r
209                                 if (prm->f_scaleFct < 1.0)\r
210                                         timerate = timerate * prm->f_scaleFct;\r
211 \r
212                                 for(i=0; i<mi->ui_sampleCount; i++){\r
213                                         ts[i].PTS = u64( u64((double)prm->i_timescale * (timeList[i] / 1000.0) / timerate + 0.5) * timerate + 0.5);\r
214                                         ts[i].CTS = ts[i].PTS;\r
215                                 }\r
216                         }\r
217 \r
218                         delete [] timeList;\r
219                 }\r
220         }\r
221         fclose(fpin);\r
222         return err;\r
223 }\r
224 \r
225 int readTimeCodeFromFileV1(T_MP4_INFO *mi, T_TS_LIST *ts, T_EDIT_PARAM *prm){\r
226         FILE *fpin;\r
227         int err = 0;\r
228 \r
229         if((fpin = fopen(prm->p_tcfile, "rb")) != NULL){\r
230                 printf("timecode\8eæ\8d\9e\92\86...\n");\r
231 \r
232                 char buf1[256], buf2[256], buf3[256], buf4[256];\r
233 \r
234                 /* read header */\r
235                 fscanf(fpin, "%s %s %s %s", buf1, buf2, buf3, buf4);\r
236                 if(     _stricmp(buf2, "timecode") != 0 ||\r
237                         _stricmp(buf3, "format") != 0 ||\r
238                         _stricmp(buf4, "v1") != 0\r
239                 ){\r
240                         err = ErrorMessage(MSG_NO_V1);\r
241                 } else {\r
242                         double AssumeFps;\r
243                         fscanf(fpin, "%s %lf",buf1, &AssumeFps);\r
244                         if(     _stricmp(buf1, "Assume") != 0)\r
245                                 err = ErrorMessage(MSG_NO_V1);\r
246                         else {\r
247                                 double  fps;\r
248                                 u32             st;\r
249                                 u32             ed;\r
250                                 s64             beforeCount = 0;\r
251                                 bool    enough          = false;\r
252                                 double  *fpsList        = new double[mi->ui_sampleCount];\r
253 \r
254 \r
255                                 while( fscanf(fpin, "%d,%d,%lf", &st, &ed, &fps) != EOF ){\r
256                                         \r
257                                         for(u32 i=st+1; i<=ed+1; i++){\r
258                                                 if ((beforeCount + 1) != i){\r
259                                                         err = ErrorMessage(MSG_LOST_FRAME);\r
260                                                         break;\r
261                                                 }\r
262                                                 beforeCount = i;\r
263                                                 fpsList[i] = fps;\r
264 \r
265                                                 if (mi->ui_sampleCount <= i+1)\r
266                                                         break;\r
267                                         }\r
268                                         if (mi->ui_sampleCount <= ed+1){\r
269                                                 enough = true;\r
270                                                 break;\r
271                                         }\r
272                                 }\r
273                                 if (!enough) {\r
274                                         err = ErrorMessage(MSG_NO_ENOUGH_FRAME);\r
275                                 } else {\r
276 \r
277                                         double max_fps = 0.1;\r
278                                         // \8dÅ\91åfps\82ð\8eæ\93¾\r
279                                         for(u32 i=0; i<mi->ui_sampleCount; i++){\r
280                                                 max_fps = MAX(max_fps, fpsList[i]);\r
281                                         }\r
282                                         int timescale = int(max_fps * (double)prm->i_timerate * prm->f_mlt + 0.5);\r
283 \r
284                                         // timescale\96¢\8ew\92è\82Ì\8fê\8d\87\r
285                                         if(prm->i_timescale <= 0){\r
286                                                 prm->i_timescale = timescale;\r
287                                                 prm->f_scaleFct = prm->f_mlt;\r
288                                         } else {\r
289                                                 prm->f_scaleFct = ((double)prm->i_timescale / (double)timescale) * prm->f_mlt;\r
290                                         }\r
291 \r
292                                         double timerate = prm->i_timerate;\r
293                                         if (prm->f_scaleFct < 1.0)\r
294                                                 timerate = timerate * prm->f_scaleFct;\r
295 \r
296                                         // \90æ\93ª\82Í0\8cÅ\92è\r
297                                         ts[0].PTS = 0;\r
298                                         ts[0].CTS = 0;\r
299                                         for(u32 i=1; i<mi->ui_sampleCount; i++){\r
300                                                 ts[i].PTS = ts[i-1].PTS + u64( u64(((double)prm->i_timescale / (fpsList[i] * timerate)) + 0.5) * timerate + 0.5);\r
301                                                 ts[i].CTS = ts[i].PTS;\r
302                                         }\r
303                                 }\r
304                         }\r
305                 }\r
306         }\r
307         fclose(fpin);\r
308         return err;\r
309 }\r
310 \r
311 \r