libeplayer3: merge Playback to Player class

This commit is contained in:
martii
2014-04-07 21:25:30 +02:00
parent a965fe4359
commit b08abf6b52
9 changed files with 271 additions and 321 deletions

View File

@@ -67,7 +67,7 @@ Input::~Input()
int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts) int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts)
{ {
if (!avfc || !stream) { if (!avfc || !stream) {
fprintf(stderr, "context / stream null\n"); fprintf(stderr, "player / stream null\n");
return INVALID_PTS_VALUE; return INVALID_PTS_VALUE;
} }
@@ -102,7 +102,7 @@ bool Input::Play()
int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0; int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0;
while (context->playback.isCreationPhase) { while (player->isCreationPhase) {
fprintf(stderr, "Thread waiting for end of init phase...\n"); fprintf(stderr, "Thread waiting for end of init phase...\n");
usleep(1000); usleep(1000);
} }
@@ -110,10 +110,10 @@ bool Input::Play()
bool restart_audio_resampling = false; bool restart_audio_resampling = false;
while (context->playback.isPlaying && !context->playback.abortRequested) { while (player->isPlaying && !player->abortRequested) {
//IF MOVIE IS PAUSED, WAIT //IF MOVIE IS PAUSED, WAIT
if (context->playback.isPaused) { if (player->isPaused) {
fprintf(stderr, "paused\n"); fprintf(stderr, "paused\n");
usleep(100000); usleep(100000);
@@ -141,8 +141,8 @@ bool Input::Play()
seek_target = seek_sec_abs * AV_TIME_BASE; seek_target = seek_sec_abs * AV_TIME_BASE;
} }
seek_sec_abs = -1.0; seek_sec_abs = -1.0;
} else if (context->playback.isBackWard && av_gettime() >= showtime) { } else if (player->isBackWard && av_gettime() >= showtime) {
context->output.ClearVideo(); player->output.ClearVideo();
if (bofcount == 1) { if (bofcount == 1) {
showtime = av_gettime(); showtime = av_gettime();
@@ -159,11 +159,11 @@ bool Input::Play()
br = avfc->bit_rate / 8.0; br = avfc->bit_rate / 8.0;
else else
br = 180000.0; br = 180000.0;
seek_target = pos + context->playback.Speed * 8 * br; seek_target = pos + player->Speed * 8 * br;
seek_target_flag = AVSEEK_FLAG_BYTE; seek_target_flag = AVSEEK_FLAG_BYTE;
} }
} else { } else {
seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + context->playback.Speed * 8) * AV_TIME_BASE;; seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + player->Speed * 8) * AV_TIME_BASE;;
} }
showtime = av_gettime() + 300000; //jump back every 300ms showtime = av_gettime() + 300000; //jump back every 300ms
} else { } else {
@@ -176,7 +176,7 @@ bool Input::Play()
seek_target = 0; seek_target = 0;
res = avformat_seek_file(avfc, -1, INT64_MIN, seek_target, INT64_MAX, seek_target_flag); res = avformat_seek_file(avfc, -1, INT64_MIN, seek_target, INT64_MAX, seek_target_flag);
if (res < 0 && context->playback.isBackWard) if (res < 0 && player->isBackWard)
bofcount = 1; bofcount = 1;
seek_target = INT64_MIN; seek_target = INT64_MIN;
restart_audio_resampling = true; restart_audio_resampling = true;
@@ -203,7 +203,7 @@ bool Input::Play()
} }
long long int pts; long long int pts;
context->playback.readCount += packet.size; player->readCount += packet.size;
int pid = avfc->streams[packet.stream_index]->id; int pid = avfc->streams[packet.stream_index]->id;
@@ -217,16 +217,16 @@ Track *_teletextTrack = teletextTrack;
if (_videoTrack && (_videoTrack->pid == pid)) { if (_videoTrack && (_videoTrack->pid == pid)) {
currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts); currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts);
if (!context->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts)) if (!player->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts))
;//fprintf(stderr, "writing data to video device failed\n"); ;//fprintf(stderr, "writing data to video device failed\n");
} else if (_audioTrack && (_audioTrack->pid == pid)) { } else if (_audioTrack && (_audioTrack->pid == pid)) {
if (restart_audio_resampling) { if (restart_audio_resampling) {
restart_audio_resampling = false; restart_audio_resampling = false;
context->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts); player->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts);
} }
if (!context->playback.isBackWard) { if (!player->isBackWard) {
currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts); currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts);
if (!context->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts)) if (!player->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts))
;//fprintf(stderr, "writing data to audio device failed\n"); ;//fprintf(stderr, "writing data to audio device failed\n");
} }
} else if (_subtitleTrack && (_subtitleTrack->pid == pid)) { } else if (_subtitleTrack && (_subtitleTrack->pid == pid)) {
@@ -268,12 +268,12 @@ Track *_teletextTrack = teletextTrack;
av_free_packet(&packet); av_free_packet(&packet);
} /* while */ } /* while */
if (context && context->playback.abortRequested) if (player && player->abortRequested)
context->output.Clear(); player->output.Clear();
dvbsub_ass_clear(); dvbsub_ass_clear();
context->playback.abortPlayback = 1; player->abortPlayback = 1;
hasPlayThreadStarted = 0; hasPlayThreadStarted = 0;
return true; return true;
@@ -283,10 +283,10 @@ Track *_teletextTrack = teletextTrack;
/* Container part for ffmpeg */ /* Container part for ffmpeg */
/* **************************** */ /* **************************** */
static int interrupt_cb(void *arg) /*static*/ int interrupt_cb(void *arg)
{ {
Playback *playback = (Playback *) arg; Player *player = (Player *) arg;
return playback->abortPlayback | playback->abortRequested; return player->abortPlayback | player->abortRequested;
} }
static void log_callback(void *ptr __attribute__ ((unused)), int lvl __attribute__ ((unused)), const char *format, va_list ap) static void log_callback(void *ptr __attribute__ ((unused)), int lvl __attribute__ ((unused)), const char *format, va_list ap)
@@ -350,7 +350,7 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid)
track.Name = format; track.Name = format;
track.is_static = 1; track.is_static = 1;
track.pid = pid; track.pid = pid;
context->manager.addSubtitleTrack(track); player->manager.addSubtitleTrack(track);
return true; return true;
} }
@@ -389,15 +389,15 @@ bool Input::Init(const char *filename)
avformat_network_init(); avformat_network_init();
context->playback.abortRequested = 0; player->abortRequested = 0;
context->playback.abortPlayback = 0; player->abortPlayback = 0;
videoTrack = NULL; videoTrack = NULL;
audioTrack = NULL; audioTrack = NULL;
subtitleTrack = NULL; subtitleTrack = NULL;
teletextTrack = NULL; teletextTrack = NULL;
avfc = avformat_alloc_context(); avfc = avformat_alloc_context();
avfc->interrupt_callback.callback = interrupt_cb; avfc->interrupt_callback.callback = interrupt_cb;
avfc->interrupt_callback.opaque = (void *) &context->playback; avfc->interrupt_callback.opaque = (void *) &player;
if ((err = avformat_open_input(&avfc, filename, NULL, 0)) != 0) { if ((err = avformat_open_input(&avfc, filename, NULL, 0)) != 0) {
char error[512]; char error[512];
@@ -412,7 +412,7 @@ bool Input::Init(const char *filename)
avfc->iformat->flags |= AVFMT_SEEK_TO_PTS; avfc->iformat->flags |= AVFMT_SEEK_TO_PTS;
avfc->flags = AVFMT_FLAG_GENPTS; avfc->flags = AVFMT_FLAG_GENPTS;
if (context->playback.noprobe) { if (player->noprobe) {
avfc->max_analyze_duration = 1; avfc->max_analyze_duration = 1;
avfc->probesize = 8192; avfc->probesize = 8192;
} }
@@ -440,9 +440,9 @@ bool Input::Init(const char *filename)
} }
if (videoTrack) if (videoTrack)
context->output.SwitchVideo(videoTrack->stream); player->output.SwitchVideo(videoTrack->stream);
if (audioTrack) if (audioTrack)
context->output.SwitchAudio(audioTrack->stream); player->output.SwitchAudio(audioTrack->stream);
ReadSubtitles(filename); ReadSubtitles(filename);
@@ -468,11 +468,11 @@ bool Input::UpdateTracks()
chapter.end = (double) ch->end * av_q2d(ch->time_base) * 1000.0; chapter.end = (double) ch->end * av_q2d(ch->time_base) * 1000.0;
chapters.push_back(chapter); chapters.push_back(chapter);
} }
context->SetChapters(chapters); player->SetChapters(chapters);
context->manager.initTrackUpdate(); player->manager.initTrackUpdate();
av_dump_format(avfc, 0, context->playback.url.c_str(), 0); av_dump_format(avfc, 0, player->url.c_str(), 0);
unsigned int n; unsigned int n;
@@ -498,9 +498,9 @@ bool Input::UpdateTracks()
track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0;
} }
context->manager.addVideoTrack(track); player->manager.addVideoTrack(track);
if (!videoTrack) if (!videoTrack)
videoTrack = context->manager.getVideoTrack(track.pid); videoTrack = player->manager.getVideoTrack(track.pid);
break; break;
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
AVDictionaryEntry *lang; AVDictionaryEntry *lang;
@@ -540,9 +540,9 @@ bool Input::UpdateTracks()
default: default:
track.ac3flags = 0; track.ac3flags = 0;
} }
context->manager.addAudioTrack(track); player->manager.addAudioTrack(track);
if (!audioTrack) if (!audioTrack)
audioTrack = context->manager.getAudioTrack(track.pid); audioTrack = player->manager.getAudioTrack(track.pid);
break; break;
case AVMEDIA_TYPE_SUBTITLE: case AVMEDIA_TYPE_SUBTITLE:
@@ -567,7 +567,7 @@ bool Input::UpdateTracks()
char lang[strlen(t->value)]; char lang[strlen(t->value)];
if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) { if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) {
track.Name = lang; track.Name = lang;
context->manager.addTeletextTrack(track); player->manager.addTeletextTrack(track);
} }
} }
i++; i++;
@@ -583,7 +583,7 @@ bool Input::UpdateTracks()
} }
} }
if (stream->codec->codec) if (stream->codec->codec)
context->manager.addSubtitleTrack(track); player->manager.addSubtitleTrack(track);
} }
break; break;
@@ -604,7 +604,7 @@ bool Input::Stop()
fprintf(stderr, "Container not running\n"); fprintf(stderr, "Container not running\n");
return false; return false;
} }
context->playback.abortRequested = 1; player->abortRequested = 1;
while (hasPlayThreadStarted != 0) while (hasPlayThreadStarted != 0)
usleep(100000); usleep(100000);
@@ -656,9 +656,9 @@ bool Input::GetDuration(double &duration)
bool Input::SwitchAudio(Track *track) bool Input::SwitchAudio(Track *track)
{ {
audioTrack = track; audioTrack = track;
context->output.SwitchAudio(track ? track->stream : NULL); player->output.SwitchAudio(track ? track->stream : NULL);
float sec = -5.0; float sec = -5.0;
context->playback.Seek(sec, false); player->Seek(sec, false);
return true; return true;
} }

