[NUT] (ods15): r105 - in /trunk: demux_nut.c libnut/demuxer.c libnut/muxer.c libnut/nut.h libnut/priv.h libnut/reorder.c nututils/demux_avi.c nututils/demux_ogg.c

Author: ods15 Date: Thu Mar 16 06:39:53 2006 New Revision: 105 Log: huge switch to timebase table... Modified: trunk/demux_nut.c trunk/libnut/demuxer.c trunk/libnut/muxer.c trunk/libnut/nut.h trunk/libnut/priv.h trunk/libnut/reorder.c trunk/nututils/demux_avi.c trunk/nututils/demux_ogg.c Modified: trunk/demux_nut.c ============================================================================== --- trunk/demux_nut.c (original) +++ trunk/demux_nut.c Thu Mar 16 06:39:53 2006 @@ -90,8 +90,8 @@ sh_audio->wf= wf; sh_audio->ds = demuxer->audio; sh_audio->audio.dwSampleSize = 0; // FIXME - sh_audio->audio.dwScale = s[i].timebase.nom; - sh_audio->audio.dwRate = s[i].timebase.den; + sh_audio->audio.dwScale = s[i].time_base.nom; + sh_audio->audio.dwRate = s[i].time_base.den; if (s[i].fourcc_len == 4) sh_audio->format = *(uint32_t*)s[i].fourcc; else sh_audio->format = *(uint16_t*)s[i].fourcc; // FIXME sh_audio->channels = s[i].channel_count; @@ -120,8 +120,8 @@ sh_video->ds = demuxer->video; sh_video->disp_w = s[i].width; sh_video->disp_h = s[i].height; - sh_video->video.dwScale = s[i].timebase.nom; - sh_video->video.dwRate = s[i].timebase.den; + sh_video->video.dwScale = s[i].time_base.nom; + sh_video->video.dwRate = s[i].time_base.den; sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; @@ -176,7 +176,7 @@ } } - pts = (double)pd.pts * priv->s[pd.stream].timebase.nom / priv->s[pd.stream].timebase.den; + pts = (double)pd.pts * priv->s[pd.stream].time_base.nom / priv->s[pd.stream].time_base.den; if (pd.stream == demuxer->audio->id) { ds = demuxer->audio; @@ -233,7 +233,7 @@ if (flags & 2) // percent time_pos *= priv->s[0].max_pts * - (double)priv->s[0].timebase.nom / priv->s[0].timebase.den; + (double)priv->s[0].time_base.nom / priv->s[0].time_base.den; ret = nut_seek(nut, time_pos, nutflags, tmp); if (ret < 0) mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(-ret)); @@ -245,7 +245,7 @@ switch (cmd) { case DEMUXER_CTRL_GET_TIME_LENGTH: *((double *)arg) = priv->s[0].max_pts * - (double)priv->s[0].timebase.nom / priv->s[0].timebase.den; + (double)priv->s[0].time_base.nom / priv->s[0].time_base.den; return DEMUXER_CTRL_OK; case DEMUXER_CTRL_GET_PERCENT_POS: if (priv->s[0].max_pts == 0) return DEMUXER_CTRL_DONTKNOW; Modified: trunk/libnut/demuxer.c ============================================================================== --- trunk/libnut/demuxer.c (original) +++ trunk/libnut/demuxer.c Thu Mar 16 06:39:53 2006 @@ -237,6 +237,13 @@ GET_V(tmp, nut->stream_count); GET_V(tmp, nut->max_distance); if (nut->max_distance > 65536) nut->max_distance = 65536; + + GET_V(tmp, nut->timebase_count); + nut->tb = realloc(nut->tb, nut->timebase_count * sizeof(nut_timebase_t)); + for (i = 0; i < nut->timebase_count; i++) { + GET_V(tmp, nut->tb[i].nom); + GET_V(tmp, nut->tb[i].den); + } for(i = 0; i < 256; ) { int scrap; @@ -285,8 +292,8 @@ GET_V(tmp, sc->sh.type); CHECK(get_vb(tmp, &sc->sh.fourcc_len, &sc->sh.fourcc)); - GET_V(tmp, sc->sh.timebase.nom); - GET_V(tmp, sc->sh.timebase.den); + GET_V(tmp, sc->timebase_id); + sc->sh.time_base = nut->tb[sc->timebase_id]; GET_V(tmp, sc->msb_pts_shift); GET_V(tmp, sc->max_pts_distance); GET_V(tmp, sc->sh.decode_delay); @@ -361,7 +368,7 @@ TO_PTS(timestamp, pts) for (i = 0; i < nut->stream_count; i++) { - nut->sc[i].last_pts = convert_ts(nut, timestamp_p, timestamp_s, i); + nut->sc[i].last_pts = convert_ts(nut, timestamp_p, nut->tb[timestamp_t], TO_TB(i)); } } @@ -418,7 +425,7 @@ GET_V(tmp, x); for (i = 0; i < nut->stream_count; i++) { TO_PTS(max, x) - nut->sc[i].sh.max_pts = convert_ts(nut, max_p, max_s, i); + nut->sc[i].sh.max_pts = convert_ts(nut, max_p, nut->tb[max_t], TO_TB(i)); } GET_V(tmp, x); @@ -559,11 +566,11 @@ // error checking - out of order dts for (i = 0; i < nut->stream_count; i++) { if (nut->sc[i].last_dts == -1) continue; - if (compare_ts(nut, pd->pts, pd->stream, nut->sc[i].last_dts, i) < 0) + if (compare_ts(nut, pd->pts, TO_TB(pd->stream), nut->sc[i].last_dts, TO_TB(i)) < 0) fprintf(stderr, "%lld %d (%f) %lld %d (%f) \n", pd->pts, pd->stream, TO_DOUBLE(pd->stream, pd->pts), nut->sc[i].last_dts, i, TO_DOUBLE(i, nut->sc[i].last_dts)); - ERROR(compare_ts(nut, pd->pts, pd->stream, nut->sc[i].last_dts, i) < 0, -ERR_OUT_OF_ORDER); + ERROR(compare_ts(nut, pd->pts, TO_TB(pd->stream), nut->sc[i].last_dts, TO_TB(i)) < 0, -ERR_OUT_OF_ORDER); } if (saw_syncpoint) *saw_syncpoint = !!after_sync; @@ -846,13 +853,16 @@ return err; } -static int binary_search_syncpoint(nut_context_t * nut, double time_pos, uint64_t * pts, off_t * start, off_t * end, syncpoint_t * stopper) { +static int binary_search_syncpoint(nut_context_t * nut, double time_pos, off_t * start, off_t * end, syncpoint_t * stopper) { int i, err = 0; syncpoint_t s; off_t hi, lo; uint64_t hip, lop; + uint64_t timebases[nut->timebase_count]; syncpoint_list_t * sl = &nut->syncpoints; int a = 0; + + for (i = 0; i < nut->timebase_count; i++) timebases[i] = (uint64_t)(time_pos / nut->tb[i].nom * nut->tb[i].den); CHECK(find_basic_syncpoints(nut)); // sl->len MUST be >=2, which is the first and last syncpoints in the file @@ -860,7 +870,7 @@ for (i = 0; i < sl->len; i++) { TO_PTS(tmp, sl->s[i].pts) - if ((pts[tmp_s] >> 1) <= tmp_p) break; + if (timebases[tmp_t] <= tmp_p) break; } if (i == sl->len) { // there isn't any syncpoint bigger than requested @@ -921,7 +931,7 @@ continue; } - res = s.pts / nut->stream_count > (pts[s.pts % nut->stream_count] >> 1); + res = (s.pts / nut->timebase_count > timebases[s.pts % nut->timebase_count]); if (res) { hi = s.pos; hip = s.pts; @@ -947,7 +957,7 @@ } fprintf(stderr, "\n[ (%d,%d) .. %d .. (%d,%d) ] => %d (%d seeks) %d\n", - (int)lo, (int)lop, (int)pts[0], (int)hi, (int)hip, (int)(lo - (sl->s[i].back_ptr>>1)), a, sl->s[i].back_ptr); + (int)lo, (int)lop, (int)timebases[0], (int)hi, (int)hip, (int)(lo - (sl->s[i].back_ptr>>1)), a, sl->s[i].back_ptr); // at this point, s[i].pts < P < s[i+1].pts, and s[i].flag is set // meaning, there are no more syncpoints between s[i] to s[i+1] *start = (sl->s[i].pos >> 1) - (sl->s[i].back_ptr>>1); @@ -1045,7 +1055,7 @@ } } else if (stopper && pd.flags&NUT_FLAG_KEY && !(good_key[i]&1)) { TO_PTS(stopper, stopper->pts) - if (compare_ts(nut, stopper_p, stopper_s, pd.pts, pd.stream) > 0) { + if (compare_ts(nut, stopper_p, nut->tb[stopper_t], pd.pts, TO_TB(pd.stream)) > 0) { good_key[pd.stream] = buf_before<<1; if (stopper_syncpoint) { int n = 1; @@ -1127,7 +1137,7 @@ static void req_to_pts(nut_context_t * nut, double * time_pos, int flags, uint64_t * pts, const int * active_streams) { uint64_t orig_pts = 0; - int orig_stream = 0; + int orig_timebase = 0; int i; for (i = 0; i < nut->stream_count; i++) pts[i] = 0; @@ -1139,17 +1149,17 @@ uint64_t dts = nut->sc[i].last_dts != -1 ? nut->sc[i].last_dts : nut->sc[i].last_pts; int FIXME; // this is completely wrong with EAGAIN if (!pts[i]) continue; - if (compare_ts(nut, orig_pts, orig_stream, dts, i) < 0) { + if (compare_ts(nut, orig_pts, nut->tb[orig_timebase], dts, TO_TB(i)) < 0) { orig_pts = dts; - orig_stream = i; - } - } - *time_pos += TO_DOUBLE(orig_stream, orig_pts); + orig_timebase = nut->sc[i].timebase_id; + } + } + *time_pos += TO_DOUBLE(orig_timebase, orig_pts); } if (*time_pos < 0.) *time_pos = 0.; for (i = 0; i < nut->stream_count; i++) { - pts[i] |= (uint64_t)(*time_pos / nut->sc[i].sh.timebase.nom * nut->sc[i].sh.timebase.den) << 1; + pts[i] |= (uint64_t)(*time_pos / TO_TB(i).nom * TO_TB(i).den) << 1; } } @@ -1208,7 +1218,7 @@ } } - if (start == 0) CHECK(binary_search_syncpoint(nut, time_pos, pts, &start, &end, &stopper)); + if (start == 0) CHECK(binary_search_syncpoint(nut, time_pos, &start, &end, &stopper)); else fprintf(stderr, "============= NO BINARY SEARCH\n"); if (start) { // "unsuccessful" seek needs no linear search @@ -1239,6 +1249,7 @@ nut->syncpoints.eor = NULL; nut->sc = NULL; + nut->tb = NULL; nut->last_headers = 0; nut->stream_count = 0; nut->dopts = *dopts; @@ -1262,6 +1273,7 @@ free(nut->syncpoints.pts); free(nut->syncpoints.eor); free(nut->sc); + free(nut->tb); free(nut->seek_state); free_buffer(nut->i); free(nut); Modified: trunk/libnut/muxer.c ============================================================================== --- trunk/libnut/muxer.c (original) +++ trunk/libnut/muxer.c Thu Mar 16 06:39:53 2006 @@ -140,7 +140,12 @@ put_v(tmp, NUT_VERSION); put_v(tmp, nut->stream_count); put_v(tmp, nut->max_distance); - for(i = 0; i < 256; ) { + put_v(tmp, nut->timebase_count); + for (i = 0; i < nut->timebase_count; i++) { + put_v(tmp, nut->tb[i].nom); + put_v(tmp, nut->tb[i].den); + } + for (i = 0; i < 256; ) { fields = 0; flag = nut->ft[i].flags; if (nut->ft[i].pts_delta != timestamp) fields = 1; @@ -182,8 +187,7 @@ put_v(tmp, id); // ### is stream_id staying in spec put_v(tmp, sc->sh.type); put_vb(tmp, sc->sh.fourcc_len, sc->sh.fourcc); - put_v(tmp, sc->sh.timebase.nom); - put_v(tmp, sc->sh.timebase.den); + put_v(tmp, sc->timebase_id); put_v(tmp, sc->msb_pts_shift); put_v(tmp, sc->max_pts_distance); put_v(tmp, sc->sh.decode_delay); @@ -259,7 +263,7 @@ output_buffer_t * tmp = clear_buffer(nut->tmp_buffer); int i; uint64_t pts = 0; - int stream = 0; + int timebase = 0; int back_ptr = 0; int keys[nut->stream_count]; syncpoint_list_t * s = &nut->syncpoints; @@ -267,9 +271,9 @@ nut->last_syncpoint = bctello(nut->o); for (i = 0; i < nut->stream_count; i++) { - if (nut->sc[i].last_dts > 0 && compare_ts(nut, nut->sc[i].last_dts, i, pts, stream) > 0) { + if (nut->sc[i].last_dts > 0 && compare_ts(nut, nut->sc[i].last_dts, TO_TB(i), pts, nut->tb[timebase]) > 0) { pts = nut->sc[i].last_dts; - stream = i; + timebase = nut->sc[i].timebase_id; } } @@ -294,7 +298,7 @@ for (j = 0; j < nut->stream_count; j++) { if (keys[j]) continue; if (!s->pts[i * nut->stream_count + j]) continue; - if (compare_ts(nut, s->pts[i * nut->stream_count + j] - 1, j, pts, stream) <= 0) keys[j] = 1; + if (compare_ts(nut, s->pts[i * nut->stream_count + j] - 1, TO_TB(j), pts, nut->tb[timebase]) <= 0) keys[j] = 1; } for (j = 0; j < nut->stream_count; j++) n &= keys[j]; if (n) { i--; break; } @@ -302,12 +306,12 @@ back_ptr = (nut->last_syncpoint - s->s[i].pos) / 16; for (i = 0; i < nut->stream_count; i++) { - nut->sc[i].last_pts = convert_ts(nut, pts, stream, i); + nut->sc[i].last_pts = convert_ts(nut, pts, nut->tb[timebase], TO_TB(i)); nut->sc[i].last_key = 0; if (nut->sc[i].eor) nut->sc[i].eor = -1; // so we know to ignore this stream in future syncpoints } - put_v(tmp, pts * nut->stream_count + stream); + put_v(tmp, pts * nut->timebase_count + timebase); put_v(tmp, back_ptr); put_header(nut->o, tmp, nut->tmp_buffer2, SYNCPOINT_STARTCODE, 0); @@ -320,15 +324,15 @@ syncpoint_list_t * s = &nut->syncpoints; int i; uint64_t max_pts = 0; - int stream = 0; + int timebase = 0; for (i = 0; i < nut->stream_count; i++) { - if (compare_ts(nut, nut->sc[i].sh.max_pts, i, max_pts, stream) > 0) { + if (compare_ts(nut, nut->sc[i].sh.max_pts, TO_TB(i), max_pts, nut->tb[timebase]) > 0) { max_pts = nut->sc[i].sh.max_pts; - stream = i; - } - } - put_v(tmp, max_pts * nut->stream_count + stream); + timebase = nut->sc[i].timebase_id; + } + } + put_v(tmp, max_pts * nut->timebase_count + timebase); put_v(tmp, s->len); for (i = 0; i < s->len; i++) { @@ -392,7 +396,7 @@ if (fd->len > 2*nut->max_distance) checksum = 1; if (ABS(pts_delta) > sc->max_pts_distance) { - fprintf(stderr, "%d > %d || %d - %d > %d \n", fd->len, nut->max_distance, (int)fd->pts, (int)sc->last_pts, sc->max_pts_distance); + fprintf(stderr, "%d > %d || %d - %d > %d \n", fd->len, 2*nut->max_distance, (int)fd->pts, (int)sc->last_pts, sc->max_pts_distance); checksum = 1; } @@ -461,11 +465,11 @@ for (i = 0; i < nut->stream_count; i++) { if (nut->sc[i].last_dts == -1) continue; - if (compare_ts(nut, fd->pts, fd->stream, nut->sc[i].last_dts, i) < 0) + if (compare_ts(nut, fd->pts, TO_TB(fd->stream), nut->sc[i].last_dts, TO_TB(i)) < 0) fprintf(stderr, "%lld %d (%f) %lld %d (%f) \n", fd->pts, fd->stream, TO_DOUBLE(fd->stream, fd->pts), nut->sc[i].last_dts, i, TO_DOUBLE(i, nut->sc[i].last_dts)); - assert(compare_ts(nut, fd->pts, fd->stream, nut->sc[i].last_dts, i) >= 0); + assert(compare_ts(nut, fd->pts, TO_TB(fd->stream), nut->sc[i].last_dts, TO_TB(i)) >= 0); } sc->last_pts = fd->pts; @@ -534,6 +538,8 @@ for (nut->stream_count = 0; s[nut->stream_count].type >= 0; nut->stream_count++); nut->sc = malloc(sizeof(stream_context_t) * nut->stream_count); + nut->tb = malloc(sizeof(nut_timebase_t) * nut->stream_count); + nut->timebase_count = 0; for (i = 0; i < nut->stream_count; i++) { int j; @@ -541,7 +547,7 @@ nut->sc[i].last_pts = 0; nut->sc[i].last_dts = -1; nut->sc[i].msb_pts_shift = 7; // TODO - nut->sc[i].max_pts_distance = (s[i].timebase.den + s[i].timebase.nom - 1) / s[i].timebase.nom; // TODO + nut->sc[i].max_pts_distance = (s[i].time_base.den + s[i].time_base.nom - 1) / s[i].time_base.nom; // TODO nut->sc[i].eor = 0; nut->sc[i].sh = s[i]; nut->sc[i].sh.max_pts = 0; @@ -553,6 +559,10 @@ memcpy(nut->sc[i].sh.codec_specific, s[i].codec_specific, s[i].codec_specific_len); nut->sc[i].pts_cache = malloc(nut->sc[i].sh.decode_delay * sizeof(int64_t)); + + for (j = 0; j < nut->timebase_count; j++) if (compare_ts(nut, 1, s[i].time_base, 1, nut->tb[j]) == 0) break; + if (j == nut->timebase_count) nut->tb[nut->timebase_count++] = s[i].time_base; + nut->sc[i].timebase_id = j; // reorder.c nut->sc[i].reorder_pts_cache = malloc(nut->sc[i].sh.decode_delay * sizeof(int64_t)); @@ -622,6 +632,7 @@ free(nut->sc[i].reorder_pts_cache); } free(nut->sc); + free(nut->tb); for (i = 0; i < nut->info_count; i++) { int j; Modified: trunk/libnut/nut.h ============================================================================== --- trunk/libnut/nut.h (original) +++ trunk/libnut/nut.h Thu Mar 16 06:39:53 2006 @@ -33,7 +33,7 @@ int type; // -1 means end int fourcc_len; uint8_t * fourcc; - nut_timebase_t timebase; + nut_timebase_t time_base; int fixed_fps; int decode_delay; int codec_specific_len; Modified: trunk/libnut/priv.h ============================================================================== --- trunk/libnut/priv.h (original) +++ trunk/libnut/priv.h Thu Mar 16 06:39:53 2006 @@ -105,6 +105,7 @@ int64_t last_dts; int msb_pts_shift; int max_pts_distance; + int timebase_id; nut_stream_header_t sh; int64_t * pts_cache; int64_t eor; @@ -127,6 +128,9 @@ output_buffer_t * tmp_buffer; output_buffer_t * tmp_buffer2; + int timebase_count; + nut_timebase_t * tb; + int stream_count; stream_context_t * sc; @@ -162,15 +166,15 @@ return crc; } -static inline uint64_t convert_ts(nut_context_t * nut, uint64_t sn, int from, int to) { +static inline uint64_t convert_ts(nut_context_t * nut, uint64_t sn, nut_timebase_t from, nut_timebase_t to) { uint64_t ln, d1, d2; - ln = (uint64_t)nut->sc[from].sh.timebase.nom * nut->sc[to].sh.timebase.den; - d1 = nut->sc[from].sh.timebase.den; - d2 = nut->sc[to].sh.timebase.nom; + ln = (uint64_t)from.nom * to.den; + d1 = from.den; + d2 = to.nom; return (ln / d1 * sn + (ln%d1) * sn / d1) / d2; } -static inline int compare_ts(nut_context_t * nut, uint64_t a, int at, uint64_t b, int bt) { +static inline int compare_ts(nut_context_t * nut, uint64_t a, nut_timebase_t at, uint64_t b, nut_timebase_t bt) { if (convert_ts(nut, a, at, bt) < b) return -1; if (convert_ts(nut, b, bt, at) < a) return 1; return 0; @@ -190,11 +194,13 @@ #define bctello(bc) ((bc)->file_pos + ((bc)->buf_ptr - (bc)->buf)) #define TO_PTS(prefix, pts) \ - int prefix##_s = (pts) % nut->stream_count; \ - uint64_t prefix##_p = (pts) / nut->stream_count; - -#define TO_DOUBLE(stream, pts) ((double)(pts) / nut->sc[(stream)].sh.timebase.den * nut->sc[(stream)].sh.timebase.nom) - -#define TO_DOUBLE_PTS(pts) ((double)((pts) / nut->stream_count) / nut->sc[(pts) % nut->stream_count].sh.timebase.den * nut->sc[(pts) % nut->stream_count].sh.timebase.nom) + int prefix##_t = (pts) % nut->timebase_count; \ + uint64_t prefix##_p = (pts) / nut->timebase_count; + +#define TO_DOUBLE(t, pts) ((double)(pts) / nut->tb[t].den * nut->tb[t].nom) + +#define TO_DOUBLE_PTS(pts) ((double)((pts) / nut->timebase_count) / nut->tb[(pts) % nut->timebase_count].den * nut->tb[(pts) % nut->timebase_count].nom) + +#define TO_TB(i) nut->tb[nut->sc[i].timebase_id] #endif // _NUT_PRIV_H Modified: trunk/libnut/reorder.c ============================================================================== --- trunk/libnut/reorder.c (original) +++ trunk/libnut/reorder.c Thu Mar 16 06:39:53 2006 @@ -38,7 +38,7 @@ else pts = nut->sc[j].next_pts; if (pts >= 0) { - pts = convert_ts(nut, pts, j, i); + pts = convert_ts(nut, pts, TO_TB(j), TO_TB(i)); if (min > pts || min == -1) min = pts; } } Modified: trunk/nututils/demux_avi.c ============================================================================== --- trunk/nututils/demux_avi.c (original) +++ trunk/nututils/demux_avi.c Thu Mar 16 06:39:53 2006 @@ -359,8 +359,8 @@ *nut_streams = s = malloc(sizeof(nut_stream_header_t) * (avi->avih->dwStreams + 1 + N)); for (i = 0; i < avi->avih->dwStreams; i++) { s[i].type = avi->stream[i].type; - s[i].timebase.den = avi->stream[i].strh->dwRate; - s[i].timebase.nom = avi->stream[i].strh->dwScale; + s[i].time_base.den = avi->stream[i].strh->dwRate; + s[i].time_base.nom = avi->stream[i].strh->dwScale; s[i].fixed_fps = 1; s[i].decode_delay = !i; // FIXME s[i].codec_specific_len = avi->stream[i].extra_len; @@ -383,7 +383,7 @@ s[i].channel_count = avi->stream[i].audio->nChannels; } } - while (i < N + 2) s[i++] = s[0]; + while (i < N + 2) { s[i] = s[0]; s[i++].decode_delay = 0; } s[i].type = -1; return 0; } Modified: trunk/nututils/demux_ogg.c ============================================================================== --- trunk/nututils/demux_ogg.c (original) +++ trunk/nututils/demux_ogg.c Thu Mar 16 06:39:53 2006 @@ -529,8 +529,8 @@ s[i].type = os->oc->type; s[i].fourcc = os->oc->fourcc; s[i].fourcc_len = os->oc->fourcc_len; - s[i].timebase.den = os->time_base_denom; - s[i].timebase.nom = os->time_base_nom; + s[i].time_base.den = os->time_base_denom; + s[i].time_base.nom = os->time_base_nom; s[i].fixed_fps = os->fixed_fps; s[i].decode_delay = os->decode_delay; s[i].codec_specific = os->codec_specific;
participants (1)
-
syncmail@mplayerhq.hu