summaryrefslogtreecommitdiff
path: root/libavformat/ffmdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/ffmdec.c')
-rw-r--r--libavformat/ffmdec.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index e6730eb2f5..028f1ee797 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
*/
@@ -24,6 +24,7 @@
#include "avformat.h"
#include "internal.h"
#include "ffm.h"
+#include "avio_internal.h"
static int ffm_is_avail_data(AVFormatContext *s, int size)
{
@@ -60,7 +61,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;
}
@@ -89,6 +90,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);
+ ffio_set_buf_size(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)
@@ -105,8 +111,8 @@ static int ffm_read_data(AVFormatContext *s,
if (ffm->first_packet || (frame_offset & 0x8000)) {
if (!frame_offset) {
/* This packet has no frame headers in it */
- if (avio_tell(pb) >= ffm->packet_size * 3) {
- avio_seek(pb, -ffm->packet_size * 2, SEEK_CUR);
+ if (avio_tell(pb) >= ffm->packet_size * 3LL) {
+ avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR);
goto retry_read;
}
/* This is bad, we cannot find a valid frame header */
@@ -243,7 +249,7 @@ static int ffm_read_header(AVFormatContext *s)
/* get also filesize */
if (pb->seekable) {
ffm->file_size = avio_size(pb);
- if (ffm->write_index)
+ if (ffm->write_index && 0)
adjust_write_index(s);
} else {
ffm->file_size = (UINT64_C(1) << 63) - 1;
@@ -380,7 +386,9 @@ static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt)
duration = AV_RB24(ffm->header + 5);
- av_new_packet(pkt, size);
+ if (av_new_packet(pkt, size) < 0) {
+ return AVERROR(ENOMEM);
+ }
pkt->stream_index = ffm->header[0];
if ((unsigned)pkt->stream_index >= s->nb_streams) {
av_log(s, AV_LOG_ERROR, "invalid stream index %d\n", pkt->stream_index);
@@ -422,11 +430,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);
@@ -471,7 +493,7 @@ static int ffm_probe(AVProbeData *p)
AVInputFormat ff_ffm_demuxer = {
.name = "ffm",
- .long_name = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed)"),
+ .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
.priv_data_size = sizeof(FFMContext),
.read_probe = ffm_probe,
.read_header = ffm_read_header,