123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- #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));
- }
|