123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #include "Cues.h"
- #include "read.h"
- #include "global_elements.h"
- nsmkv::CuePoint *nsmkv::Cues::GetCuePoint(uint64_t when, uint64_t current_time, int seek_direction)
- {
- CuePoint *last=0;
- CuePoints::iterator itr;
- for (itr=cue_points.begin(); itr!=cue_points.end();itr++)
- {
- CuePoint *cue_point = itr->second;
- if (cue_point->cue_time == when)
- {
- if (seek_direction != SEEK_FORWARD || current_time < cue_point->cue_time)
- return cue_point;
- }
- else if (cue_point->cue_time > when)
- {
- if (last)
- {
- if (seek_direction != SEEK_FORWARD || current_time < last->cue_time)
- return last;
- }
- else
- return cue_point;
- }
- last = cue_point;
- }
- return last; // will be 0 if we don't have any cue points, which is what we want.
- }
- nsmkv::CueTrackPosition *nsmkv::CuePoint::GetPosition(uint64_t track)
- {
- CueTrackPositions::iterator found = cue_track_positions.find(track);
- if (found != cue_track_positions.end())
- return found->second;
- else
- return 0;
- }
- // returns bytes read. 0 means EOF
- static uint64_t ReadCueTrackPositions(nsmkv::MKVReader *reader, uint64_t size, nsmkv::CueTrackPosition &track_position)
- {
- 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_cuetrackpositions_cuetrack:
- {
- uint64_t val;
- if (read_unsigned(reader, node.size, &val) == 0)
- return 0;
- track_position.track = val;
- #ifdef WA_VALIDATE
- printf(" Cue Track: %I64u\n", val);
- track_position.track_found = true;
- #endif
- }
- break;
- case mkv_cuetrackpositions_cueclusterposition:
- {
- uint64_t val;
- if (read_unsigned(reader, node.size, &val) == 0)
- return 0;
- track_position.cluster_position = val;
- #ifdef WA_VALIDATE
- printf(" Cue Cluster Position: %I64u\n", val);
- track_position.cluster_position_found = true;
- #endif
- }
- break;
- default:
- nsmkv::ReadGlobal(reader, node.id, node.size);
- }
- }
- return total_bytes_read;
- }
- // returns bytes read. 0 means EOF
- static uint64_t ReadCuePoint(nsmkv::MKVReader *reader, uint64_t size, nsmkv::CuePoint &cue_point)
- {
- 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_cuepoint_cuetime:
- {
- uint64_t val;
- if (read_unsigned(reader, node.size, &val) == 0)
- return 0;
- cue_point.cue_time = val;
- #ifdef WA_VALIDATE
- printf(" Cue Time: %I64u\n", val);
- cue_point.cue_time_found = true;
- #endif
- }
- break;
- case mkv_cuepoint_cuetrackpositions:
- {
- #ifdef WA_VALIDATE
- printf(" Cue Track Positions\n");
- #endif
- nsmkv::CueTrackPosition *track_position = new nsmkv::CueTrackPosition;
- if (ReadCueTrackPositions(reader, node.size, *track_position) == 0)
- {
- delete track_position;
- return 0;
- }
- cue_point.cue_track_positions[track_position->track] = track_position;
- }
- break;
- default:
- nsmkv::ReadGlobal(reader, node.id, node.size);
- }
- }
- return total_bytes_read;
- }
- // returns bytes read. 0 means EOF
- uint64_t nsmkv::ReadCues(nsmkv::MKVReader *reader, uint64_t size, nsmkv::Cues &cues)
- {
- 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_cues_cuepoint:
- {
- #ifdef WA_VALIDATE
- printf(" Cue Point\n");
- #endif
- CuePoint *cue_point = new CuePoint;
- if (ReadCuePoint(reader, node.size, *cue_point) == 0)
- {
- delete cue_point;
- return 0;
- }
- cues.cue_points[cue_point->cue_time] = cue_point;
- }
- break;
- default:
- ReadGlobal(reader, node.id, node.size);
- }
- }
- return total_bytes_read;
- }
|