View File

@@ -37,7 +37,7 @@ class Input
bool isContainerRunning; bool isContainerRunning;
bool terminating; bool terminating;
Player *context; Player *player;
AVFormatContext *avfc; AVFormatContext *avfc;
uint64_t readCount; uint64_t readCount;
public: public:

View File

@@ -47,7 +47,7 @@ class Manager
friend class Player; friend class Player;
private: private:
Player *context; Player *player;
OpenThreads::Mutex mutex; OpenThreads::Mutex mutex;
std::map<int,Track *> videoTracks, audioTracks, subtitleTracks, teletextTracks; std::map<int,Track *> videoTracks, audioTracks, subtitleTracks, teletextTracks;
public: public:

View File

@@ -32,7 +32,7 @@ class Output
Writer *videoWriter, *audioWriter; Writer *videoWriter, *audioWriter;
OpenThreads::Mutex audioMutex, videoMutex; OpenThreads::Mutex audioMutex, videoMutex;
AVStream *audioStream, *videoStream; AVStream *audioStream, *videoStream;
Player *context; Player *player;
public: public:
Output(); Output();
~Output(); ~Output();

View File

@@ -1,82 +0,0 @@
#ifndef __PLAYBACK_H__
#define __PLAYBACK_H__
#include <stdint.h>
#include <string>
#include <vector>
#include <map>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
extern "C" {
#include <libavutil/avutil.h>
#include <libavutil/time.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libavutil/opt.h>
}
class Player;
class Input;
class Playback {
friend class Player;
friend class Input;
private:
Player *context;
bool isHttp;
bool isPaused;
bool isCreationPhase;
bool isSlowMotion;
int Speed;
int AVSync;
bool isVideo;
bool isAudio;
std::string url;
bool noprobe; /* hack: only minimal probing in av_find_stream_info */
int hasThreadStarted;
public:
bool isForwarding;
bool isBackWard;
bool isPlaying;
bool abortPlayback;
bool abortRequested;
uint64_t readCount;
bool SwitchAudio(int pid);
bool SwitchVideo(int pid);
bool SwitchTeletext(int pid);
bool SwitchSubtitle(int pid);
bool GetPts(int64_t &pts);
bool GetFrameCount(int64_t &framecount);
bool GetDuration(double &duration);
bool GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
bool SlowMotion(int repeats);
bool FastBackward(int speed);
bool FastForward(int speed);
bool Open(const char *Url);
bool Close();
bool Play();
bool Pause();
bool Continue();
bool Stop();
bool Seek(float pos, bool absolute);
bool Terminate();
static void* SupervisorThread(void*);
Playback();
};
#endif

