diff options
Diffstat (limited to 'libavformat/ffmdec.c')
-rw-r--r-- | libavformat/ffmdec.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index b9516d5b8b..5fa2de3dfb 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -1,21 +1,21 @@ /* - * FFM (avserver live feed) demuxer + * FFM (ffserver live feed) demuxer * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,7 +23,7 @@ #include "libavutil/intfloat_readwrite.h" #include "avformat.h" #include "ffm.h" -#if CONFIG_AVSERVER +#if CONFIG_FFSERVER #include <unistd.h> int64_t ffm_read_write_index(int fd) @@ -55,7 +55,7 @@ void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size) ffm->write_index = pos; ffm->file_size = file_size; } -#endif // CONFIG_AVSERVER +#endif // CONFIG_FFSERVER static int ffm_is_avail_data(AVFormatContext *s, int size) { @@ -92,7 +92,7 @@ static int ffm_resync(AVFormatContext *s, int state) { av_log(s, AV_LOG_ERROR, "resyncing\n"); while (state != PACKET_ID) { - if (s->pb->eof_reached) { + if (url_feof(s->pb)) { av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n"); return -1; } @@ -121,6 +121,11 @@ static int ffm_read_data(AVFormatContext *s, if (avio_tell(pb) == ffm->file_size) avio_seek(pb, ffm->packet_size, SEEK_SET); retry_read: + if (pb->buffer_size != ffm->packet_size) { + int64_t tell = avio_tell(pb); + url_setbufsize(pb, ffm->packet_size); + avio_seek(pb, tell, SEEK_SET); + } id = avio_rb16(pb); /* PACKET_ID */ if (id != PACKET_ID) if (ffm_resync(s, id) < 0) @@ -166,7 +171,7 @@ static int ffm_read_data(AVFormatContext *s, /* ensure that acutal seeking happens between FFM_PACKET_SIZE and file_size - FFM_PACKET_SIZE */ -static void ffm_seek1(AVFormatContext *s, int64_t pos1) +static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1) { FFMContext *ffm = s->priv_data; AVIOContext *pb = s->pb; @@ -175,7 +180,7 @@ static void ffm_seek1(AVFormatContext *s, int64_t pos1) pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE); pos = FFMAX(pos, FFM_PACKET_SIZE); av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos); - avio_seek(pb, pos, SEEK_SET); + return avio_seek(pb, pos, SEEK_SET); } static int64_t get_dts(AVFormatContext *s, int64_t pos) @@ -319,8 +324,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) codec->qcompress = avio_rb16(pb) / 10000.0; codec->qblur = avio_rb16(pb) / 10000.0; codec->bit_rate_tolerance = avio_rb32(pb); - avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); - codec->rc_eq = av_strdup(rc_eq_buf); + codec->rc_eq = av_strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf))); codec->rc_max_rate = avio_rb32(pb); codec->rc_min_rate = avio_rb32(pb); codec->rc_buffer_size = avio_rb32(pb); @@ -344,6 +348,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) codec->thread_count = avio_r8(pb); codec->coder_type = avio_rb32(pb); codec->me_cmp = avio_rb32(pb); + codec->partitions = avio_rb32(pb); codec->me_subpel_quality = avio_rb32(pb); codec->me_range = avio_rb32(pb); codec->keyint_min = avio_rb32(pb); @@ -353,6 +358,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) codec->qblur = av_int2dbl(avio_rb64(pb)); codec->max_qdiff = avio_rb32(pb); codec->refs = avio_rb32(pb); + codec->directpred = avio_rb32(pb); break; case AVMEDIA_TYPE_AUDIO: codec->sample_rate = avio_rb32(pb); @@ -460,11 +466,25 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0); /* find the position using linear interpolation (better than dichotomy in typical cases) */ - pos_min = FFM_PACKET_SIZE; - pos_max = ffm->file_size - FFM_PACKET_SIZE; + if (ffm->write_index && ffm->write_index < ffm->file_size) { + if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) { + pos_min = FFM_PACKET_SIZE; + pos_max = ffm->write_index - FFM_PACKET_SIZE; + } else { + pos_min = ffm->write_index; + pos_max = ffm->file_size - FFM_PACKET_SIZE; + } + } else { + pos_min = FFM_PACKET_SIZE; + pos_max = ffm->file_size - FFM_PACKET_SIZE; + } while (pos_min <= pos_max) { pts_min = get_dts(s, pos_min); pts_max = get_dts(s, pos_max); + if (pts_min > wanted_pts || pts_max < wanted_pts) { + pos = pts_min > wanted_pts ? pos_min : pos_max; + goto found; + } /* linear interpolation */ pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) / (double)(pts_max - pts_min); @@ -486,7 +506,8 @@ static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, in pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; found: - ffm_seek1(s, pos); + if (ffm_seek1(s, pos) < 0) + return -1; /* reset read state */ ffm->read_state = READ_HEADER; @@ -508,7 +529,7 @@ static int ffm_probe(AVProbeData *p) AVInputFormat ff_ffm_demuxer = { .name = "ffm", - .long_name = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed) format"), + .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed) format"), .priv_data_size = sizeof(FFMContext), .read_probe = ffm_probe, .read_header = ffm_read_header, |