Commit 194be1f4 authored by Anton Khirnov's avatar Anton Khirnov

lavf: switch to AVStream.time_base as the hint for the muxer timebase

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.

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).
parent d754ed41
...@@ -13,6 +13,11 @@ libavutil: 2013-12-xx ...@@ -13,6 +13,11 @@ libavutil: 2013-12-xx
API changes, most recent first: API changes, most recent first:
2014-xx-xx - xxxxxxx - lavf 55.20.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 2014-04-xx - xxxxxxx - lavc 55.54.0 - avcodec.h
Add AVCodecContext.side_data_only_packets to allow encoders to output packets 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 with only side data. This option may become mandatory in the future, so all
......
...@@ -710,9 +710,12 @@ typedef struct AVStream { ...@@ -710,9 +710,12 @@ typedef struct AVStream {
* of which frame timestamps are represented. * of which frame timestamps are represented.
* *
* decoding: set by libavformat * decoding: set by libavformat
* encoding: set by libavformat in avformat_write_header. The muxer may use the * encoding: May be set by the caller before avformat_write_header() to
* user-provided value of @ref AVCodecContext.time_base "codec->time_base" * provide a hint to the muxer about the desired timebase. In
* as a hint. * 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; AVRational time_base;
......
...@@ -144,6 +144,7 @@ static int avi_write_header(AVFormatContext *s) ...@@ -144,6 +144,7 @@ static int avi_write_header(AVFormatContext *s)
AVIOContext *pb = s->pb; AVIOContext *pb = s->pb;
int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;
AVCodecContext *video_enc; AVCodecContext *video_enc;
AVStream *video_st = NULL;
int64_t list1, list2, strh, strf; int64_t list1, list2, strh, strf;
AVDictionaryEntry *t = NULL; AVDictionaryEntry *t = NULL;
...@@ -172,15 +173,18 @@ static int avi_write_header(AVFormatContext *s) ...@@ -172,15 +173,18 @@ static int avi_write_header(AVFormatContext *s)
for (n = 0; n < s->nb_streams; n++) { for (n = 0; n < s->nb_streams; n++) {
AVCodecContext *codec = s->streams[n]->codec; AVCodecContext *codec = s->streams[n]->codec;
bitrate += codec->bit_rate; bitrate += codec->bit_rate;
if (codec->codec_type == AVMEDIA_TYPE_VIDEO) if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
video_enc = codec; video_enc = codec;
video_st = s->streams[n];
}
} }
nb_frames = 0; nb_frames = 0;
if (video_enc) // TODO: should be avg_frame_rate
avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_enc->time_base.num / if (video_st)
video_enc->time_base.den)); avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num /
video_st->time_base.den));
else else
avio_wl32(pb, 0); avio_wl32(pb, 0);
avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
...@@ -337,7 +341,8 @@ static int avi_write_header(AVFormatContext *s) ...@@ -337,7 +341,8 @@ static int avi_write_header(AVFormatContext *s)
avio_wl32(pb, 0); // video format = unknown avio_wl32(pb, 0); // video format = unknown
avio_wl32(pb, 0); // video standard = 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->width);
avio_wl32(pb, enc->height); avio_wl32(pb, enc->height);
avio_wl16(pb, den); avio_wl16(pb, den);
......
...@@ -64,7 +64,8 @@ static int write_trailer(AVFormatContext *s) ...@@ -64,7 +64,8 @@ static int write_trailer(AVFormatContext *s)
avio_wb16(pb, st->codec->width); avio_wb16(pb, st->codec->width);
avio_wb16(pb, st->codec->height); avio_wb16(pb, st->codec->height);
avio_wb16(pb, 0); // leading 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++) for (i = 0; i < 16; i++)
avio_w8(pb, 0x00); // reserved avio_w8(pb, 0x00); // reserved
......
...@@ -25,7 +25,6 @@ int ff_framehash_write_header(AVFormatContext *s) ...@@ -25,7 +25,6 @@ int ff_framehash_write_header(AVFormatContext *s)
int i; int i;
for (i = 0; i < s->nb_streams; i++) { for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->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_printf(s->pb, "#tb %d: %d/%d\n", i, st->time_base.num, st->time_base.den);
avio_flush(s->pb); avio_flush(s->pb);
} }
......
...@@ -814,10 +814,10 @@ static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track) ...@@ -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 if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
else tag = MKTAG('d','v','p','p'); else tag = MKTAG('d','v','p','p');
else if (track->enc->height == 720) /* HD 720 line */ 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 tag = MKTAG('d','v','h','p');
else if (track->enc->height == 1080) /* HD 1080 line */ 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 tag = MKTAG('d','v','h','6');
else { else {
av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n"); 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) ...@@ -2656,10 +2656,12 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
static void mov_write_uuidprof_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 *video_codec = s->streams[0]->codec;
AVCodecContext *audio_codec = s->streams[1]->codec; AVCodecContext *audio_codec = s->streams[1]->codec;
int audio_rate = audio_codec->sample_rate; 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 audio_kbitrate = audio_codec->bit_rate / 1000;
int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate); int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
...@@ -3400,7 +3402,7 @@ static int mov_write_header(AVFormatContext *s) ...@@ -3400,7 +3402,7 @@ static int mov_write_header(AVFormatContext *s)
} }
track->height = track->tag >> 24 == 'n' ? 486 : 576; 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) if (track->mode == MODE_MOV && track->timescale > 100000)
av_log(s, AV_LOG_WARNING, av_log(s, AV_LOG_WARNING,
"WARNING codec timebase is very high. If duration is too long,\n" "WARNING codec timebase is very high. If duration is too long,\n"
...@@ -3428,9 +3430,9 @@ static int mov_write_header(AVFormatContext *s) ...@@ -3428,9 +3430,9 @@ static int mov_write_header(AVFormatContext *s)
goto error; goto error;
} }
} else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { } 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) { } 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) if (!track->height)
track->height = st->codec->height; track->height = st->codec->height;
......
...@@ -194,6 +194,7 @@ typedef struct MpegTSWriteStream { ...@@ -194,6 +194,7 @@ typedef struct MpegTSWriteStream {
int payload_flags; int payload_flags;
uint8_t *payload; uint8_t *payload;
AVFormatContext *amux; AVFormatContext *amux;
AVRational user_tb;
} MpegTSWriteStream; } MpegTSWriteStream;
static void mpegts_write_pat(AVFormatContext *s) static void mpegts_write_pat(AVFormatContext *s)
...@@ -480,13 +481,17 @@ static int mpegts_write_header(AVFormatContext *s) ...@@ -480,13 +481,17 @@ static int mpegts_write_header(AVFormatContext *s)
/* assign pids to each stream */ /* assign pids to each stream */
for(i = 0;i < s->nb_streams; i++) { for(i = 0;i < s->nb_streams; i++) {
st = s->streams[i]; st = s->streams[i];
avpriv_set_pts_info(st, 33, 1, 90000);
ts_st = av_mallocz(sizeof(MpegTSWriteStream)); ts_st = av_mallocz(sizeof(MpegTSWriteStream));
if (!ts_st) { if (!ts_st) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
st->priv_data = ts_st; 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); ts_st->payload = av_mallocz(ts->pes_payload_size);
if (!ts_st->payload) { if (!ts_st->payload) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
...@@ -557,7 +562,8 @@ static int mpegts_write_header(AVFormatContext *s) ...@@ -557,7 +562,8 @@ static int mpegts_write_header(AVFormatContext *s)
pcr_st = s->streams[0]; pcr_st = s->streams[0];
ts_st = pcr_st->priv_data; ts_st = pcr_st->priv_data;
service->pcr_pid = ts_st->pid; service->pcr_pid = ts_st->pid;
} } else
ts_st = pcr_st->priv_data;
if (ts->mux_rate > 1) { if (ts->mux_rate > 1) {
service->pcr_packet_period = (ts->mux_rate * ts->pcr_period) / service->pcr_packet_period = (ts->mux_rate * ts->pcr_period) /
...@@ -583,8 +589,9 @@ static int mpegts_write_header(AVFormatContext *s) ...@@ -583,8 +589,9 @@ static int mpegts_write_header(AVFormatContext *s)
} }
} else { } else {
// max delta PCR 0.1s // max delta PCR 0.1s
// TODO: should be avg_frame_rate
service->pcr_packet_period = 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);
} }
} }
......
...@@ -115,6 +115,25 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) ...@@ -115,6 +115,25 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
st = s->streams[i]; st = s->streams[i];
codec = st->codec; codec = st->codec;
#if FF_API_LAVF_CODEC_TB
FF_DISABLE_DEPRECATION_WARNINGS
if (!st->time_base.num && codec->time_base.num) {
av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a "
"timebase hint to the muxer is deprecated. Set "
"AVStream.time_base instead.\n");
avpriv_set_pts_info(st, 64, codec->time_base.num, codec->time_base.den);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
if (!st->time_base.num) {
/* fall back on the default timebase values */
if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->sample_rate)
avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
else
avpriv_set_pts_info(st, 33, 1, 90000);
}
switch (codec->codec_type) { switch (codec->codec_type) {
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
if (codec->sample_rate <= 0) { if (codec->sample_rate <= 0) {
...@@ -127,13 +146,6 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) ...@@ -127,13 +146,6 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
av_get_bits_per_sample(codec->codec_id) >> 3; av_get_bits_per_sample(codec->codec_id) >> 3;
break; break;
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
if (codec->time_base.num <= 0 ||
codec->time_base.den <= 0) { //FIXME audio too?
av_log(s, AV_LOG_ERROR, "time base not set\n");
ret = AVERROR(EINVAL);
goto fail;
}
if ((codec->width <= 0 || codec->height <= 0) && if ((codec->width <= 0 || codec->height <= 0) &&
!(of->flags & AVFMT_NODIMENSIONS)) { !(of->flags & AVFMT_NODIMENSIONS)) {
av_log(s, AV_LOG_ERROR, "dimensions not set\n"); av_log(s, AV_LOG_ERROR, "dimensions not set\n");
......
...@@ -1433,11 +1433,12 @@ static int mxf_write_header(AVFormatContext *s) ...@@ -1433,11 +1433,12 @@ static int mxf_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR, "video stream must be first track\n"); av_log(s, AV_LOG_ERROR, "video stream must be first track\n");
return -1; return -1;
} }
if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) { // TODO: should be avg_frame_rate
if (fabs(av_q2d(st->time_base) - 1/25.0) < 0.0001) {
samples_per_frame = PAL_samples_per_frame; samples_per_frame = PAL_samples_per_frame;
mxf->time_base = (AVRational){ 1, 25 }; mxf->time_base = (AVRational){ 1, 25 };
mxf->timecode_base = 25; mxf->timecode_base = 25;
} else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) { } else if (fabs(av_q2d(st->time_base) - 1001/30000.0) < 0.0001) {
samples_per_frame = NTSC_samples_per_frame; samples_per_frame = NTSC_samples_per_frame;
mxf->time_base = (AVRational){ 1001, 30000 }; mxf->time_base = (AVRational){ 1001, 30000 };
mxf->timecode_base = 30; mxf->timecode_base = 30;
......
...@@ -428,8 +428,7 @@ static int ogg_write_header(AVFormatContext *s) ...@@ -428,8 +428,7 @@ static int ogg_write_header(AVFormatContext *s)
avpriv_set_pts_info(st, 64, 1, 48000); avpriv_set_pts_info(st, 64, 1, 48000);
else else
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
if (st->codec->codec_id != AV_CODEC_ID_VORBIS && if (st->codec->codec_id != AV_CODEC_ID_VORBIS &&
st->codec->codec_id != AV_CODEC_ID_THEORA && st->codec->codec_id != AV_CODEC_ID_THEORA &&
st->codec->codec_id != AV_CODEC_ID_SPEEX && st->codec->codec_id != AV_CODEC_ID_SPEEX &&
......
...@@ -230,8 +230,8 @@ void ff_parse_specific_params(AVStream *st, int *au_rate, ...@@ -230,8 +230,8 @@ void ff_parse_specific_params(AVStream *st, int *au_rate,
} else if (codec->codec_type == AVMEDIA_TYPE_VIDEO || } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
codec->codec_type == AVMEDIA_TYPE_DATA || codec->codec_type == AVMEDIA_TYPE_DATA ||
codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
*au_scale = codec->time_base.num; *au_scale = st->time_base.num;
*au_rate = codec->time_base.den; *au_rate = st->time_base.den;
} else { } else {
*au_scale = codec->block_align ? codec->block_align * 8 : 8; *au_scale = codec->block_align ? codec->block_align * 8 : 8;
*au_rate = codec->bit_rate ? codec->bit_rate : *au_rate = codec->bit_rate ? codec->bit_rate :
......
...@@ -310,6 +310,8 @@ static int rm_write_header(AVFormatContext *s) ...@@ -310,6 +310,8 @@ static int rm_write_header(AVFormatContext *s)
AVCodecContext *codec; AVCodecContext *codec;
for(n=0;n<s->nb_streams;n++) { for(n=0;n<s->nb_streams;n++) {
AVStream *st = s->streams[n];
s->streams[n]->id = n; s->streams[n]->id = n;
codec = s->streams[n]->codec; codec = s->streams[n]->codec;
stream = &rm->streams[n]; stream = &rm->streams[n];
...@@ -329,7 +331,8 @@ static int rm_write_header(AVFormatContext *s) ...@@ -329,7 +331,8 @@ static int rm_write_header(AVFormatContext *s)
break; break;
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
rm->video_stream = stream; rm->video_stream = stream;
stream->frame_rate = (float)codec->time_base.den / (float)codec->time_base.num; // TODO: should be avg_frame_rate
stream->frame_rate = (float)st->time_base.den / (float)st->time_base.num;
/* XXX: dummy values */ /* XXX: dummy values */
stream->packet_max_size = 4096; stream->packet_max_size = 4096;
stream->nb_packets = 0; stream->nb_packets = 0;
......
...@@ -76,6 +76,7 @@ typedef struct SWFContext { ...@@ -76,6 +76,7 @@ typedef struct SWFContext {
int tag; int tag;
AVFifoBuffer *audio_fifo; AVFifoBuffer *audio_fifo;
AVCodecContext *audio_enc, *video_enc; AVCodecContext *audio_enc, *video_enc;
AVStream *video_st;
} SWFContext; } SWFContext;
extern const AVCodecTag ff_swf_codec_tags[]; extern const AVCodecTag ff_swf_codec_tags[];
......
...@@ -207,6 +207,7 @@ static int swf_write_header(AVFormatContext *s) ...@@ -207,6 +207,7 @@ static int swf_write_header(AVFormatContext *s)
if (enc->codec_id == AV_CODEC_ID_VP6F || if (enc->codec_id == AV_CODEC_ID_VP6F ||
enc->codec_id == AV_CODEC_ID_FLV1 || enc->codec_id == AV_CODEC_ID_FLV1 ||
enc->codec_id == AV_CODEC_ID_MJPEG) { enc->codec_id == AV_CODEC_ID_MJPEG) {
swf->video_st = s->streams[i];
swf->video_enc = enc; swf->video_enc = enc;
} else { } else {
av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n"); av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n");
...@@ -224,8 +225,9 @@ static int swf_write_header(AVFormatContext *s) ...@@ -224,8 +225,9 @@ static int swf_write_header(AVFormatContext *s)
} else { } else {
width = swf->video_enc->width; width = swf->video_enc->width;
height = swf->video_enc->height; height = swf->video_enc->height;
rate = swf->video_enc->time_base.den; // TODO: should be avg_frame_rate
rate_base = swf->video_enc->time_base.num; rate = swf->video_st->time_base.den;
rate_base = swf->video_st->time_base.num;
} }
if (!swf->audio_enc) if (!swf->audio_enc)
......
...@@ -2663,9 +2663,14 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c) ...@@ -2663,9 +2663,14 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
} }
st->codec = avcodec_alloc_context3(c); st->codec = avcodec_alloc_context3(c);
if (s->iformat) if (s->iformat) {
/* no default bitrate if decoding */ /* no default bitrate if decoding */
st->codec->bit_rate = 0; st->codec->bit_rate = 0;
/* default pts setting is MPEG-like */
avpriv_set_pts_info(st, 33, 1, 90000);
}
st->index = s->nb_streams; st->index = s->nb_streams;
st->start_time = AV_NOPTS_VALUE; st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE; st->duration = AV_NOPTS_VALUE;
...@@ -2677,8 +2682,6 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c) ...@@ -2677,8 +2682,6 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
st->first_dts = AV_NOPTS_VALUE; st->first_dts = AV_NOPTS_VALUE;
st->probe_packets = MAX_PROBE_PACKETS; st->probe_packets = MAX_PROBE_PACKETS;
/* default pts setting is MPEG-like */
avpriv_set_pts_info(st, 33, 1, 90000);
st->last_IP_pts = AV_NOPTS_VALUE; st->last_IP_pts = AV_NOPTS_VALUE;
for (i = 0; i < MAX_REORDER_DELAY + 1; i++) for (i = 0; i < MAX_REORDER_DELAY + 1; i++)
st->pts_buffer[i] = AV_NOPTS_VALUE; st->pts_buffer[i] = AV_NOPTS_VALUE;
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include "libavutil/version.h" #include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 55 #define LIBAVFORMAT_VERSION_MAJOR 55
#define LIBAVFORMAT_VERSION_MINOR 19 #define LIBAVFORMAT_VERSION_MINOR 20
#define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
...@@ -57,5 +57,8 @@ ...@@ -57,5 +57,8 @@
#ifndef FF_API_LAVF_FRAC #ifndef FF_API_LAVF_FRAC
#define FF_API_LAVF_FRAC (LIBAVFORMAT_VERSION_MAJOR < 57) #define FF_API_LAVF_FRAC (LIBAVFORMAT_VERSION_MAJOR < 57)
#endif #endif
#ifndef FF_API_LAVF_CODEC_TB
#define FF_API_LAVF_CODEC_TB (LIBAVFORMAT_VERSION_MAJOR < 57)
#endif
#endif /* AVFORMAT_VERSION_H */ #endif /* AVFORMAT_VERSION_H */
...@@ -38,8 +38,9 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf) ...@@ -38,8 +38,9 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf)
width = st->codec->width; width = st->codec->width;
height = st->codec->height; height = st->codec->height;
av_reduce(&raten, &rated, st->codec->time_base.den, // TODO: should be avg_frame_rate
st->codec->time_base.num, (1UL << 31) - 1); av_reduce(&raten, &rated, st->time_base.den,
st->time_base.num, (1UL << 31) - 1);
aspectn = st->sample_aspect_ratio.num; aspectn = st->sample_aspect_ratio.num;
aspectd = st->sample_aspect_ratio.den; aspectd = st->sample_aspect_ratio.den;
......
268fb8f9278b0df2f87a6a9455f3cd56 *./tests/data/lavf/lavf.mkv 268fb8f9278b0df2f87a6a9455f3cd56 *./tests/data/lavf/lavf.mkv
320380 ./tests/data/lavf/lavf.mkv 320380 ./tests/data/lavf/lavf.mkv
./tests/data/lavf/lavf.mkv CRC=0xbe7d3cda ./tests/data/lavf/lavf.mkv CRC=0x36193cda
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment