On Sun, 1 Jun 2014, Anton Khirnov wrote:

Previously, AVStream.codec.time_base was used for that purpose, which
was quite confusing for the callers. This change also opens the path for
removing AVStream.codec.

How would the codec parameters be passed to muxers in this case?

The change in the lavf-mkv test is due to the native timebase (1/1000)
being used instead of the default one (1/90000), so the packets are now
sent to the crc muxer in the same order in which they are demuxed
(previously some of them got reordered because of inexact timestamp
conversion).
---
doc/APIchanges             |    5 +++++
libavformat/avformat.h     |    9 ++++++---
libavformat/avienc.c       |   15 ++++++++++-----
libavformat/filmstripenc.c |    3 ++-
libavformat/framehash.c    |    1 -
libavformat/movenc.c       |   14 ++++++++------
libavformat/mpegtsenc.c    |   12 +++++++++---
libavformat/mux.c          |   26 +++++++++++++++++++-------
libavformat/mxfenc.c       |    5 +++--
libavformat/oggenc.c       |    3 +--
libavformat/riffenc.c      |    4 ++--
libavformat/rmenc.c        |    5 ++++-
libavformat/swf.h          |    1 +
libavformat/swfenc.c       |    6 ++++--
libavformat/utils.c        |    9 ++++++---
libavformat/version.h      |    3 +++
libavformat/yuv4mpegenc.c  |    5 +++--
tests/ref/lavf/mkv         |    2 +-
18 files changed, 87 insertions(+), 41 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 952ee51..82774ea 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,11 @@ libavutil:     2013-12-xx

API changes, most recent first:

+2014-xx-xx - xxxxxxx - lavf 55.19.0 - avformat.h
+  The proper way for providing a hint about the desired timebase to the muxers
+  is now setting AVStream.time_base, instead of AVStream.codec.time_base as was
+  done previously. The old method is now deprecated.
+
2014-04-xx - xxxxxxx - lavc 55.54.0 - avcodec.h
  Add AVCodecContext.side_data_only_packets to allow encoders to output packets
  with only side data. This option may become mandatory in the future, so all
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index b17c791..473b8da 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -710,9 +710,12 @@ typedef struct AVStream {
     * of which frame timestamps are represented.
     *
     * decoding: set by libavformat
-     * encoding: set by libavformat in avformat_write_header. The muxer may 
use the
-     * user-provided value of @ref AVCodecContext.time_base "codec->time_base"
-     * as a hint.
+     * encoding: May be set by the caller before avformat_write_header() to
+     *           provide a hint to the muxer about the desired timebase. In
+     *           avformat_write_header(), the muxer will overwrite this field
+     *           with the timebase that will actually be used for the 
timestamps
+     *           written into the file (which may or may not be related to the
+     *           user-provided one, depending on the format).
     */
    AVRational time_base;

diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 87075d4..417a8e9 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -144,6 +144,7 @@ static int avi_write_header(AVFormatContext *s)
    AVIOContext *pb = s->pb;
    int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
    AVCodecContext *video_enc;
+    AVStream *video_st = NULL;
    int64_t list1, list2, strh, strf;
    AVDictionaryEntry *t = NULL;

@@ -172,15 +173,18 @@ static int avi_write_header(AVFormatContext *s)
    for (n = 0; n < s->nb_streams; n++) {
        AVCodecContext *codec = s->streams[n]->codec;
        bitrate += codec->bit_rate;
-        if (codec->codec_type == AVMEDIA_TYPE_VIDEO)
+        if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_enc = codec;
+            video_st = s->streams[n];
+        }
    }

    nb_frames = 0;

-    if (video_enc)
-        avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_enc->time_base.num /
-                                  video_enc->time_base.den));
+    // TODO: should be avg_frame_rate
+    if (video_st)
+        avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num /
+                                  video_st->time_base.den));
    else
        avio_wl32(pb, 0);
    avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
@@ -337,7 +341,8 @@ static int avi_write_header(AVFormatContext *s)

            avio_wl32(pb, 0); // video format   = unknown
            avio_wl32(pb, 0); // video standard = unknown
-            avio_wl32(pb, lrintf(1.0 / av_q2d(enc->time_base)));
+            // TODO: should be avg_frame_rate
+            avio_wl32(pb, lrintf(1.0 / av_q2d(st->time_base)));
            avio_wl32(pb, enc->width);
            avio_wl32(pb, enc->height);
            avio_wl16(pb, den);
diff --git a/libavformat/filmstripenc.c b/libavformat/filmstripenc.c
index 90d9a76..8d1d2d8 100644
--- a/libavformat/filmstripenc.c
+++ b/libavformat/filmstripenc.c
@@ -64,7 +64,8 @@ static int write_trailer(AVFormatContext *s)
    avio_wb16(pb, st->codec->width);
    avio_wb16(pb, st->codec->height);
    avio_wb16(pb, 0);  // leading
-    avio_wb16(pb, 1/av_q2d(st->codec->time_base));
+    // TODO: should be avg_frame_rate
+    avio_wb16(pb, 1/av_q2d(st->time_base));
    for (i = 0; i < 16; i++)
        avio_w8(pb, 0x00);  // reserved

