libeplayer3: use uint64_t instead of float/double for position calculations

This commit is contained in:
martii
2014-04-14 21:47:40 +02:00
parent 31230e5b19
commit 8ccf1ba33b
7 changed files with 52 additions and 58 deletions

View File

@@ -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);

View File

@@ -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<std::string> &keys, std::vector<std::string> &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<int> &positions, std::vector<std::string> &titles);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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();

View File

@@ -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;
}