mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-libstb-hal.git
synced 2025-08-26 23:12:44 +02:00
libeplayer3: merge Playback to Player class
Origin commit data
------------------
Branch: master
Commit: b08abf6b52
Author: martii <m4rtii@gmx.de>
Date: 2014-04-07 (Mon, 07 Apr 2014)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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:
|
||||||
|
@@ -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:
|
||||||
|
@@ -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();
|
||||||
|
@@ -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
|
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user