On Fri, 19 Apr 2013 10:56:33 +0200, Luca Barbato <[email protected]> wrote:
> Most formats do not support negative timestamps, shift them to avoid
> unexpected behaviour and a number of bad crashes.
> 
> Signed-off-by: Anton Khirnov <[email protected]>
> Signed-off-by: Luca Barbato <[email protected]>
> ---
> 
> Now with additional safety check.
> 
>  libavformat/avformat.h    | 17 +++++++++++++++
>  libavformat/ffmenc.c      |  1 +
>  libavformat/framecrcenc.c |  3 ++-
>  libavformat/md5enc.c      |  3 ++-
>  libavformat/mux.c         | 32 +++++++++++++++++++++++++---
>  libavformat/oggenc.c      |  1 +
>  tests/ref/lavf/asf        |  4 ++--
>  tests/ref/lavf/mkv        |  2 +-
>  tests/ref/lavf/mpg        |  2 +-
>  tests/ref/lavf/ts         |  2 +-
>  tests/ref/seek/lavf-asf   | 54 
> +++++++++++++++++++++++------------------------
>  tests/ref/seek/lavf-mkv   | 44 +++++++++++++++++++-------------------
>  tests/ref/seek/lavf-mpg   | 54 
> +++++++++++++++++++++++------------------------
>  tests/ref/seek/lavf-ts    | 54 
> +++++++++++++++++++++++------------------------
>  14 files changed, 160 insertions(+), 113 deletions(-)
> 
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 067a787..2512e36 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -360,6 +360,11 @@ typedef struct AVProbeData {
>  #define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
>                                          increasing timestamps, but they must
>                                          still be monotonic */
> +#define AVFMT_TS_NEGATIVE  0x40000 /**< Format allows muxing negative
> +                                        timestamps. If not set the timestamp
> +                                        will be shifted in av_write_frame and
> +                                        av_interleaved_write_frame so they
> +                                        start from 0. */
> 
>  /**
>   * @addtogroup lavf_encoding
> @@ -1021,6 +1026,18 @@ typedef struct AVFormatContext {
>       */
>  #define RAW_PACKET_BUFFER_SIZE 2500000
>      int raw_packet_buffer_remaining_size;
> +
> +    /**
> +     * Offset to remap timestamps to be non-negative.
> +     * Expressed in timebase units.
> +     */
> +    int64_t offset;
> +
> +    /**
> +     * Timebase for the timestamp offset.
> +     */
> +    AVRational offset_timebase;
> +
>  } AVFormatContext;
> 
>  typedef struct AVPacketList {
> diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
> index 386487f..91658e1 100644
> --- a/libavformat/ffmenc.c
> +++ b/libavformat/ffmenc.c
> @@ -245,4 +245,5 @@ AVOutputFormat ff_ffm_muxer = {
>      .write_header      = ffm_write_header,
>      .write_packet      = ffm_write_packet,
>      .write_trailer     = ffm_write_trailer,
> +    .flags             = AVFMT_TS_NEGATIVE,
>  };
> diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
> index de6fa2b..fed0cca 100644
> --- a/libavformat/framecrcenc.c
> +++ b/libavformat/framecrcenc.c
> @@ -43,5 +43,6 @@ AVOutputFormat ff_framecrc_muxer = {
>      .video_codec       = AV_CODEC_ID_RAWVIDEO,
>      .write_header      = ff_framehash_write_header,
>      .write_packet      = framecrc_write_packet,
> -    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
> +    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
> +                         AVFMT_TS_NEGATIVE,
>  };
> diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
> index 16412c9..9249704 100644
> --- a/libavformat/md5enc.c
> +++ b/libavformat/md5enc.c
> @@ -127,6 +127,7 @@ AVOutputFormat ff_framemd5_muxer = {
>      .write_header      = framemd5_write_header,
>      .write_packet      = framemd5_write_packet,
>      .write_trailer     = framemd5_write_trailer,
> -    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
> +    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
> +                         AVFMT_TS_NEGATIVE,
>  };
>  #endif
> diff --git a/libavformat/mux.c b/libavformat/mux.c
> index 76b0fb4..c0d5bec 100644
> --- a/libavformat/mux.c
> +++ b/libavformat/mux.c
> @@ -391,6 +391,32 @@ static int compute_pkt_fields2(AVFormatContext *s, 
> AVStream *st, AVPacket *pkt)
>      return 0;
>  }
> 
> +static int write_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> +    if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS))) {
> +        AVRational time_base = s->streams[pkt->stream_index]->time_base;
> +        int64_t offset = 0;
> +
> +        if (pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE) {
> +            av_log(s, AV_LOG_ERROR, "Invalid timestamp: %s not set.\n",
> +                   pkt->pts == AV_NOPTS_VALUE ? "pts" : "dts");
> +            return AVERROR(EINVAL);

I don't think it's a good idea to introduce such an error
a) at all
b) here of all places

Just make it not offset anything if the values are invalid.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to