X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fogg2.c;h=2b4b1603b6dd86664781db5ecc761f83f448888e;hb=1cbe9d6a780d27a790ec2fd2d5bf5ae6edef10ff;hp=1d49e211166b08245ea2ff8da96ba4636ef51276;hpb=d2a067d1d9011bf1015fd23efcbfb20cd4f79e1a;p=ffmpeg diff --git a/libavformat/ogg2.c b/libavformat/ogg2.c index 1d49e211166..2b4b1603b6d 100644 --- a/libavformat/ogg2.c +++ b/libavformat/ogg2.c @@ -41,6 +41,7 @@ static ogg_codec_t *ogg_codecs[] = { &vorbis_codec, &theora_codec, &flac_codec, + &old_flac_codec, &ogm_video_codec, &ogm_audio_codec, &ogm_old_codec, @@ -65,10 +66,10 @@ ogg_write_trailer (AVFormatContext * avfcontext) } -static AVOutputFormat ogg_muxer = { +AVOutputFormat ogg_muxer = { "ogg", - "Ogg Vorbis", - "audio/x-vorbis", + "Ogg format", + "application/ogg", "ogg", sizeof (OggContext), CODEC_ID_VORBIS, @@ -90,6 +91,7 @@ ogg_save (AVFormatContext * s) ost->pos = url_ftell (&s->pb);; ost->curidx = ogg->curidx; ost->next = ogg->state; + ost->nstreams = ogg->nstreams; memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams)); for (i = 0; i < ogg->nstreams; i++){ @@ -123,8 +125,9 @@ ogg_restore (AVFormatContext * s, int discard) url_fseek (bc, ost->pos, SEEK_SET); ogg->curidx = ost->curidx; - memcpy (ogg->streams, ost->streams, - ogg->nstreams * sizeof (*ogg->streams)); + ogg->nstreams = ost->nstreams; + memcpy(ogg->streams, ost->streams, + ost->nstreams * sizeof(*ogg->streams)); } av_free (ost); @@ -198,10 +201,9 @@ ogg_new_stream (AVFormatContext * s, uint32_t serial) st = av_new_stream (s, idx); if (!st) - return AVERROR_NOMEM; + return AVERROR(ENOMEM); av_set_pts_info(st, 64, 1, 1000000); - st->start_time = 0; return idx; } @@ -236,7 +238,7 @@ ogg_read_page (AVFormatContext * s, int *str) uint32_t seq; uint32_t crc; int size, idx; - char sync[4]; + uint8_t sync[4]; int sp = 0; if (get_buffer (bc, sync, 4) < 4) @@ -308,7 +310,6 @@ ogg_read_page (AVFormatContext * s, int *str) if (os->bufsize - os->bufpos < size){ uint8_t *nb = av_malloc (os->bufsize *= 2); - memset (nb, 0, os->bufsize); memcpy (nb, os->buf, os->bufpos); av_free (os->buf); os->buf = nb; @@ -484,7 +485,8 @@ ogg_get_length (AVFormatContext * s) url_fseek (&s->pb, end, SEEK_SET); while (!ogg_read_page (s, &i)){ - if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) + if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && + ogg->streams[i].codec) idx = i; } @@ -495,6 +497,16 @@ ogg_get_length (AVFormatContext * s) ogg->size = size; ogg_restore (s, 0); + ogg_save (s); + while (!ogg_read_page (s, &i)) { + if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) + break; + } + if (i == idx) { + s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule); + s->streams[idx]->duration -= s->streams[idx]->start_time; + } + ogg_restore (s, 0); return 0; } @@ -529,7 +541,7 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt) //Get an ogg packet do{ if (ogg_packet (s, &idx, &pstart, &psize) < 0) - return AVERROR_IO; + return AVERROR(EIO); }while (idx < 0 || !s->streams[idx]); ogg = s->priv_data; @@ -537,7 +549,7 @@ ogg_read_packet (AVFormatContext * s, AVPacket * pkt) //Alloc a pkt if (av_new_packet (pkt, psize) < 0) - return AVERROR_IO; + return AVERROR(EIO); pkt->stream_index = idx; memcpy (pkt->data, os->buf + pstart, psize); if (os->lastgp != -1LL){ @@ -572,12 +584,14 @@ ogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts, ogg_t *ogg = s->priv_data; ByteIOContext *bc = &s->pb; uint64_t min = 0, max = ogg->size; - uint64_t tmin = 0, tmax = st->duration; + uint64_t tmin = st->start_time, tmax = st->start_time + st->duration; int64_t pts = AV_NOPTS_VALUE; ogg_save (s); - while (min <= max){ + if ((uint64_t)target_ts < tmin || target_ts < 0) + target_ts = tmin; + while (min <= max && tmin < tmax){ uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin); int i = -1; @@ -595,19 +609,35 @@ ogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts, pts = ogg_gptopts (s, i, ogg->streams[i].granule); p = url_ftell (bc); - if (ABS (pts - target_ts) * st->time_base.num < st->time_base.den) + if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den) break; if (pts > target_ts){ + if (max == p && tmax == pts) { + // probably our tmin is wrong, causing us to always end up too late in the file + tmin = (target_ts + tmin + 1) / 2; + if (tmin == target_ts) { + url_fseek(bc, min, SEEK_SET); + break; + } + } max = p; tmax = pts; }else{ + if (min == p && tmin == pts) { + // probably our tmax is wrong, causing us to always end up too early in the file + tmax = (target_ts + tmax) / 2; + if (tmax == target_ts) { + url_fseek(bc, max, SEEK_SET); + break; + } + } min = p; tmin = pts; } } - if (ABS (pts - target_ts) * st->time_base.num < st->time_base.den){ + if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den){ ogg_restore (s, 1); ogg_reset (ogg); }else{ @@ -615,7 +645,8 @@ ogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts, pts = AV_NOPTS_VALUE; } - return pts; + av_update_cur_dts(s, st, pts); + return 0; #if 0 //later... @@ -646,8 +677,6 @@ ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, static int ogg_probe(AVProbeData *p) { - if (p->buf_size < 6) - return 0; if (p->buf[0] == 'O' && p->buf[1] == 'g' && p->buf[2] == 'g' && p->buf[3] == 'S' && p->buf[4] == 0x0 && p->buf[5] <= 0x7 ) @@ -656,7 +685,7 @@ static int ogg_probe(AVProbeData *p) return 0; } -static AVInputFormat ogg_demuxer = { +AVInputFormat ogg_demuxer = { "ogg", "Ogg", sizeof (ogg_t), @@ -668,13 +697,3 @@ static AVInputFormat ogg_demuxer = { // ogg_read_timestamp, .extensions = "ogg", }; - -int -ogg_init (void) -{ -#if 0 // CONFIG_MUXERS - av_register_output_format (&ogg_muxer); -#endif - av_register_input_format (&ogg_demuxer); - return 0; -}