dynamically allocate next_dts and use it in write_packet to store the next dts value. write_interleaved_packet destroys the passed in packet so we need to store next_dts before writing out the packet.

This commit is contained in:
Isaac Connor 2019-10-23 09:25:16 -04:00
parent 76fd32b427
commit 35ae81d985
2 changed files with 18 additions and 13 deletions

View File

@ -110,6 +110,7 @@ VideoStore::VideoStore(
} else { } else {
Debug(2, "Success creating video out stream"); Debug(2, "Success creating video out stream");
} }
max_stream_index = video_out_stream->index;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// by allocating our own copy, we don't run into the problems when we free the streams // by allocating our own copy, we don't run into the problems when we free the streams
@ -277,14 +278,9 @@ VideoStore::VideoStore(
#endif #endif
video_first_pts = 0; video_first_pts = 0;
video_first_dts = 0; video_first_dts = 0;
video_next_pts = 0;
video_next_dts = 0;
audio_first_pts = 0; audio_first_pts = 0;
audio_first_dts = 0; audio_first_dts = 0;
/* When encoding audio, these are used to tell us what the correct pts is, because it gets lost during resampling. */
audio_next_pts = 0;
audio_next_dts = 0;
if ( audio_in_stream ) { if ( audio_in_stream ) {
Debug(3, "Have audio stream"); Debug(3, "Have audio stream");
@ -381,7 +377,16 @@ VideoStore::VideoStore(
audio_out_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; audio_out_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
#endif #endif
} }
// We will assume that subsequent stream allocations will increase the index
max_stream_index = audio_out_stream->index;
} // end if audio_in_stream } // end if audio_in_stream
//max_stream_index is 0-based, so add 1
next_dts = new int64_t[max_stream_index+1];
for ( int i = 0; i <= max_stream_index; i++ ) {
next_dts[i] = 0;
}
} // VideoStore::VideoStore } // VideoStore::VideoStore
bool VideoStore::open() { bool VideoStore::open() {
@ -605,6 +610,7 @@ VideoStore::~VideoStore() {
/* free the streams */ /* free the streams */
avformat_free_context(oc); avformat_free_context(oc);
delete[] next_dts;
} // VideoStore::~VideoStore() } // VideoStore::~VideoStore()
bool VideoStore::setup_resampler() { bool VideoStore::setup_resampler() {
@ -899,8 +905,8 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
} }
opkt.dts = ipkt->dts - video_first_dts; opkt.dts = ipkt->dts - video_first_dts;
} else { } else {
opkt.dts = video_next_dts ? av_rescale_q(video_next_dts, video_out_stream->time_base, video_in_stream->time_base) : 0; opkt.dts = next_dts[video_out_stream->index] ? av_rescale_q(next_dts[video_out_stream->index], video_out_stream->time_base, video_in_stream->time_base) : 0;
Debug(3, "Setting dts to video_next_dts %" PRId64 " from %" PRId64, opkt.dts, video_next_dts); Debug(3, "Setting dts to video_next_dts %" PRId64 " from %" PRId64, opkt.dts, next_dts[video_out_stream->index]);
} }
if ( ipkt->pts != AV_NOPTS_VALUE ) { if ( ipkt->pts != AV_NOPTS_VALUE ) {
opkt.pts = ipkt->pts - video_first_dts; opkt.pts = ipkt->pts - video_first_dts;
@ -911,9 +917,6 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
dumpPacket(video_out_stream, &opkt, "after pts adjustment"); dumpPacket(video_out_stream, &opkt, "after pts adjustment");
write_packet(&opkt, video_out_stream); write_packet(&opkt, video_out_stream);
dumpPacket(video_out_stream, &opkt, "after write_packet");
video_next_dts = opkt.dts + opkt.duration;
Debug(3, "video_next_dts has become %" PRId64, video_next_dts);
zm_av_packet_unref(&opkt); zm_av_packet_unref(&opkt);
@ -1025,6 +1028,8 @@ int VideoStore::write_packet(AVPacket *pkt, AVStream *stream) {
} }
dumpPacket(stream, pkt, "finished pkt"); dumpPacket(stream, pkt, "finished pkt");
next_dts[stream->index] = opkt.dts + opkt.duration;
Debug(3, "video_next_dts has become %" PRId64, next_dts[stream->index]);
int ret = av_interleaved_write_frame(oc, pkt); int ret = av_interleaved_write_frame(oc, pkt);
if ( ret != 0 ) { if ( ret != 0 ) {

View File

@ -70,10 +70,10 @@ private:
int64_t audio_first_dts; int64_t audio_first_dts;
// These are for out, should start at zero. We assume they do not wrap because we just aren't going to save files that big. // These are for out, should start at zero. We assume they do not wrap because we just aren't going to save files that big.
int64_t video_next_pts; int64_t *next_dts;
int64_t video_next_dts;
int64_t audio_next_pts; int64_t audio_next_pts;
int64_t audio_next_dts;
int max_stream_index;
bool setup_resampler(); bool setup_resampler();
int write_packet(AVPacket *pkt, AVStream *stream); int write_packet(AVPacket *pkt, AVStream *stream);