View File

@@ -23,8 +23,6 @@ extern "C" {
#include "input.h" #include "input.h"
#include "output.h" #include "output.h"
#include "manager.h" #include "manager.h"
#include "playback.h"
#include "player.h"
struct Chapter struct Chapter
{ {
@@ -37,27 +35,61 @@ class Player {
friend class Input; friend class Input;
friend class Output; friend class Output;
friend class Manager; friend class Manager;
friend class Playback;
friend class cPlayback; friend class cPlayback;
friend int interrupt_cb(void *arg);
private: private:
Input input; Input input;
Output output; Output output;
Manager manager; Manager manager;
Playback playback;
OpenThreads::Mutex chapterMutex; OpenThreads::Mutex chapterMutex;
std::vector<Chapter> chapters; std::vector<Chapter> chapters;
public: //FIXME bool abortPlayback;
int64_t *currentAudioPtsP; bool abortRequested;
public: bool isHttp;
Player() bool isPaused;
{ bool isCreationPhase;
input.context = this; bool isSlowMotion;
output.context = this; int Speed;
playback.context = this; int AVSync;
manager.context = this;
}
bool isVideo;
bool isAudio;
std::string url;
bool noprobe; /* hack: only minimal probing in av_find_stream_info */
int hasThreadStarted;
static void* SupervisorThread(void*);
public:
bool isForwarding;
bool isBackWard;
bool isPlaying;
uint64_t readCount;
bool SwitchAudio(int pid);
bool SwitchVideo(int pid);
bool SwitchTeletext(int pid);
bool SwitchSubtitle(int pid);
bool GetPts(int64_t &pts);
bool GetFrameCount(int64_t &framecount);
bool GetDuration(double &duration);
bool GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
bool SlowMotion(int repeats);
bool FastBackward(int speed);
bool FastForward(int speed);
bool Open(const char *Url);
bool Close();
bool Play();
bool Pause();
bool Continue();
bool Stop();
bool Seek(float pos, bool absolute);
bool Terminate();
bool GetChapters(std::vector<int> &positions, std::vector<std::string> &titles); bool GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
void SetChapters(std::vector<Chapter> &Chapters); void SetChapters(std::vector<Chapter> &Chapters);
Player();
}; };
#endif #endif

View File

@@ -76,7 +76,7 @@ void Manager::addTeletextTrack(Track &track)
std::vector<Track> Manager::getVideoTracks() std::vector<Track> Manager::getVideoTracks()
{ {
context->input.UpdateTracks(); player->input.UpdateTracks();
std::vector<Track> res; std::vector<Track> res;
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for(std::map<int,Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it) for(std::map<int,Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
@@ -87,7 +87,7 @@ std::vector<Track> Manager::getVideoTracks()
std::vector<Track> Manager::getAudioTracks() std::vector<Track> Manager::getAudioTracks()
{ {
context->input.UpdateTracks(); player->input.UpdateTracks();
std::vector<Track> res; std::vector<Track> res;
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for(std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) for(std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
@@ -98,7 +98,7 @@ std::vector<Track> Manager::getAudioTracks()
std::vector<Track> Manager::getSubtitleTracks() std::vector<Track> Manager::getSubtitleTracks()
{ {
context->input.UpdateTracks(); player->input.UpdateTracks();
std::vector<Track> res; std::vector<Track> res;
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for(std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it) for(std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it)
@@ -109,7 +109,7 @@ std::vector<Track> Manager::getSubtitleTracks()
std::vector<Track> Manager::getTeletextTracks() std::vector<Track> Manager::getTeletextTracks()
{ {
context->input.UpdateTracks(); player->input.UpdateTracks();
std::vector<Track> res; std::vector<Track> res;
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex); OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for(std::map<int,Track*>::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it) for(std::map<int,Track*>::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it)

View File

@@ -19,7 +19,6 @@
#include <errno.h> #include <errno.h>
#include <poll.h> #include <poll.h>
#include "playback.h"
#include "player.h" #include "player.h"
#include "misc.h" #include "misc.h"
@@ -28,62 +27,65 @@
static pthread_t supervisorThread; static pthread_t supervisorThread;
Playback::Playback() Player::Player()
{ {
input.player = this;
output.player = this;
manager.player = this;
hasThreadStarted = 0; hasThreadStarted = 0;
} }
void *Playback::SupervisorThread(void *arg) void *Player::SupervisorThread(void *arg)
{ {
Playback *me = (Playback *) arg; Player *player = (Player *) arg;
me->hasThreadStarted = 1; player->hasThreadStarted = 1;
me->context->input.Play(); player->input.Play();
me->hasThreadStarted = 2; player->hasThreadStarted = 2;
me->Terminate(); player->Terminate();
fprintf(stderr, "terminating\n"); fprintf(stderr, "terminating\n");
me->hasThreadStarted = 0; player->hasThreadStarted = 0;
pthread_exit(NULL); pthread_exit(NULL);
} }
bool Playback::Open(const char *Url) bool Player::Open(const char *Url)
{ {
if (context->playback.isPlaying) if (isPlaying)
Stop(); // shouldn't happen. Most definitely a bug Stop(); // shouldn't happen. Most definitely a bug
fprintf(stderr, "URL=%s\n", Url); fprintf(stderr, "URL=%s\n", Url);
if (context->playback.isPlaying) { // shouldn't happen if (isPlaying) { // shouldn't happen
fprintf(stderr, "playback already running\n"); fprintf(stderr, "playback already running\n");
return false; return false;
} }
context->playback.isHttp = 0; isHttp = 0;
if (!strncmp("file://", Url, 7) || !strncmp("myts://", Url, 7)) { if (!strncmp("file://", Url, 7) || !strncmp("myts://", Url, 7)) {
if (!strncmp("myts://", Url, 7)) { if (!strncmp("myts://", Url, 7)) {
context->playback.url = "file"; url = "file";
context->playback.url += (Url + 4); url += (Url + 4);
context->playback.noprobe = 1; noprobe = 1;
} else { } else {
context->playback.noprobe = 0; noprobe = 0;
context->playback.url = Url; url = Url;
} }
} else if (strstr(Url, "://")) { } else if (strstr(Url, "://")) {
context->playback.isHttp = 1; isHttp = 1;
if (!strncmp("mms://", Url, 6)) { if (!strncmp("mms://", Url, 6)) {
context->playback.url = "mmst"; url = "mmst";
context->playback.url += (Url + 3); url += (Url + 3);
} else } else
context->playback.url = Url; url = Url;
} else { } else {
fprintf(stderr, "Unknown stream (%s)\n", Url); fprintf(stderr, "Unknown stream (%s)\n", Url);
return false; return false;
} }
context->manager.clearTracks(); manager.clearTracks();
if (!context->input.Init(context->playback.url.c_str())) if (!input.Init(url.c_str()))
return false; return false;
fprintf(stderr, "exiting with value 0\n"); fprintf(stderr, "exiting with value 0\n");
@@ -91,52 +93,52 @@ bool Playback::Open(const char *Url)
return true; return true;
} }
bool Playback::Close() bool Player::Close()
{ {
bool ret = true; bool ret = true;
context->playback.isPaused = 0; isPaused = 0;
context->playback.isPlaying = 0; isPlaying = 0;
context->playback.isForwarding = 0; isForwarding = 0;
context->playback.isBackWard = 0; isBackWard = 0;
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 0; Speed = 0;
context->playback.url.clear(); url.clear();
return ret; return ret;
} }
bool Playback::Play() bool Player::Play()
{ {
pthread_attr_t attr; pthread_attr_t attr;
bool ret = true; bool ret = true;
if (!context->playback.isPlaying) { if (!isPlaying) {
context->playback.AVSync = 1; AVSync = 1;
context->output.AVSync(true); output.AVSync(true);
context->playback.isCreationPhase = 1; // allows the created thread to go into wait mode isCreationPhase = 1; // allows the created thread to go into wait mode
ret = context->output.Play(); ret = output.Play();
if (!ret) { if (!ret) {
context->playback.isCreationPhase = 0; // allow thread to go into next state isCreationPhase = 0; // allow thread to go into next state
} else { } else {
context->playback.isPlaying = 1; isPlaying = 1;
context->playback.isPaused = 0; isPaused = 0;
context->playback.isForwarding = 0; isForwarding = 0;
if (context->playback.isBackWard) { if (isBackWard) {
context->playback.isBackWard = 0; isBackWard = 0;
context->output.Mute(false); output.Mute(false);
} }
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 1; Speed = 1;
if (hasThreadStarted == 0) { if (hasThreadStarted == 0) {
int error; int error;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, &context->playback))) { if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, this))) {
fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error)); fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error));
ret = false; ret = false;
@@ -147,7 +149,7 @@ bool Playback::Play()
fprintf(stderr, "clearing isCreationPhase!\n"); fprintf(stderr, "clearing isCreationPhase!\n");
context->playback.isCreationPhase = 0; // allow thread to go into next state isCreationPhase = 0; // allow thread to go into next state
} }
} else { } else {
@@ -160,26 +162,26 @@ bool Playback::Play()
return ret; return ret;
} }
bool Playback::Pause() bool Player::Pause()
{ {
bool ret = true; bool ret = true;
if (context->playback.isPlaying && !context->playback.isPaused) { if (isPlaying && !isPaused) {
if (context->playback.isSlowMotion) if (isSlowMotion)
context->output.Clear(); output.Clear();
context->output.Pause(); output.Pause();
context->playback.isPaused = 1; isPaused = 1;
//context->playback.isPlaying = 1; //isPlaying = 1;
context->playback.isForwarding = 0; isForwarding = 0;
if (context->playback.isBackWard) { if (isBackWard) {
context->playback.isBackWard = 0; isBackWard = 0;
context->output.Mute(false); output.Mute(false);
} }
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 1; Speed = 1;
} else { } else {
fprintf(stderr,"playback not playing or already in pause mode\n"); fprintf(stderr,"playback not playing or already in pause mode\n");
ret = false; ret = false;
@@ -190,27 +192,27 @@ bool Playback::Pause()
return ret; return ret;
} }
bool Playback::Continue() bool Player::Continue()
{ {
int ret = true; int ret = true;
if (context->playback.isPlaying && (context->playback.isPaused || context->playback.isForwarding if (isPlaying && (isPaused || isForwarding
|| context->playback.isBackWard || context->playback.isSlowMotion)) { || isBackWard || isSlowMotion)) {
if (context->playback.isSlowMotion) if (isSlowMotion)
context->output.Clear(); output.Clear();
context->output.Continue(); output.Continue();
context->playback.isPaused = 0; isPaused = 0;
//context->playback.isPlaying = 1; //isPlaying = 1;
context->playback.isForwarding = 0; isForwarding = 0;
if (context->playback.isBackWard) { if (isBackWard) {
context->playback.isBackWard = 0; isBackWard = 0;
context->output.Mute(false); output.Mute(false);
} }
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 1; Speed = 1;
} else { } else {
fprintf(stderr,"continue not possible\n"); fprintf(stderr,"continue not possible\n");
ret = false; ret = false;
@@ -219,25 +221,25 @@ bool Playback::Continue()
return ret; return ret;
} }
bool Playback::Stop() bool Player::Stop()
{ {
bool ret = true; bool ret = true;
int wait_time = 20; int wait_time = 20;
if (context->playback.isPlaying) { if (isPlaying) {
context->playback.isPaused = 0; isPaused = 0;
context->playback.isPlaying = 0; isPlaying = 0;
context->playback.isForwarding = 0; isForwarding = 0;
if (context->playback.isBackWard) { if (isBackWard) {
context->playback.isBackWard = 0; isBackWard = 0;
context->output.Mute(false); output.Mute(false);
} }
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 0; Speed = 0;
context->output.Stop(); output.Stop();
context->input.Stop(); input.Stop();
} else { } else {
fprintf(stderr,"stop not possible\n"); fprintf(stderr,"stop not possible\n");
@@ -262,30 +264,28 @@ bool Playback::Stop()
} }
// FIXME // FIXME
bool Playback::Terminate() bool Player::Terminate()
{ {
bool ret = true; bool ret = true;
int wait_time = 20; int wait_time = 20;
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (context->playback.isPlaying) { if (isPlaying) {
if (!context->playback.abortRequested && !context->output.Flush()) { if (!abortRequested && !output.Flush()) {
fprintf(stderr,"failed to flush output.\n"); fprintf(stderr,"failed to flush output.\n");
} }
ret = context->input.Stop(); ret = input.Stop();
context->playback.isPaused = 0; isPaused = 0;
context->playback.isPlaying = 0; isPlaying = 0;
context->playback.isForwarding = 0; isForwarding = 0;
context->playback.isBackWard = 0; isBackWard = 0;
context->playback.isSlowMotion = 0; isSlowMotion = 0;
context->playback.Speed = 0; Speed = 0;
} else { } else {
fprintf(stderr,"%p %d\n", context, context->playback.isPlaying);
/* fixme: konfetti: we should return an error here but this seems to be a condition which /* fixme: konfetti: we should return an error here but this seems to be a condition which
* can happen and is not a real error, which leads to a dead neutrino. should investigate * can happen and is not a real error, which leads to a dead neutrino. should investigate
* here later. * here later.
@@ -309,22 +309,22 @@ bool Playback::Terminate()
return ret; return ret;
} }
bool Playback::FastForward(int speed) bool Player::FastForward(int speed)
{ {
int ret = true; int ret = true;
/* Audio only forwarding not supported */ /* Audio only forwarding not supported */
if (context->playback.isVideo && !context->playback.isHttp && !context->playback.isBackWard if (isVideo && !isHttp && !isBackWard
&& (!context->playback.isPaused || context-> playback.isPlaying)) { && (!isPaused || isPlaying)) {
if ((speed <= 0) || (speed > cMaxSpeed_ff)) { if ((speed <= 0) || (speed > cMaxSpeed_ff)) {
fprintf(stderr, "speed %d out of range (1 - %d) \n", speed, cMaxSpeed_ff); fprintf(stderr, "speed %d out of range (1 - %d) \n", speed, cMaxSpeed_ff);
return false; return false;
} }
context->playback.isForwarding = 1; isForwarding = 1;
context->playback.Speed = speed; Speed = speed;
context->output.FastForward(speed); output.FastForward(speed);
} else { } else {
fprintf(stderr,"fast forward not possible\n"); fprintf(stderr,"fast forward not possible\n");
ret = false; ret = false;
@@ -333,13 +333,13 @@ bool Playback::FastForward(int speed)
return ret; return ret;
} }
bool Playback::FastBackward(int speed) bool Player::FastBackward(int speed)
{ {
bool ret = true; bool ret = true;
/* Audio only reverse play not supported */ /* Audio only reverse play not supported */
if (context->playback.isVideo && !context->playback.isForwarding if (isVideo && !isForwarding
&& (!context->playback.isPaused || context->playback.isPlaying)) { && (!isPaused || isPlaying)) {
if ((speed > 0) || (speed < cMaxSpeed_fr)) { if ((speed > 0) || (speed < cMaxSpeed_fr)) {
fprintf(stderr, "speed %d out of range (0 - %d) \n", speed, cMaxSpeed_fr); fprintf(stderr, "speed %d out of range (0 - %d) \n", speed, cMaxSpeed_fr);
@@ -347,19 +347,19 @@ bool Playback::FastBackward(int speed)
} }
if (speed == 0) { if (speed == 0) {
context->playback.isBackWard = false; isBackWard = false;
context->playback.Speed = false; /* reverse end */ Speed = false; /* reverse end */
} else { } else {
context->playback.Speed = speed; Speed = speed;
context->playback.isBackWard = true; isBackWard = true;
} }
context->output.Clear(); output.Clear();
#if 0 #if 0
if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0) { if (output->Command(player, OUTPUT_REVERSE, NULL) < 0) {
fprintf(stderr,"OUTPUT_REVERSE failed\n"); fprintf(stderr,"OUTPUT_REVERSE failed\n");
context->playback.isBackWard = 0; isBackWard = 0;
context->playback.Speed = 1; Speed = 1;
ret = false; ret = false;
} }
#endif #endif
@@ -368,98 +368,98 @@ bool Playback::FastBackward(int speed)
ret = false; ret = false;
} }
if (context->playback.isBackWard) if (isBackWard)
context->output.Mute(true); output.Mute(true);
return ret; return ret;
} }
bool Playback::SlowMotion(int repeats) bool Player::SlowMotion(int repeats)
{ {
if (context->playback.isVideo && !context->playback.isHttp && context->playback.isPlaying) { if (isVideo && !isHttp && isPlaying) {
if (context->playback.isPaused) if (isPaused)
Continue(); Continue();
switch (repeats) { switch (repeats) {
case 2: case 2:
case 4: case 4:
case 8: case 8:
context->playback.isSlowMotion = true; isSlowMotion = true;
break; break;
default: default:
repeats = 0; repeats = 0;
} }
context->output.SlowMotion(repeats); output.SlowMotion(repeats);
return true; return true;
} }
fprintf(stderr, "slowmotion not possible\n"); fprintf(stderr, "slowmotion not possible\n");
return false; return false;
} }
bool Playback::Seek(float pos, bool absolute) bool Player::Seek(float pos, bool absolute)
{ {
context->output.Clear(); output.Clear();
return context->input.Seek(pos, absolute); return input.Seek(pos, absolute);
} }
bool Playback::GetPts(int64_t &pts) bool Player::GetPts(int64_t &pts)
{ {
if (context->playback.isPlaying) if (isPlaying)
return context->output.GetPts(pts); return output.GetPts(pts);
return false; return false;
} }
bool Playback::GetFrameCount(int64_t &frameCount) bool Player::GetFrameCount(int64_t &frameCount)
{ {
if (context->playback.isPlaying) if (isPlaying)
return context->output.GetFrameCount(frameCount); return output.GetFrameCount(frameCount);
return false; return false;
} }
bool Playback::GetDuration(double &duration) bool Player::GetDuration(double &duration)
{ {
duration = -1; duration = -1;
if (context->playback.isPlaying) if (isPlaying)
return context->input.GetDuration(duration); return input.GetDuration(duration);
return false; return false;
} }
bool Playback::SwitchVideo(int pid) bool Player::SwitchVideo(int pid)
{ {
Track *track = context->manager.getVideoTrack(pid); Track *track = manager.getVideoTrack(pid);
if (track) if (track)
context->input.SwitchVideo(track); input.SwitchVideo(track);
return !!track; return !!track;
} }
bool Playback::SwitchAudio(int pid) bool Player::SwitchAudio(int pid)
{ {
Track *track = context->manager.getAudioTrack(pid); Track *track = manager.getAudioTrack(pid);
if (track) if (track)
context->input.SwitchAudio(track); input.SwitchAudio(track);
return !!track; return !!track;
} }
bool Playback::SwitchSubtitle(int pid) bool Player::SwitchSubtitle(int pid)
{ {
Track *track = context->manager.getSubtitleTrack(pid); Track *track = manager.getSubtitleTrack(pid);
if (track) if (track)
context->input.SwitchSubtitle(track); input.SwitchSubtitle(track);
return !!track; return !!track;
} }
bool Playback::SwitchTeletext(int pid) bool Player::SwitchTeletext(int pid)
{ {
Track *track = context->manager.getTeletextTrack(pid); Track *track = manager.getTeletextTrack(pid);
if (track) if (track)
context->input.SwitchTeletext(track); input.SwitchTeletext(track);
return !!track; return !!track;
} }
bool Playback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values) bool Player::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
{ {
return context->input.GetMetadata(keys, values); return input.GetMetadata(keys, values);
} }
bool Player::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles) bool Player::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)

View File

@@ -97,12 +97,12 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
strcat(file, filename); strcat(file, filename);
//try to open file //try to open file
if(player && player->playback.Open(file)) { if(player && player->Open(file)) {
if (pm != PLAYMODE_TS) { if (pm != PLAYMODE_TS) {
player->output.Open(); player->output.Open();
SetAPid(apid, 0); SetAPid(apid, 0);
ret = player->playback.Play(); ret = player->Play();
} }
} }
@@ -119,7 +119,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
{ {
//pause playback in case of timeshift //pause playback in case of timeshift
//FIXME: no picture on tv //FIXME: no picture on tv
if (!player || !player->playback.Pause()) if (!player || !player->Pause())
{ {
ret = false; ret = false;
printf("failed to pause playback\n"); printf("failed to pause playback\n");
@@ -157,13 +157,13 @@ bool cPlayback::Stop(void)
//if(playing==false) return false; //if(playing==false) return false;
if(player) if(player)
player->playback.Stop(); player->Stop();
if(player) if(player)
player->output.Close(); player->output.Close();
if(player) if(player)
player->playback.Close(); player->Close();
if(player) { if(player) {
delete player; delete player;
player = NULL; player = NULL;
@@ -178,7 +178,7 @@ bool cPlayback::SetAPid(int pid, bool ac3 __attribute__((unused)))
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
if(pid!=mAudioStream){ if(pid!=mAudioStream){
if(player) if(player)
player->playback.SwitchAudio(pid); player->SwitchAudio(pid);
mAudioStream=pid; mAudioStream=pid;
} }
return true; return true;
@@ -189,7 +189,7 @@ bool cPlayback::SetSubtitlePid(int pid)
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
if(pid!=mSubtitleStream){ if(pid!=mSubtitleStream){
if(player) if(player)
player->playback.SwitchSubtitle(pid); player->SwitchSubtitle(pid);
mSubtitleStream = pid; mSubtitleStream = pid;
} }
return true; return true;
@@ -200,7 +200,7 @@ bool cPlayback::SetTeletextPid(int pid)
printf("%s:%s\n", FILENAME, __FUNCTION__); printf("%s:%s\n", FILENAME, __FUNCTION__);
if(pid!=mTeletextStream){ if(pid!=mTeletextStream){
if(player) if(player)
player->playback.SwitchTeletext(pid); player->SwitchTeletext(pid);
mTeletextStream=pid; mTeletextStream=pid;
} }
return true; return true;
@@ -218,7 +218,7 @@ bool cPlayback::SetSpeed(int speed)
usleep(500000); usleep(500000);
if (player) { if (player) {
player->output.Open(); player->output.Open();
playing = player->playback.Play(); playing = player->Play();
} }
} }
@@ -234,39 +234,39 @@ bool cPlayback::SetSpeed(int speed)
if (speed > 1) if (speed > 1)
{ {
/* direction switch ? */ /* direction switch ? */
if (player->playback.isBackWard) if (player->isBackWard)
{ {
result = player->playback.FastBackward(0); result = player->FastBackward(0);
printf("result = %d\n", result); printf("result = %d\n", result);
} }
result = player->playback.FastForward(speed); result = player->FastForward(speed);
} else } else
if (speed < 0) if (speed < 0)
{ {
/* direction switch ? */ /* direction switch ? */
if (player->playback.isForwarding) if (player->isForwarding)
{ {
result = player->playback.Continue(); result = player->Continue();
printf("result = %d\n", result); printf("result = %d\n", result);
} }
result = player->playback.FastBackward(speed); result = player->FastBackward(speed);
} }
else else
if (speed == 0) if (speed == 0)
{ {
/* konfetti: hmmm accessing the member isn't very proper */ /* konfetti: hmmm accessing the member isn't very proper */
if ((player->playback.isForwarding) || (!player->playback.isBackWard)) if ((player->isForwarding) || (!player->isBackWard))
player->playback.Pause(); player->Pause();
else else
{ {
player->playback.FastForward(0); player->FastForward(0);
} }
} else } else
{ {
result = player->playback.Continue(); result = player->Continue();
} }
if (init_jump > -1) if (init_jump > -1)
@@ -293,7 +293,7 @@ bool cPlayback::GetSpeed(int &speed) const
void cPlayback::GetPts(uint64_t &pts) void cPlayback::GetPts(uint64_t &pts)
{ {
if (player) if (player)
player->playback.GetPts((int64_t &) pts); player->GetPts((int64_t &) pts);
} }
// in milliseconds // in milliseconds
@@ -325,7 +325,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
if(playing==false) return false; if(playing==false) return false;
if (player && !player->playback.isPlaying) { if (player && !player->isPlaying) {
printf("cPlayback::%s !!!!EOF!!!! < -1\n", __func__); printf("cPlayback::%s !!!!EOF!!!! < -1\n", __func__);
position = duration + 1000; position = duration + 1000;
return false; return false;
@@ -333,7 +333,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
int64_t vpts = 0; int64_t vpts = 0;
if(player) if(player)
player->playback.GetPts(vpts); player->GetPts(vpts);
if(vpts <= 0) { if(vpts <= 0) {
//printf("ERROR: vpts==0"); //printf("ERROR: vpts==0");
@@ -348,7 +348,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
double length = 0; double length = 0;
if(player) if(player)
player->playback.GetDuration(length); player->GetDuration(length);
if(length <= 0) { if(length <= 0) {
duration = duration+1000; duration = duration+1000;
@@ -375,7 +375,7 @@ bool cPlayback::SetPosition(int position, bool absolute)
} }
float pos = (position/1000.0); float pos = (position/1000.0);
if(player) if(player)
player->playback.Seek(pos, absolute); player->Seek(pos, absolute);
return true; return true;
} }
@@ -485,21 +485,21 @@ cPlayback::~cPlayback()
void cPlayback::RequestAbort() { void cPlayback::RequestAbort() {
if (player) { if (player) {
player->playback.abortRequested = 1; player->abortRequested = 1;
while (player->playback.isPlaying) while (player->isPlaying)
usleep(100000); usleep(100000);
} }
} }
bool cPlayback::IsPlaying() { bool cPlayback::IsPlaying() {
if (player) if (player)
return player->playback.isPlaying; return player->isPlaying;
return false; return false;
} }
unsigned long long cPlayback::GetReadCount() { unsigned long long cPlayback::GetReadCount() {
if (player) if (player)
return player->playback.readCount; return player->readCount;
return 0; return 0;
} }
@@ -515,7 +515,7 @@ bool cPlayback::IsPlaying(void) const
*/ */
if (playing) if (playing)
{ {
return player->playback->isPlaying; return player->isPlaying;
} }
return playing; return playing;