diff --git a/libavformat/framehash.c b/libavformat/framehash.c
index 28e9e84..6a6da98 100644
--- a/libavformat/framehash.c
+++ b/libavformat/framehash.c
@@ -25,7 +25,6 @@ int ff_framehash_write_header(AVFormatContext *s)
    int i;
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
-        avpriv_set_pts_info(st, 64, st->codec->time_base.num, 
st->codec->time_base.den);
        avio_printf(s->pb, "#tb %d: %d/%d\n", i, st->time_base.num, 
st->time_base.den);
        avio_flush(s->pb);
    }
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index dcd3294..f5c36fc 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -814,10 +814,10 @@ static int mov_get_dv_codec_tag(AVFormatContext *s, 
MOVTrack *track)
        else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = 
MKTAG('d','v','c','p');
        else                                                tag = 
MKTAG('d','v','p','p');
    else if (track->enc->height == 720) /* HD 720 line */
-        if  (track->enc->time_base.den == 50)               tag = 
MKTAG('d','v','h','q');
+        if  (track->st->time_base.den == 50)                tag = 
MKTAG('d','v','h','q');
        else                                                tag = 
MKTAG('d','v','h','p');
    else if (track->enc->height == 1080) /* HD 1080 line */
-        if  (track->enc->time_base.den == 25)               tag = 
MKTAG('d','v','h','5');
+        if  (track->st->time_base.den == 25)                tag = 
MKTAG('d','v','h','5');
        else                                                tag = 
MKTAG('d','v','h','6');
    else {
        av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
@@ -2656,10 +2656,12 @@ static int mov_write_ftyp_tag(AVIOContext *pb, 
AVFormatContext *s)

static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
{
+    AVStream       *video_st    = s->streams[0];
    AVCodecContext *video_codec = s->streams[0]->codec;
    AVCodecContext *audio_codec = s->streams[1]->codec;
    int audio_rate = audio_codec->sample_rate;
-    int frame_rate = ((video_codec->time_base.den) * (0x10000)) / 
(video_codec->time_base.num);
+    // TODO: should be avg_frame_rate
+    int frame_rate = ((video_st->time_base.den) * (0x10000)) / 
(video_st->time_base.num);
    int audio_kbitrate = audio_codec->bit_rate / 1000;
    int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - 
audio_kbitrate);

@@ -3400,7 +3402,7 @@ static int mov_write_header(AVFormatContext *s)
                }
                track->height = track->tag >> 24 == 'n' ? 486 : 576;
            }
-            track->timescale = st->codec->time_base.den;
+            track->timescale = st->time_base.den;
            if (track->mode == MODE_MOV && track->timescale > 100000)
                av_log(s, AV_LOG_WARNING,
                       "WARNING codec timebase is very high. If duration is too 
long,\n"
@@ -3428,9 +3430,9 @@ static int mov_write_header(AVFormatContext *s)
                goto error;
            }
        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-            track->timescale = st->codec->time_base.den;
+            track->timescale = st->time_base.den;
        } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
-            track->timescale = st->codec->time_base.den;
+            track->timescale = st->time_base.den;
        }
        if (!track->height)
            track->height = st->codec->height;
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 8efd93e..487de18 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -228,6 +228,7 @@ typedef struct MpegTSWriteStream {
    int payload_flags;
    uint8_t *payload;
    AVFormatContext *amux;
+    AVRational user_tb;
} MpegTSWriteStream;

static void mpegts_write_pat(AVFormatContext *s)
@@ -514,13 +515,17 @@ static int mpegts_write_header(AVFormatContext *s)
    /* assign pids to each stream */
    for(i = 0;i < s->nb_streams; i++) {
        st = s->streams[i];
-        avpriv_set_pts_info(st, 33, 1, 90000);
+
        ts_st = av_mallocz(sizeof(MpegTSWriteStream));
        if (!ts_st) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
        st->priv_data = ts_st;
+
+        ts_st->user_tb = st->time_base;
+        avpriv_set_pts_info(st, 33, 1, 90000);
+
        ts_st->payload = av_mallocz(ts->pes_payload_size);
        if (!ts_st->payload) {
            ret = AVERROR(ENOMEM);
@@ -591,7 +596,8 @@ static int mpegts_write_header(AVFormatContext *s)
        pcr_st = s->streams[0];
        ts_st = pcr_st->priv_data;
        service->pcr_pid = ts_st->pid;
-    }
+    } else
+        ts_st = pcr_st->priv_data;

    if (ts->mux_rate > 1) {
        service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
@@ -618,7 +624,7 @@ static int mpegts_write_header(AVFormatContext *s)
        } else {
            // max delta PCR 0.1s
            service->pcr_packet_period =
-                pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num);
+                ts_st->user_tb.den / (10 * ts_st->user_tb.num);
        }
    }


Doesn't this codepath assume that the input time base is 1/framerate? I.e. I think this also could have a similar comment as the other ones.

The rest of the patch seems ok.

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

Reply via email to