pub fn track_to_segments(trak: &TrackBox, segment_duration: Option<u32>) -> io::Result<Vec<Segment>> {
    let media = trak.media();
    let table = media.media_info().sample_table();
    let handler = media.handler();

    let timescale_ = media.media_header().timescale as f64;
    let timescale = timescale_ as f64;
    let comp_time_shift = trak.composition_time_shift().unwrap_or(0);
    let mut segment_duration = segment_duration.map(|d| ((d as u64 * timescale_ as u64) / 1000) as u32);

    let mut stts_iter = table.time_to_sample().iter();
    let mut ctss_iter = table.composition_time_to_sample().map(|ctts| ctts.iter());
    let mut stsz_iter = table.sample_size().iter();
    let mut stss_iter = match table.sync_samples() {
        Some(stss) => Some(stss.iter()),
        None => {
            println!("subtitles");
            if !handler.is_subtitle() {
                return Err(ioerr!(InvalidData, "track {}: no SyncSampleBox"));
            }
            segment_duration = None;
            None
        },
    };
    println!("stss_iter is {:?}", stss_iter.is_some());

    let mut segments = Vec::new();
    let mut cur_time = 0;
    let mut cur_seg_duration = 0u32;
    let mut cur_seg_size = 0u32;
    let mut cur_segment = Segment_::default();
    cur_segment.start_sample = 1;

    for cur_sample in 1..=u32::MAX {
        // FIXME? with fixed durations, only update delta on sync-frames?
        let delta = ctss_iter.as_mut().and_then(|iter| iter.next()).unwrap_or(0);

        let sample_duration = match stts_iter.next() {
            Some((d, _)) => d,
            None => {
                // No more samples, we're done. Finish the last segment.
                if cur_segment.start_sample > 0 && cur_seg_duration > 0 {
                    cur_segment.end_sample = cur_sample - 1;
                    cur_segment.duration = cur_seg_duration as f64 / timescale;
                    cur_segment.size = cur_seg_size;
                    segments.push(cur_segment.clone());
                }
                break;
            },
        };

        let sample_size = stsz_iter.next().unwrap_or(0);

        let mut is_sync = true;
        let do_next_seg = match segment_duration {
            Some(d) => cur_seg_duration >= d,
            None => {
                is_sync = if let Some(stss_iter) = stss_iter.as_mut() {
                    stss_iter.next().unwrap_or(false)
                } else {
                    // no stss iter? every sample is a sync sample.
                    true
                };
                if cur_seg_size + sample_size > MAX_SEGMENT_SIZE {
                    true
                } else {
                    is_sync
                }
            },
        };

        if do_next_seg || cur_sample == 1 {
            // A new segment starts here.
            if cur_sample > 1 {
                // Finish the previous segment and push it onto the vec.
                cur_segment.end_sample = cur_sample - 1;
                cur_segment.duration = cur_seg_duration as f64 / timescale;
                cur_segment.size = cur_seg_size;
                segments.push(cur_segment.clone());
            }
            cur_segment.start_sample = cur_sample;
            let tm = cur_time as i64 + (delta as i64) - (comp_time_shift as i64);
            let tm = std::cmp::max(0, tm);
            cur_segment.start_time = tm as f64 / timescale;
            cur_segment.is_sync = is_sync;
            cur_seg_duration = 0;
            cur_seg_size = 0;
        }
        cur_seg_duration += sample_duration;
        cur_seg_size += sample_size;
        cur_time += sample_duration;
    }

    Ok(squish(segments))
}
/// Parse a track into segments, each starting at a sync sample.
///
/// Returns an array with sample start/end, start time, and duration.
///
/// If `segment_duration` is `Some(milliseconds)`, we just create a new segment every
/// `segment_duration` milliseconds.
///
/// You use this to segment the video tracks into segments. The
/// resulting timing data can then be used to segment the audio
/// track(s) into segments with the exact same start_time and duration.
Parse a track into segments, each starting at a sync sample.
Returns an array with sample start/end, start time, and duration.



