summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Bœsch <clement.boesch@smartjog.com>2012-10-05 16:46:01 +0200
committerClément Bœsch <ubitux@gmail.com>2012-10-08 09:03:19 +0200
commitf7c46d251c9a2d645568c2c38c543e5e31fac812 (patch)
treeafc0502c0544d751c7ced9bdba2175e7b0ff3c48
parent9425dc3dba0bd1209aa7a788ea8f3c194fc7c7c5 (diff)
ffserver: fix seeking with ?date=...
Regression since 5f847bf61dca1fd1a2f65a2f56c9a99d1cb716ab. After this commit, timestamps pushed by FFmpeg won't be relative anymore, but absolute (based on the date/time at the beginning of the push). This will allow seeking to work properly. Before this patch, the seek was done, but ffm timestamps were way smallers than the absolute requested timestamp (based on a date), so the seek was done, but to the end of the stream (which was similar to no effect at all).
-rw-r--r--ffmpeg_opt.c5
-rw-r--r--libavformat/ffm.h1
-rw-r--r--libavformat/ffmenc.c13
3 files changed, 16 insertions, 3 deletions
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index bce66f825b..323ae8b869 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1368,8 +1368,11 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
choose_pixel_fmt(st, codec, st->codec->pix_fmt);
}
+ /* ffserver seeking with date=... needs a date reference */
+ err = parse_option(o, "metadata", "creation_time=now", options);
+
avformat_close_input(&ic);
- return 0;
+ return err;
}
static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
diff --git a/libavformat/ffm.h b/libavformat/ffm.h
index 04f19cc88e..49402355f4 100644
--- a/libavformat/ffm.h
+++ b/libavformat/ffm.h
@@ -54,6 +54,7 @@ typedef struct FFMContext {
int64_t dts;
uint8_t *packet_ptr, *packet_end;
uint8_t packet[FFM_PACKET_SIZE];
+ int64_t start_time;
} FFMContext;
int64_t ffm_read_write_index(int fd);
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index fb397aff37..d43b7d44da 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -22,6 +22,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/avassert.h"
+#include "libavutil/parseutils.h"
#include "avformat.h"
#include "internal.h"
#include "ffm.h"
@@ -85,11 +86,18 @@ static void ffm_write_data(AVFormatContext *s,
static int ffm_write_header(AVFormatContext *s)
{
FFMContext *ffm = s->priv_data;
+ AVDictionaryEntry *t;
AVStream *st;
AVIOContext *pb = s->pb;
AVCodecContext *codec;
int bit_rate, i;
+ if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
+ int ret = av_parse_time(&ffm->start_time, t->value, 0);
+ if (ret < 0)
+ return ret;
+ }
+
ffm->packet_size = FFM_PACKET_SIZE;
/* header */
@@ -198,11 +206,12 @@ static int ffm_write_header(AVFormatContext *s)
static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
{
+ FFMContext *ffm = s->priv_data;
int64_t dts;
uint8_t header[FRAME_HEADER_SIZE+4];
int header_size = FRAME_HEADER_SIZE;
- dts = pkt->dts;
+ dts = ffm->start_time + pkt->dts;
/* packet size & key_frame */
header[0] = pkt->stream_index;
header[1] = 0;
@@ -210,7 +219,7 @@ static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
header[1] |= FLAG_KEY_FRAME;
AV_WB24(header+2, pkt->size);
AV_WB24(header+5, pkt->duration);
- AV_WB64(header+8, pkt->pts);
+ AV_WB64(header+8, ffm->start_time + pkt->pts);
if (pkt->pts != pkt->dts) {
header[1] |= FLAG_DTS;
AV_WB32(header+16, pkt->pts - pkt->dts);