diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index 166c916fd39923b0f26b9d84b97225afa289406f..52ea3851e237d44a92a3e81c777dd808cda75ea5 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -197,6 +197,7 @@ MediaDecoder::setupStream(AVMediaType mediaType) return -1; } avcodec_parameters_to_context(decoderCtx_, avStream_->codecpar); + decoderCtx_->framerate = avStream_->avg_frame_rate; decoderCtx_->thread_count = std::max(1u, std::min(8u, std::thread::hardware_concurrency()/2)); if (mediaType == AVMEDIA_TYPE_AUDIO) { @@ -289,9 +290,12 @@ MediaDecoder::decode(VideoFrame& result) } } #endif + if (frame->pts != AV_NOPTS_VALUE) + frame->pts = av_rescale_q(frame->pts - avStream_->start_time, avStream_->time_base, decoderCtx_->time_base); + if (auto rec = recorder_.lock()) { if (!recordingStarted_) { - auto ms = MediaStream("", avStream_, frame->pts); + auto ms = MediaStream("", decoderCtx_, frame->pts); ms.format = frame->format; // might not match avStream_ if accel is used if (rec->addStream(true, true, ms) >= 0) recordingStarted_ = true; @@ -355,9 +359,12 @@ MediaDecoder::decode(const AudioFrame& decodedFrame) if (frameFinished) { av_packet_unref(&inpacket); + if (frame->pts != AV_NOPTS_VALUE) + frame->pts = av_rescale_q(frame->pts, avStream_->time_base, decoderCtx_->time_base); + if (auto rec = recorder_.lock()) { if (!recordingStarted_) { - auto ms = MediaStream("", avStream_, frame->pts); + auto ms = MediaStream("", decoderCtx_, frame->pts); if (rec->addStream(false, true, ms) >= 0) recordingStarted_ = true; else diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp index 9736f2c6fabd4c928922c897bead5d9768ddfdc2..029d566af82862949798dd49f12d2bd02cf9a489 100644 --- a/src/media/media_encoder.cpp +++ b/src/media/media_encoder.cpp @@ -363,8 +363,8 @@ MediaEncoder::encode(VideoFrame& input, bool is_keyframe, scaler_.scale_with_aspect(input, scaledFrame_); auto frame = scaledFrame_.pointer(); - AVStream* st = outputCtx_->streams[currentStreamIdx_]; - frame->pts = getNextTimestamp(frame_number, st->avg_frame_rate, st->time_base); + AVCodecContext* enc = encoders_[currentStreamIdx_]; + frame->pts = getNextTimestamp(frame_number, enc->framerate, enc->time_base); if (is_keyframe) { frame->pict_type = AV_PICTURE_TYPE_I; @@ -422,8 +422,7 @@ int MediaEncoder::encode_audio(const AudioBuffer &buffer) frame->channels = buffer.channels(); frame->sample_rate = sample_rate; - AVStream* st = outputCtx_->streams[currentStreamIdx_]; - frame->pts = getNextTimestamp(sent_samples, st->codecpar->sample_rate, st->time_base); + frame->pts = getNextTimestamp(sent_samples, encoderCtx->sample_rate, encoderCtx->time_base); sent_samples += frame->nb_samples; const auto buffer_size = \ @@ -464,7 +463,7 @@ MediaEncoder::encode(AVFrame* frame, int streamIdx) if (auto rec = recorder_.lock()) { bool isVideo = encoderCtx->codec_type == AVMEDIA_TYPE_VIDEO; if (!recordingStarted_) { - auto ms = MediaStream("", outputCtx_->streams[streamIdx], frame->pts); + auto ms = MediaStream("", encoderCtx, frame->pts); if (rec->addStream(isVideo, false, ms) >= 0) recordingStarted_ = true; else diff --git a/src/media/media_stream.h b/src/media/media_stream.h index d074093e1b302ef6bda59fb63ea250ac4a73c02e..5e9fffb402bc972ebbab229981138d362a2d942a 100644 --- a/src/media/media_stream.h +++ b/src/media/media_stream.h @@ -65,29 +65,30 @@ struct MediaStream { , nbChannels(channels) {} - MediaStream(std::string name, AVStream* st) - : MediaStream(name, st, 0) + MediaStream(std::string name, AVCodecContext* c) + : MediaStream(name, c, 0) { } - MediaStream(std::string name, AVStream* st, int64_t firstTimestamp) + MediaStream(std::string name, AVCodecContext* c, int64_t firstTimestamp) : name(name) { - format = st->codecpar->format; - timeBase = st->time_base; + timeBase = c->time_base; this->firstTimestamp = firstTimestamp; - switch (st->codecpar->codec_type) { + switch (c->codec_type) { case AVMEDIA_TYPE_VIDEO: + format = c->pix_fmt; isVideo = true; - width = st->codecpar->width; - height = st->codecpar->height; - aspectRatio = st->codecpar->sample_aspect_ratio; - frameRate = st->avg_frame_rate; + width = c->width; + height = c->height; + aspectRatio = c->sample_aspect_ratio; + frameRate = c->framerate; break; case AVMEDIA_TYPE_AUDIO: + format = c->sample_fmt; isVideo = false; - sampleRate = st->codecpar->sample_rate; - nbChannels = st->codecpar->channels; + sampleRate = c->sample_rate; + nbChannels = c->channels; break; default: break;