You use this to segment the video tracks into segments. The
resulting timing data can then be used to segment the audio
track(s) into segments with the exact same start_time and duration.
Parse a track into segments each starting at a sync sample . Returns an array with sample start / end start time and duration . You use this to segment the video tracks into segments . The resulting timing data can then be used to segment the audio track ( s ) into segments with the exact same start_time and duration .
pub fn track_to_segments(trak: &TrackBox, segment_duration: Option<u32>) -> io::Result<Vec<Segment>> {
    let media = trak.media();
    let table = media.media_info().sample_table();
    let handler = media.handler();
    let timescale_ = media.media_header().timescale as f64;
    let timescale = timescale_ as f64;
    let comp_time_shift = trak.composition_time_shift().unwrap_or(0);
    let mut segment_duration = segment_duration.map(|d| ((d as u64 * timescale_ as u64) / 1000) as u32);
    let mut stts_iter = table.time_to_sample().iter();
    let mut ctss_iter = table.composition_time_to_sample().map(|ctts| ctts.iter());
    let mut stsz_iter = table.sample_size().iter();
    let mut stss_iter = match table.sync_samples() {
        Some(stss) => Some(stss.iter()),
        None => {
            println!("subtitles");
            if !handler.is_subtitle() {
                return Err(ioerr!(InvalidData, "track {}: no SyncSampleBox"));
            }
            segment_duration = None;
            None
        },
    };
    println!("stss_iter is {:?}", stss_iter.is_some());
    let mut segments = Vec::new();
    let mut cur_time = 0;
    let mut cur_seg_duration = 0u32;
    let mut cur_seg_size = 0u32;
    let mut cur_segment = Segment_::default();
    cur_segment.start_sample = 1;
    for cur_sample in 1..=u32::MAX {
        // FIXME? with fixed durations, only update delta on sync-frames?
        let delta = ctss_iter.as_mut().and_then(|iter| iter.next()).unwrap_or(0);
        let sample_duration = match stts_iter.next() {
            Some((d, _)) => d,
            None => {
                // No more samples, we're done. Finish the last segment.
                if cur_segment.start_sample > 0 && cur_seg_duration > 0 {
                    cur_segment.end_sample = cur_sample - 1;
                    cur_segment.duration = cur_seg_duration as f64 / timescale;
                    cur_segment.size = cur_seg_size;
                    segments.push(cur_segment.clone());
                }
                break;
            },
        };
        let sample_size = stsz_iter.next().unwrap_or(0);
        let mut is_sync = true;
        let do_next_seg = match segment_duration {
            Some(d) => cur_seg_duration >= d,
            None => {
                is_sync = if let Some(stss_iter) = stss_iter.as_mut() {
                    stss_iter.next().unwrap_or(false)
                } else {
                    // no stss iter? every sample is a sync sample.
                    true
                };
                if cur_seg_size + sample_size > MAX_SEGMENT_SIZE {
                    true
                } else {
                    is_sync
                }
            },
        };
        if do_next_seg || cur_sample == 1 {
            // A new segment starts here.
            if cur_sample > 1 {
                // Finish the previous segment and push it onto the vec.
                cur_segment.end_sample = cur_sample - 1;
                cur_segment.duration = cur_seg_duration as f64 / timescale;
                cur_segment.size = cur_seg_size;
                segments.push(cur_segment.clone());
            }
            cur_segment.start_sample = cur_sample;
            let tm = cur_time as i64 + (delta as i64) - (comp_time_shift as i64);
            let tm = std::cmp::max(0, tm);
            cur_segment.start_time = tm as f64 / timescale;
            cur_segment.is_sync = is_sync;
            cur_seg_duration = 0;
            cur_seg_size = 0;
        }
        cur_seg_duration += sample_duration;
        cur_seg_size += sample_size;
        cur_time += sample_duration;
    }
    Ok(squish(segments))
}
pub fn track_to_segments ( trak : & TrackBox , segment_duration : Option < u32 > ) -> io :: Result < Vec < Segment > > { let media = trak . media ( ) ; let table = media . media_info ( ) . sample_table ( ) ; let handler = media . handler ( ) ; let timescale_ = media . media_header ( ) . timescale as f64 ; let timescale = timescale_ as f64 ; let comp_time_shift = trak . composition_time_shift ( ) . unwrap_or ( 0 ) ; let mut segment_duration = segment_duration . map ( | d | ( ( d as u64 * timescale_ as u64 ) / 1000 ) as u32 ) ; let mut stts_iter = table . time_to_sample ( ) . iter ( ) ; let mut ctss_iter = table . composition_time_to_sample ( ) . map ( | ctts | ctts . iter ( ) ) ; let mut stsz_iter = table . sample_size ( ) . iter ( ) ; let mut stss_iter = match table . sync_samples ( ) { Some ( stss ) => Some ( stss . iter ( ) ) , None => { println ! ( " " ) ; if ! handler . is_subtitle ( ) { return Err ( ioerr ! ( InvalidData " " ) ) ; } segment_duration = None ; None } , } ; println ! ( " " stss_iter is_some ( ) ) ; let mut segments = Vec :: new ( ) ; let mut cur_time = 0 ; let mut cur_seg_duration = 0u32 ; let mut cur_seg_size = 0u32 ; let mut cur_segment = Segment_ :: default ( ) ; cur_segment . start_sample = 1 ; for cur_sample in 1 ..= u32 :: MAX { // FIXME? with fixed durations, only update delta on sync-frames? let delta = ctss_iter . as_mut ( ) . and_then ( | iter | iter . next ( ) ) . unwrap_or ( 0 ) ; let sample_duration = match stts_iter . next ( ) { Some ( ( d , _ ) ) => d , None => { // No more samples, we're done. Finish the last segment. if cur_segment . start_sample > 0 && cur_seg_duration > 0 { cur_segment . end_sample = cur_sample - 1 ; cur_segment . duration = cur_seg_duration as f64 / timescale ; cur_segment . size = cur_seg_size ; segments . push ( cur_segment . clone ( ) ) ; } break ; } , } ; let sample_size = stsz_iter . next ( ) . unwrap_or ( 0 ) ; let mut is_sync = true ; let do_next_seg = match segment_duration { Some ( d ) => cur_seg_duration >= d , None => { is_sync = if let Some ( stss_iter ) = stss_iter . as_mut ( ) { stss_iter . next ( ) . unwrap_or ( false ) } else { // no stss iter? every sample is a sync sample. true } ; if cur_seg_size + sample_size > MAX_SEGMENT_SIZE { true } else { is_sync } } , } ; if do_next_seg || cur_sample == 1 { // A new segment starts here. if cur_sample > 1 { // Finish the previous segment and push it onto the vec. cur_segment . end_sample = cur_sample - 1 ; cur_segment . duration = cur_seg_duration as f64 / timescale ; cur_segment . size = cur_seg_size ; segments . push ( cur_segment . clone ( ) ) ; } cur_segment . start_sample = cur_sample ; let tm = cur_time as i64 + ( delta as i64 ) - ( comp_time_shift as i64 ) ; let tm = std :: cmp :: max ( 0 , tm ) ; cur_segment . start_time = tm as f64 / timescale ; cur_segment . is_sync = is_sync ; cur_seg_duration = 0 ; cur_seg_size = 0 ; } cur_seg_duration += sample_duration ; cur_seg_size += sample_size ; cur_time += sample_duration ; } Ok ( squish ( segments ) ) }
Parse a track into segments, each starting at a sync sample.
Parse a track into segments each starting at a sync sample .
trak
&TrackBox
segment_duration
Option<u32>
trak
&TrackBox
segment_duration
Option<u32>