Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
235
Src/nsmkv/SegmentInfo.cpp
Normal file
235
Src/nsmkv/SegmentInfo.cpp
Normal file
|
@ -0,0 +1,235 @@
|
|||
#include "SegmentInfo.h"
|
||||
#include "read.h"
|
||||
#include "global_elements.h"
|
||||
#include <time.h>
|
||||
#include <TCHAR.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int FileExists(const char * filename);
|
||||
|
||||
// returns bytes read. 0 means EOF
|
||||
uint64_t nsmkv::ReadSegmentInfo(nsmkv::MKVReader *reader, uint64_t size, nsmkv::SegmentInfo &segment_info)
|
||||
{
|
||||
uint64_t total_bytes_read=0;
|
||||
while (size)
|
||||
{
|
||||
ebml_node node;
|
||||
uint64_t bytes_read = read_ebml_node(reader, &node);
|
||||
|
||||
if (bytes_read == 0)
|
||||
return 0;
|
||||
|
||||
// benski> checking bytes_read and node.size separately prevents possible integer overflow attack
|
||||
if (bytes_read > size)
|
||||
return 0;
|
||||
total_bytes_read+=bytes_read;
|
||||
size-=bytes_read;
|
||||
|
||||
if (node.size > size)
|
||||
return 0;
|
||||
total_bytes_read+=node.size;
|
||||
size-=node.size;
|
||||
|
||||
switch(node.id)
|
||||
{
|
||||
case mkv_segmentinfo_timecodescale:
|
||||
{
|
||||
uint64_t val;
|
||||
if (read_unsigned(reader, node.size, &val) == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Time Code Scale: %I64u\n", val);
|
||||
segment_info.time_code_scale_found = true;
|
||||
#endif
|
||||
segment_info.time_code_scale = val;
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_muxingapp:
|
||||
{
|
||||
char *utf8 = 0;
|
||||
if (node.size && read_utf8(reader, node.size, &utf8) == 0)
|
||||
return 0;
|
||||
if (utf8)
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Muxing App: %s\n", utf8);
|
||||
segment_info.muxing_app_found = true;
|
||||
#endif
|
||||
segment_info.Own(segment_info.muxing_app, utf8);
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_writingapp:
|
||||
{
|
||||
char *utf8 = 0;
|
||||
if (node.size && read_utf8(reader, node.size, &utf8) == 0)
|
||||
return 0;
|
||||
if (utf8)
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Writing App: %s\n", utf8);
|
||||
segment_info.writing_app_found = true;
|
||||
#endif
|
||||
segment_info.Own(segment_info.writing_app, utf8);
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_duration:
|
||||
{
|
||||
double val;
|
||||
if (read_float(reader, node.size, &val) == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Duration: %g\n", val);
|
||||
segment_info.duration_found = true;
|
||||
#endif
|
||||
segment_info.duration = val;
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_dateutc:
|
||||
{
|
||||
uint64_t val;
|
||||
if (read_unsigned(reader, node.size, &val) == 0)
|
||||
return 0;
|
||||
|
||||
segment_info.production_date = val;
|
||||
// value is in nanoseconds, relative to jan 01, 2001. ugh
|
||||
|
||||
__time64_t val_time = mkv_date_as_time_t(val);
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Date UTC: %s", _ctime64(&val_time));
|
||||
segment_info.production_date_found = true;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_segmentuid:
|
||||
{
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Segment UID: binary size %I64u\n", node.size);
|
||||
segment_info.segment_uid_found = true;
|
||||
#endif
|
||||
if (node.size == 16)
|
||||
{
|
||||
size_t bytes_read;
|
||||
reader->Read(&segment_info.segment_uid, (size_t)node.size, &bytes_read);
|
||||
if (bytes_read != node.size)
|
||||
return 0;
|
||||
}
|
||||
else // bad size, let's just skip it
|
||||
{
|
||||
reader->Skip(node.size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_prevuid:
|
||||
{
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Previous UID: binary size %I64u\n", node.size);
|
||||
segment_info.prev_uid_found = true;
|
||||
#endif
|
||||
if (node.size == 16)
|
||||
{
|
||||
size_t bytes_read;
|
||||
reader->Read(&segment_info.prev_uid, (size_t)node.size, &bytes_read);
|
||||
if (bytes_read != node.size)
|
||||
return 0;
|
||||
}
|
||||
else // bad size, let's just skip it
|
||||
{
|
||||
reader->Skip(node.size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_nextuid:
|
||||
{
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Next Segment UID: binary size %I64u\n", node.size);
|
||||
segment_info.next_uid_found = true;
|
||||
#endif
|
||||
if (node.size == 16)
|
||||
{
|
||||
size_t bytes_read;
|
||||
reader->Read(&segment_info.next_uid, (size_t)node.size, &bytes_read);
|
||||
if (bytes_read != node.size)
|
||||
return 0;
|
||||
}
|
||||
else // bad size, let's just skip it
|
||||
{
|
||||
reader->Skip(node.size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_title:
|
||||
{
|
||||
char *utf8 = 0;
|
||||
if (read_utf8(reader, node.size, &utf8) == 0)
|
||||
return 0;
|
||||
if (utf8)
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Title: %s\n", utf8);
|
||||
segment_info.title_found = true;
|
||||
#endif
|
||||
segment_info.Own(segment_info.title, utf8);
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_prevfilename:
|
||||
{
|
||||
char *utf8 = 0;
|
||||
if (read_utf8(reader, node.size, &utf8) == 0)
|
||||
return 0;
|
||||
if (utf8)
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Previous Filename: %s\n", utf8);
|
||||
segment_info.prev_filename_found = true;
|
||||
if (FileExists(segment_info.prev_filename) != 0)
|
||||
{
|
||||
printf("****Specified previous filename not found");
|
||||
}
|
||||
#endif
|
||||
segment_info.Own(segment_info.prev_filename,utf8);
|
||||
}
|
||||
break;
|
||||
case mkv_segmentinfo_nextfilename:
|
||||
{
|
||||
char *utf8 = 0;
|
||||
if (read_utf8(reader, node.size, &utf8) == 0)
|
||||
return 0;
|
||||
if (utf8)
|
||||
#ifdef WA_VALIDATE
|
||||
printf(" Next Filename: %s\n", utf8);
|
||||
segment_info.next_filename_found = true;
|
||||
if (FileExists(segment_info.next_filename) != 0)
|
||||
{
|
||||
printf("****Specified next filename not found");
|
||||
}
|
||||
#endif
|
||||
segment_info.Own(segment_info.next_filename, utf8);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
nsmkv::ReadGlobal(reader, node.id, node.size);
|
||||
}
|
||||
}
|
||||
return total_bytes_read;
|
||||
}
|
||||
|
||||
int nsmkv::SegmentInfo::GetDurationMilliseconds() const
|
||||
{
|
||||
double nanoseconds = (double)time_code_scale * duration;
|
||||
double microseconds = nanoseconds / 1000.0;
|
||||
double milliseconds = microseconds / 1000.0;
|
||||
return (int)milliseconds;
|
||||
}
|
||||
|
||||
uint64_t nsmkv::SegmentInfo::ConvertMillisecondsToTime(int milliseconds) const
|
||||
{
|
||||
double time_code = (double)milliseconds * 1000000.0 / (double)time_code_scale;
|
||||
return (uint64_t)time_code;
|
||||
}
|
||||
|
||||
int FileExists(const char * filename) {
|
||||
int iStat;
|
||||
struct _stat64 fileInfo;
|
||||
|
||||
// get the file attributes
|
||||
return (iStat = _stat64(filename,&fileInfo));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue