[nut]: r223 - in trunk/libnut: demuxer.c priv.h

Author: ods15 Date: Fri Nov 17 16:25:44 2006 New Revision: 223 Modified: trunk/libnut/demuxer.c trunk/libnut/priv.h Log: get rid of nut->seek_state, keep in stream context Modified: trunk/libnut/demuxer.c ============================================================================== --- trunk/libnut/demuxer.c (original) +++ trunk/libnut/demuxer.c Fri Nov 17 16:25:44 2006 @@ -1083,7 +1083,7 @@ return err; } -static int linear_search_seek(nut_context_t * nut, int backwards, seek_state_t * state, off_t start, off_t end, syncpoint_t * stopper) { +static int linear_search_seek(nut_context_t * nut, int backwards, off_t start, off_t end, syncpoint_t * stopper) { syncpoint_list_t * sl = &nut->syncpoints; int i, err = 0; off_t min_pos = 0; @@ -1129,7 +1129,7 @@ if (stopper && !stopper_syncpoint && buf_before > stopper->pos - stopper->back_ptr + 15) { int n = 1; stopper_syncpoint = buf_before; - for (i = 0; i < nut->stream_count; i++) if (!state[i].active && state[i].good_key) n = 0; + for (i = 0; i < nut->stream_count; i++) if (!nut->sc[i].state.active && nut->sc[i].state.good_key) n = 0; if (n) break; // no inactive streams have keyframes between stopper and stopper_syncpoint, stop now } if (buf_before != stopper_syncpoint) { // flush at every syncpoint - except stopper_syncpoint @@ -1141,19 +1141,19 @@ } } - if (state[pd.stream].active) { - if (end && pd.pts > state[pd.stream].pts) { // higher than requested pts + if (nut->sc[pd.stream].state.active) { + if (end && pd.pts > nut->sc[pd.stream].state.pts) { // higher than requested pts int n = 1; - state[pd.stream].pts_higher = 1; - for (i = 0; i < nut->stream_count; i++) if (state[i].active && !state[i].pts_higher) n = 0; + nut->sc[pd.stream].state.pts_higher = 1; + for (i = 0; i < nut->stream_count; i++) if (nut->sc[i].state.active && !nut->sc[i].state.pts_higher) n = 0; if (n) break; // pts for all active streams higher than requested pts } if (pd.flags & NUT_FLAG_KEY) { - if (pd.pts <= state[pd.stream].pts) { - state[pd.stream].good_key = buf_before; - if (pd.flags & NUT_FLAG_EOR) state[pd.stream].good_key = 0; + if (pd.pts <= nut->sc[pd.stream].state.pts) { + nut->sc[pd.stream].state.good_key = buf_before; + if (pd.flags & NUT_FLAG_EOR) nut->sc[pd.stream].state.good_key = 0; } - if (!end && pd.pts >= state[pd.stream].pts) { // forward seek end + if (!end && pd.pts >= nut->sc[pd.stream].state.pts) { // forward seek end nut->i->buf_ptr -= bctello(nut->i) - buf_before; break; } @@ -1163,11 +1163,11 @@ TO_PTS(stopper, stopper->pts) // only relavent if pts is smaller than stopper, and we passed stopper's back_ptr if (compare_ts(pd.pts, TO_TB(pd.stream), stopper_p, nut->tb[stopper_t]) < 0 && buf_before >= back_ptr) { - if (!stopper_syncpoint) state[pd.stream].good_key = 1; - else if (state[pd.stream].good_key) { + if (!stopper_syncpoint) nut->sc[pd.stream].state.good_key = 1; + else if (nut->sc[pd.stream].state.good_key) { int n = 1; - state[pd.stream].good_key = 0; - for (i = 0; i < nut->stream_count; i++) if (!state[i].active && state[i].good_key) n = 0; + nut->sc[pd.stream].state.good_key = 0; + for (i = 0; i < nut->stream_count; i++) if (!nut->sc[i].state.active && nut->sc[i].state.good_key) n = 0; // smart linear search stop // keyframe for every inactive stream (which had a keyframe in stopper area), after stopper_syncpoint if (n) break; @@ -1175,7 +1175,7 @@ } } // dts higher than requested pts - if (end && peek_dts(nut->sc[pd.stream].sh.decode_delay, nut->sc[pd.stream].pts_cache, pd.pts) > (int64_t)state[pd.stream].pts) break; + if (end && peek_dts(nut->sc[pd.stream].sh.decode_delay, nut->sc[pd.stream].pts_cache, pd.pts) > (int64_t)nut->sc[pd.stream].state.pts) break; CHECK(skip_buffer(nut->i, pd.len)); push_frame(nut, &pd); @@ -1183,12 +1183,12 @@ if (!end) goto err_out; // forward seek for (i = 0; i < nut->stream_count; i++) { - if (!state[i].active) continue; - if (state[i].good_key && (!min_pos || state[i].good_key < min_pos)) min_pos = state[i].good_key; + if (!nut->sc[i].state.active) continue; + if (nut->sc[i].state.good_key && (!min_pos || nut->sc[i].state.good_key < min_pos)) min_pos = nut->sc[i].state.good_key; } if (!min_pos) { fprintf(stderr, "BIG FAT WARNING\n"); - for (i = 0; i < nut->stream_count; i++) fprintf(stderr, "%d: %d\n", i, (int)state[i].good_key); + for (i = 0; i < nut->stream_count; i++) fprintf(stderr, "%d: %d\n", i, (int)nut->sc[i].state.good_key); min_pos = nut->seek_status >> 1; } @@ -1217,7 +1217,7 @@ if (err != NUT_ERR_EAGAIN) { // unless EAGAIN if (err) { if (err == NUT_ERR_NOT_SEEKABLE) { // a failed seek - then go back to before everything started - for (i = 0; i < nut->stream_count; i++) nut->sc[i].last_pts = state[i].old_last_pts; + for (i = 0; i < nut->stream_count; i++) nut->sc[i].last_pts = nut->sc[i].state.old_last_pts; seek_buf(nut->i, nut->before_seek, SEEK_SET); } else { // some NUT error, let's just go back to last good syncpoint err = 0; @@ -1237,29 +1237,28 @@ int nut_seek(nut_context_t * nut, double time_pos, int flags, const int * active_streams) { int err = 0; off_t start = 0, end = 0; - seek_state_t state[nut->stream_count]; int backwards = flags & 1 ? time_pos < 0 : 1; syncpoint_t stopper = { 0, 0, 0, 0, 0 }; if (!nut->i->isc.seek) return NUT_ERR_NOT_SEEKABLE; - if (!nut->before_seek) nut->before_seek = bctello(nut->i); - - if (!nut->seek_state) { + if (!nut->before_seek) { int i; + nut->before_seek = bctello(nut->i); + for (i = 0; i < nut->stream_count; i++) { - state[i].old_last_pts = nut->sc[i].last_pts; - state[i].active = active_streams ? 0 : 1; - state[i].good_key = state[i].pts_higher = 0; + nut->sc[i].state.old_last_pts = nut->sc[i].last_pts; + nut->sc[i].state.active = active_streams ? 0 : 1; + nut->sc[i].state.good_key = nut->sc[i].state.pts_higher = 0; } - if (active_streams) for (i = 0; active_streams[i] != -1; i++) state[active_streams[i]].active = 1; + if (active_streams) for (i = 0; active_streams[i] != -1; i++) nut->sc[active_streams[i]].state.active = 1; if (flags & 1) { // relative seek uint64_t orig_pts = 0; int orig_timebase = 0; for (i = 0; i < nut->stream_count; i++) { uint64_t dts = nut->sc[i].last_dts != -1 ? nut->sc[i].last_dts : nut->sc[i].last_pts; - if (!state[i].active) continue; + if (!nut->sc[i].state.active) continue; if (compare_ts(orig_pts, nut->tb[orig_timebase], dts, TO_TB(i)) < 0) { orig_pts = dts; orig_timebase = nut->sc[i].timebase_id; @@ -1269,11 +1268,10 @@ } if (time_pos < 0.) time_pos = 0.; - for (i = 0; i < nut->stream_count; i++) state[i].pts = (uint64_t)(time_pos / TO_TB(i).nom * TO_TB(i).den); + for (i = 0; i < nut->stream_count; i++) nut->sc[i].state.pts = (uint64_t)(time_pos / TO_TB(i).nom * TO_TB(i).den); nut->seek_time_pos = time_pos; nut->dopts.cache_syncpoints |= 2; } else { - memcpy(state, nut->seek_state, sizeof state); time_pos = nut->seek_time_pos; } @@ -1291,18 +1289,18 @@ if (!sl->s[i].pts_valid) continue; for (j = 0; j < nut->stream_count; j++) { uint64_t tmp; - if (!state[j].active) continue; + if (!nut->sc[j].state.active) continue; tmp = sl->pts[i * nut->stream_count + j]; if (tmp--) { // -- because all pts array is off-by-one. zero indicate no keyframe. - if (tmp > state[j].pts) { if (!last_sync) last_sync = i; } + if (tmp > nut->sc[j].state.pts) { if (!last_sync) last_sync = i; } else sync[j] = (i-1); } tmp = sl->eor[i * nut->stream_count + j]; - if (tmp--) if (tmp <= state[j].pts) sync[j] = -(i+1); // flag stream eor + if (tmp--) if (tmp <= nut->sc[j].state.pts) sync[j] = -(i+1); // flag stream eor } } for (i = 0; i < nut->stream_count; i++) { - if (!state[i].active) continue; + if (!nut->sc[i].state.active) continue; if (sync[i] < -1) { backup = MAX(backup, -sync[i] - 1); continue; } // eor stream if (good_sync == -2 || good_sync > sync[i]) good_sync = sync[i]; } @@ -1324,9 +1322,9 @@ if (start) { // "unsuccessful" seek needs no linear search if (!(flags & 2)) { // regular seek - CHECK(linear_search_seek(nut, backwards, state, start, end, stopper.pos ? &stopper : NULL)); + CHECK(linear_search_seek(nut, backwards, start, end, stopper.pos ? &stopper : NULL)); } else { // forwards seek, find keyframe - CHECK(linear_search_seek(nut, backwards, state, end, 0, NULL)); + CHECK(linear_search_seek(nut, backwards, end, 0, NULL)); } } fprintf(stderr, "DONE SEEK\n"); @@ -1335,18 +1333,12 @@ syncpoint_list_t * sl = &nut->syncpoints; flush_buf(nut->i); nut->before_seek = 0; - nut->alloc->free(nut->seek_state); - nut->seek_state = NULL; nut->dopts.cache_syncpoints &= ~2; if (!nut->dopts.cache_syncpoints && sl->len > 1) { sl->s[1] = sl->s[sl->len - 1]; sl->len = 2; sl->s[0].seen_next = 0; } - } else { - if (!nut->seek_state) nut->seek_state = nut->alloc->malloc(sizeof state); - if (!nut->seek_state) return NUT_ERR_OUT_OF_MEM; - memcpy(nut->seek_state, state, sizeof state); } return err; } @@ -1376,7 +1368,6 @@ nut->seek_status = 0; nut->before_seek = 0; nut->last_syncpoint = 0; - nut->seek_state = NULL; nut->alloc = &nut->dopts.alloc; @@ -1422,7 +1413,6 @@ nut->alloc->free(nut->tmp_buffer); // the caller's allocated stream list nut->alloc->free(nut->info); nut->alloc->free(nut->tb); - nut->alloc->free(nut->seek_state); free_buffer(nut->i); nut->alloc->free(nut); } Modified: trunk/libnut/priv.h ============================================================================== --- trunk/libnut/priv.h (original) +++ trunk/libnut/priv.h Fri Nov 17 16:25:44 2006 @@ -90,6 +90,14 @@ } reorder_packet_t; typedef struct { + int active; + uint64_t pts; // requested pts; + uint64_t old_last_pts; + off_t good_key; + int pts_higher; // for active streams +} seek_state_t; + +typedef struct { uint64_t last_key; // muxer.c, re-set to 0 on every keyframe uint64_t last_pts; int64_t last_dts; @@ -99,6 +107,7 @@ nut_stream_header_t sh; int64_t * pts_cache; int64_t eor; + seek_state_t state; // reorder.c int64_t next_pts; reorder_packet_t * packets; @@ -110,14 +119,6 @@ int total_frames; } stream_context_t; -typedef struct { - int active; - uint64_t pts; // requested pts; - uint64_t old_last_pts; - off_t good_key; - int pts_higher; // for active streams -} seek_state_t; - struct nut_context_s { nut_muxer_opts_t mopts; nut_demuxer_opts_t dopts; @@ -145,7 +146,6 @@ off_t before_seek; // position before any seek mess off_t seek_status; - seek_state_t * seek_state; // array per stream count double seek_time_pos; syncpoint_list_t syncpoints;
participants (1)
-
ods15