Index: libs/libmythtv/avformatdecoder.cpp =================================================================== --- libs/libmythtv/avformatdecoder.cpp (revision 27322) +++ libs/libmythtv/avformatdecoder.cpp (working copy) @@ -957,6 +957,11 @@ } } + int64_t dur = ic->duration / (int64_t)AV_TIME_BASE; + if (dur > 0) + { + m_parent->SetDuration((int)dur); + } // If we don't have a position map, set up ffmpeg for seeking if (!recordingHasPositionMap && !livetv) { @@ -2946,7 +2951,7 @@ bool AvFormatDecoder::ProcessVideoPacket(AVStream *curstream, AVPacket *pkt) { int ret = 0, gotpicture = 0; - long long pts = 0; + int64_t pts = 0; AVCodecContext *context = curstream->codec; AVFrame mpa_pic; avcodec_get_frame_defaults(&mpa_pic); @@ -3069,28 +3074,26 @@ if (ringBuffer->isDVD()) { if (pkt->dts != (int64_t)AV_NOPTS_VALUE) - pts = (long long)pkt->dts; + pts = pkt->dts; } else if (private_dec && private_dec->NeedsReorderedPTS() && mpa_pic.reordered_opaque != (int64_t)AV_NOPTS_VALUE) { - pts = (long long)mpa_pic.reordered_opaque; + pts = mpa_pic.reordered_opaque; } else if ((force_reordered_opaque || faulty_pts <= faulty_dts || pkt->dts == (int64_t)AV_NOPTS_VALUE) && mpa_pic.reordered_opaque != (int64_t)AV_NOPTS_VALUE) { - pts = (long long)mpa_pic.reordered_opaque; + pts = mpa_pic.reordered_opaque; } else if ((faulty_dts < faulty_pts || !reordered_pts_detected) && pkt->dts != (int64_t)AV_NOPTS_VALUE) { - pts = (long long)pkt->dts; + pts = pkt->dts; } - pts = (long long)(av_q2d(curstream->time_base) * pts * 1000); + long long temppts = (long long)(av_q2d(curstream->time_base) * pts * 1000); - long long temppts = pts; - // Validate the video pts against the last pts. If it's // a little bit smaller, equal or missing, compute // it from the last. Otherwise assume a wraparound. @@ -3104,10 +3107,33 @@ temppts += (long long)(mpa_pic.repeat_pict * 500 / fps); } + pts = (int64_t)((temppts / 1000.0f) / av_q2d(curstream->time_base)); + + int64_t disp_pts, disp_timecode; + + if (ic->start_time != (int64_t)AV_NOPTS_VALUE) + { + int64_t st1 = av_rescale(ic->start_time, + curstream->time_base.den, + AV_TIME_BASE * (int64_t)curstream->time_base.num); + disp_pts = lsb3full(pts, st1, curstream->pts_wrap_bits); + } + + disp_timecode = (int64_t)(av_q2d(curstream->time_base) * disp_pts * 1000); + VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + - QString("video timecode %1 %2 %3 %4 %5").arg(mpa_pic.reordered_opaque).arg(pkt->pts).arg(pkt->dts) - .arg(temppts).arg(lastvpts)); + QString("video timecode %1 %2 %3 %4 %5").arg(mpa_pic.reordered_opaque) + .arg(pkt->pts).arg(pkt->dts).arg(temppts).arg(lastvpts)); + long double total_secs = (long double)(disp_timecode / 1000.0f); + int hours = (int)total_secs / 60 / 60; + int minutes = ((int)total_secs / 60) - (hours * 60); + double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60); + VERBOSE(VB_PLAYBACK, LOC + QString("display timecode @ [%1:%2:%3]") + .arg(QString().sprintf("%02d", hours)) + .arg(QString().sprintf("%02d", minutes)) + .arg(QString().sprintf("%06.3f", secs))); + /* XXX: Broken. if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && context->height == picframe->height) @@ -3132,6 +3158,8 @@ picframe->interlaced_frame = mpa_pic.interlaced_frame; picframe->top_field_first = mpa_pic.top_field_first; picframe->repeat_pict = mpa_pic.repeat_pict; + picframe->pts = pts; + picframe->disp_timecode = disp_timecode; picframe->frameNumber = framesPlayed; m_parent->ReleaseNextVideoFrame(picframe, temppts); Index: libs/libmythtv/frame.h =================================================================== --- libs/libmythtv/frame.h (revision 27322) +++ libs/libmythtv/frame.h (working copy) @@ -40,6 +40,8 @@ long long frameNumber; long long timecode; + int64_t disp_timecode; + int64_t pts; unsigned char *priv[4]; // random empty storage Index: libs/libmythtv/mythplayer.h =================================================================== --- libs/libmythtv/mythplayer.h (revision 27322) +++ libs/libmythtv/mythplayer.h (working copy) @@ -150,6 +150,7 @@ float a = 1.33333, FrameScanType scan = kScan_Ignore, bool video_codec_changed = false); void SetFileLength(int total, int frames); + void SetDuration(int duration); void SetForcedAspectRatio(int mpeg2_aspect_value, int letterbox_permission); void SetVideoResize(const QRect &videoRect); @@ -480,6 +481,7 @@ void SetDecoder(DecoderBase *dec); /// Returns the stream decoder currently in use. const DecoderBase *GetDecoder(void) const { return decoder; } + int64_t GetDisplayTimecode(void) { return disp_timecode; } bool DecodeFrame(struct rtframeheader *frameheader, unsigned char *strm, unsigned char *outbuf); @@ -595,6 +597,7 @@ uint64_t framesPlayed; uint64_t totalFrames; long long totalLength; + int64_t totalDuration; long long rewindtime; // -- end state stuff -- @@ -704,6 +707,7 @@ bool lastsync; bool decode_extra_audio; int repeat_delay; + int64_t disp_timecode; // Time Code stuff int prevtc; ///< 32 bit timecode if last VideoFrame shown Index: libs/libmythtv/mythplayer.cpp =================================================================== --- libs/libmythtv/mythplayer.cpp (revision 27322) +++ libs/libmythtv/mythplayer.cpp (working copy) @@ -191,6 +191,7 @@ // Playback misc. videobuf_retries(0), framesPlayed(0), totalFrames(0), totalLength(0), + totalDuration(0), rewindtime(0), // Input Video Attributes video_disp_dim(0,0), video_dim(0,0), @@ -240,6 +241,7 @@ avsync_adjustment(0), avsync_avg(0), refreshrate(0), lastsync(false), repeat_delay(0), + disp_timecode(0), // Time Code stuff prevtc(0), prevrp(0), // LiveTVChain stuff @@ -897,6 +899,11 @@ totalFrames = frames; } +void MythPlayer::SetDuration(int duration) +{ + totalDuration = duration; +} + void MythPlayer::OpenDummy(void) { isDummy = true; @@ -1674,8 +1681,9 @@ if (buffer) { - repeat_pict = buffer->repeat_pict; - timecode = buffer->timecode; + repeat_pict = buffer->repeat_pict; + timecode = buffer->timecode; + disp_timecode = buffer->disp_timecode; } float diverge = 0.0f; @@ -4267,8 +4275,12 @@ info.values.insert("progbefore", 0); info.values.insert("progafter", 0); - int playbackLen = totalLength; - + int playbackLen; + if (totalDuration > 0) + playbackLen = totalDuration; + else + playbackLen = totalLength; + if (livetv && player_ctx->tvchain) { info.values["progbefore"] = (int)player_ctx->tvchain->HasPrev(); @@ -4285,7 +4297,8 @@ islive = true; } - float secsplayed = ((float)framesPlayed / video_frame_rate); +// float secsplayed = ((float)framesPlayed / video_frame_rate); + float secsplayed = (float)(disp_timecode / 1000.f); calcSliderPosPriv(info, paddedFields, playbackLen, secsplayed, islive); }