From 8ccf1ba33bc5c08bf676d056ca9d5a4adbd64aaf Mon Sep 17 00:00:00 2001 From: martii Date: Mon, 14 Apr 2014 21:47:40 +0200 Subject: [PATCH] libeplayer3: use uint64_t instead of float/double for position calculations --- libeplayer3/include/input.h | 8 ++-- libeplayer3/include/player.h | 8 ++-- libeplayer3/input.cpp | 78 +++++++++++++++---------------- libeplayer3/player.cpp | 4 +- libeplayer3/writer/h264.cpp | 2 +- libeplayer3/writer/vc1.cpp | 1 - libspark/playback_libeplayer3.cpp | 9 ++-- 7 files changed, 52 insertions(+), 58 deletions(-) diff --git a/libeplayer3/include/input.h b/libeplayer3/include/input.h index f087b25..7343dde 100644 --- a/libeplayer3/include/input.h +++ b/libeplayer3/include/input.h @@ -53,8 +53,8 @@ class Input Track *teletextTrack; int hasPlayThreadStarted; - float seek_sec_abs; - float seek_sec_rel; + int64_t seek_avts_abs; + int64_t seek_avts_rel; bool isContainerRunning; bool abortPlayback; @@ -71,8 +71,8 @@ class Input bool UpdateTracks(); bool Play(); bool Stop(); - bool Seek(float sec, bool absolute); - bool GetDuration(double &duration); + bool Seek(int64_t sec, bool absolute); + bool GetDuration(int64_t &duration); bool SwitchAudio(Track *track); bool SwitchSubtitle(Track *track); bool SwitchTeletext(Track *track); diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index 7a8b1f1..9b6e44b 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -47,8 +47,8 @@ extern "C" { struct Chapter { std::string title; - double start; - double end; + int64_t start; + int64_t end; }; class Player { @@ -97,7 +97,7 @@ class Player { bool GetPts(int64_t &pts); bool GetFrameCount(int64_t &framecount); - bool GetDuration(double &duration); + bool GetDuration(int64_t &duration); bool GetMetadata(std::vector &keys, std::vector &values); bool SlowMotion(int repeats); @@ -110,7 +110,7 @@ class Player { bool Pause(); bool Continue(); bool Stop(); - bool Seek(float pos, bool absolute); + bool Seek(int64_t pos, bool absolute); void RequestAbort(); bool GetChapters(std::vector &positions, std::vector &titles); diff --git a/libeplayer3/input.cpp b/libeplayer3/input.cpp index 2a9a86d..515dc7b 100644 --- a/libeplayer3/input.cpp +++ b/libeplayer3/input.cpp @@ -47,8 +47,8 @@ Input::Input() teletextTrack = NULL; hasPlayThreadStarted = 0; - seek_sec_abs = -1.0; - seek_sec_rel = 0.0; + seek_avts_abs = INT64_MIN; + seek_avts_rel = 0; abortPlayback = false; } @@ -67,7 +67,7 @@ int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts) if (pts == AV_NOPTS_VALUE) return INVALID_PTS_VALUE; - pts = 90000.0 * (double) pts * av_q2d(stream->time_base); + pts = 90000 * pts * stream->time_base.num / stream->time_base.den; if (avfc->start_time != AV_NOPTS_VALUE) pts -= 90000.0 * avfc->start_time / AV_TIME_BASE; @@ -103,28 +103,30 @@ bool Input::Play() } int seek_target_flag = 0; - int64_t seek_target = INT64_MIN; + int64_t seek_target = INT64_MIN; // in AV_TIME_BASE units - if (seek_sec_rel != 0.0) { + if (seek_avts_rel) { if (avfc->iformat->flags & AVFMT_TS_DISCONT) { - float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; - seek_target_flag = AVSEEK_FLAG_BYTE; - seek_target = avio_tell(avfc->pb) + seek_sec_rel * br; + if (avfc->bit_rate) { + seek_target_flag = AVSEEK_FLAG_BYTE; + seek_target = avio_tell(avfc->pb) + seek_avts_rel * avfc->bit_rate / ( 8 * AV_TIME_BASE); + } } else { int64_t pts; if(player->output.GetPts(pts)) - seek_target = (pts * AV_TIME_BASE)/ 90000.0 + seek_sec_rel * AV_TIME_BASE; + seek_target = (pts * AV_TIME_BASE) / 90000 + seek_avts_rel; } - seek_sec_rel = 0.0; - } else if (seek_sec_abs >= 0.0) { + seek_avts_rel = 0; + } else if (seek_avts_abs != INT64_MIN) { if (avfc->iformat->flags & AVFMT_TS_DISCONT) { - float br = (avfc->bit_rate) ? avfc->bit_rate / 8.0 : 180000.0; - seek_target_flag = AVSEEK_FLAG_BYTE; - seek_target = seek_sec_abs * br; + if (avfc->bit_rate) { + seek_target_flag = AVSEEK_FLAG_BYTE; + seek_target = seek_avts_abs * avfc->bit_rate / (8 * AV_TIME_BASE); + } } else { - seek_target = seek_sec_abs * AV_TIME_BASE; + seek_target = seek_avts_abs; } - seek_sec_abs = -1.0; + seek_avts_abs = INT64_MIN; } else if (player->isBackWard && av_gettime() >= showtime) { player->output.ClearVideo(); @@ -137,15 +139,14 @@ bool Input::Play() if (avfc->iformat->flags & AVFMT_TS_DISCONT) { off_t pos = avio_tell(avfc->pb); - if (pos > 0) { - float br = avfc->bit_rate ? avfc->bit_rate / 8.0 : 180000.0; + if (pos > 0 && avfc->bit_rate) { seek_target_flag = AVSEEK_FLAG_BYTE; - seek_target = pos + player->Speed * 8 * br; + seek_target = pos + player->Speed * avfc->bit_rate * AV_TIME_BASE; } } else { int64_t pts; if(player->output.GetPts(pts)) - seek_target = (pts * AV_TIME_BASE)/ 90000.0 + seek_sec_rel * AV_TIME_BASE; + seek_target = (pts * AV_TIME_BASE) / 90000 + seek_avts_rel; } showtime = av_gettime() + 300000; //jump back every 300ms } else { @@ -419,8 +420,8 @@ bool Input::UpdateTracks() AVDictionaryEntry* title = av_dict_get(ch->metadata, "title", NULL, 0); Chapter chapter; chapter.title = title ? title->value : ""; - chapter.start = (double) ch->start * av_q2d(ch->time_base) * 1000.0; - chapter.end = (double) ch->end * av_q2d(ch->time_base) * 1000.0; + chapter.start = AV_TIME_BASE * ch->start * ch->time_base.num / ch->time_base.den; + chapter.end = AV_TIME_BASE * ch->end * ch->time_base.num / ch->time_base.den; chapters.push_back(chapter); } player->SetChapters(chapters); @@ -442,9 +443,9 @@ bool Input::UpdateTracks() track.Name = lang ? lang->value : ""; track.pid = stream->id; if (stream->duration == AV_NOPTS_VALUE) - track.duration = (double) avfc->duration / 1000.0; + track.duration = avfc->duration; else - track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; + track.duration = AV_TIME_BASE * stream->duration * stream->time_base.num / stream->time_base.den; switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { @@ -534,36 +535,32 @@ bool Input::Stop() return true; } -bool Input::Seek(float sec, bool absolute) +bool Input::Seek(int64_t avts, bool absolute) { if (absolute) - seek_sec_abs = sec, seek_sec_rel = 0.0; + seek_avts_abs = avts, seek_avts_rel = 0; else - seek_sec_abs = -1.0, seek_sec_rel = sec; + seek_avts_abs = INT64_MIN, seek_avts_rel = avts; return true; } -bool Input::GetDuration(double &duration) +bool Input::GetDuration(int64_t &duration) { - duration = 0.0; + duration = 0; Track *track = videoTrack; - if (track && track->duration != 0.0) { - duration = track->duration / 1000.0; + if (track && track->duration) { + duration = track->duration; return true; } track = audioTrack; - if (track && track->duration != 0.0) { - duration = track->duration / 1000.0; + if (track && track->duration) { + duration = track->duration; return true; } track = subtitleTrack; - if (track && track->duration != 0.0) { - duration = track->duration / 1000.0; - return true; - } - if (avfc && avfc->duration != 0.0) { - duration = avfc->duration /1000.0; + if (track && track->duration) { + duration = track->duration; return true; } return false; @@ -573,8 +570,7 @@ bool Input::SwitchAudio(Track *track) { audioTrack = track; player->output.SwitchAudio(track ? track->stream : NULL); - float sec = -5.0; - player->Seek(sec, false); + player->Seek(-5000, false); return true; } diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index dd5617f..483f506 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -309,7 +309,7 @@ bool Player::SlowMotion(int repeats) return false; } -bool Player::Seek(float pos, bool absolute) +bool Player::Seek(int64_t pos, bool absolute) { output.Clear(); return input.Seek(pos, absolute); @@ -326,7 +326,7 @@ bool Player::GetFrameCount(int64_t &frameCount) return isPlaying && output.GetFrameCount(frameCount); } -bool Player::GetDuration(double &duration) +bool Player::GetDuration(int64_t &duration) { duration = -1; return isPlaying && input.GetDuration(duration); diff --git a/libeplayer3/writer/h264.cpp b/libeplayer3/writer/h264.cpp index 402661c..bf30659 100644 --- a/libeplayer3/writer/h264.cpp +++ b/libeplayer3/writer/h264.cpp @@ -77,7 +77,7 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A int ic = 0; struct iovec iov[128]; - TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */ + TimeDelta = 1000.0 * stream->r_frame_rate.num / stream->r_frame_rate.den; TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */ if ((packet->size > 3) diff --git a/libeplayer3/writer/vc1.cpp b/libeplayer3/writer/vc1.cpp index 7ac5c18..51e4f24 100644 --- a/libeplayer3/writer/vc1.cpp +++ b/libeplayer3/writer/vc1.cpp @@ -50,7 +50,6 @@ class WriterVC1 : public Writer private: bool initialHeader; uint8_t FrameHeaderSeen; - double frameRate; public: bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); void Init(); diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index cedfacb..1b590c6 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -222,14 +222,14 @@ bool cPlayback::GetPosition(int &position, int &duration) if (got_duration) return true; - double length = 0; + int64_t length = 0; player->GetDuration(length); if(length <= 0) - duration = duration+1000; + duration = position + AV_TIME_BASE / 1000; else - duration = length*1000.0; + duration = length * 1000 / AV_TIME_BASE; return true; } @@ -246,8 +246,7 @@ bool cPlayback::SetPosition(int position, bool absolute) init_jump = position; return false; } - float pos = (position/1000.0); - player->Seek(pos, absolute); + player->Seek((int64_t)position * (AV_TIME_BASE / 1000), absolute); return true; }