From 225ec050ae3030f1836da9980c5b5baa1a7a19da Mon Sep 17 00:00:00 2001 From: martii Date: Sun, 6 Apr 2014 18:19:00 +0200 Subject: [PATCH] libeplayer3: implement Output class Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/cd3d91fa389649197144e278dfafbe3af095b7d6 Author: martii Date: 2014-04-06 (Sun, 06 Apr 2014) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3/container/container_ffmpeg.cpp | 46 +- libeplayer3/include/manager.h | 4 +- libeplayer3/include/output.h | 70 +- libeplayer3/include/player.h | 3 +- libeplayer3/manager/audio.cpp | 6 +- libeplayer3/manager/chapter.cpp | 4 +- libeplayer3/manager/subtitle.cpp | 4 +- libeplayer3/manager/teletext.cpp | 4 +- libeplayer3/manager/video.cpp | 6 +- libeplayer3/output/linuxdvb.cpp | 800 +++++++-------------- libeplayer3/playback/playback.cpp | 77 +- libeplayer3/player.cpp | 3 - libspark/playback_libeplayer3.cpp | 29 +- 13 files changed, 377 insertions(+), 679 deletions(-) diff --git a/libeplayer3/container/container_ffmpeg.cpp b/libeplayer3/container/container_ffmpeg.cpp index 33a65e6..0ee772c 100644 --- a/libeplayer3/container/container_ffmpeg.cpp +++ b/libeplayer3/container/container_ffmpeg.cpp @@ -189,7 +189,7 @@ static void *FFMPEGThread(void *arg) } seek_sec_abs = -1.0; } else if (context->playback->BackWard && av_gettime() >= showtime) { - context->output->Command(context, OUTPUT_CLEAR, "video"); + context->output.ClearVideo(); if (bofcount == 1) { showtime = av_gettime(); @@ -272,23 +272,23 @@ static void *FFMPEGThread(void *arg) ffmpeg_printf(200, "packet_size %d - index %d\n", packet.size, pid); - if (videoTrack && (videoTrack->Id == pid)) { + if (videoTrack && (videoTrack->pid == pid)) { currentVideoPts = pts = calcPts(avContext, videoTrack->stream, packet.pts); ffmpeg_printf(200, "VideoTrack index = %d %lld\n", pid, currentVideoPts); - if (!context->output->Write(avContext, videoTrack->stream, &packet, currentVideoPts)) - ffmpeg_err("writing data to video device failed\n"); - } else if (audioTrack && (audioTrack->Id == pid)) { + if (!context->output.Write(avContext, videoTrack->stream, &packet, currentVideoPts)) + ;//ffmpeg_err("writing data to video device failed\n"); + } else if (audioTrack && (audioTrack->pid == pid)) { if (restart_audio_resampling) { restart_audio_resampling = false; - context->output->Write(avContext, audioTrack->stream, NULL, currentAudioPts); + context->output.Write(avContext, audioTrack->stream, NULL, currentAudioPts); } if (!context->playback->BackWard) { currentAudioPts = pts = calcPts(avContext, audioTrack->stream, packet.pts); - if (!context->output->Write(avContext, audioTrack->stream, &packet, currentAudioPts)) - ffmpeg_err("writing data to audio device failed\n"); + if (!context->output.Write(avContext, audioTrack->stream, &packet, currentAudioPts)) + ;//ffmpeg_err("writing data to audio device failed\n"); } - } else if (subtitleTrack && (subtitleTrack->Id == pid)) { + } else if (subtitleTrack && (subtitleTrack->pid == pid)) { float duration = 3.0; ffmpeg_printf(100, "subtitleTrack->stream %p \n", subtitleTrack->stream); @@ -322,15 +322,15 @@ static void *FFMPEGThread(void *arg) } } } /* duration */ - } else if (teletextTrack && (teletextTrack->Id == pid)) { + } else if (teletextTrack && (teletextTrack->pid == pid)) { teletext_write(pid, packet.data, packet.size); } av_free_packet(&packet); } /* while */ - if (context && context->playback && context->output && context->playback->abortRequested) - context->output->Command(context, OUTPUT_CLEAR, NULL); + if (context && context->playback && context->playback->abortRequested) + context->output.Clear(); dvbsub_ass_clear(); @@ -412,7 +412,7 @@ static void container_ffmpeg_read_subtitle(Player * context, const char *filenam Track_t track; track.Name = format; track.is_static = 1; - track.Id = pid; + track.pid = pid; context->manager->subtitle->Command(context, MANAGER_ADD, &track); } @@ -425,10 +425,6 @@ static void container_ffmpeg_read_subtitles(Player * context, const char *filena container_ffmpeg_read_subtitle(context, filename, "ssa", 0xFFFD); } -// from output/linuxdvb.cpp ... FIXME! -extern AVStream *audioStream; -extern AVStream *videoStream; - int container_ffmpeg_init(Player * context, const char *filename) { int err; @@ -506,8 +502,8 @@ int container_ffmpeg_init(Player * context, const char *filename) terminating = 0; int res = container_ffmpeg_update_tracks(context, filename); -audioStream = NULL; -videoStream = NULL; +AVStream *audioStream = NULL; +AVStream *videoStream = NULL; unsigned int n, found_av = 0; for (n = 0; n < avContext->nb_streams; n++) { @@ -527,6 +523,8 @@ videoStream = NULL; break; } } + context->output.SwitchAudio(audioStream); + context->output.SwitchVideo(videoStream); if (!found_av) { avformat_close_input(&avContext); isContainerRunning = 0; @@ -547,7 +545,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); for (i = 0; i < avContext->nb_chapters; i++) { Track_t track; - track.Id = i; + track.pid = i; AVDictionaryEntry *title; AVChapter *ch = avContext->chapters[i]; title = av_dict_get(ch->metadata, "title", NULL, 0); @@ -591,7 +589,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) track.Name = "und"; track.avfc = avContext; - track.Id = stream->id; + track.pid = stream->id; if (stream->duration == AV_NOPTS_VALUE) { ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); @@ -618,7 +616,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) ffmpeg_printf(10, "Language %s\n", track.Name.c_str()); - track.Id = stream->id; + track.pid = stream->id; track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; if (stream->duration == AV_NOPTS_VALUE) { @@ -670,7 +668,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) ffmpeg_printf(10, "Language %s\n", track.Name.c_str()); - track.Id = stream->id; + track.pid = stream->id; track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; #if 0 @@ -851,7 +849,7 @@ static int container_ffmpeg_switch_audio(Player * context, int *arg) Track_t *audioTrack = NULL; context->manager->audio->Command(context, MANAGER_GET_TRACK, &arg); if (audioTrack) { - audioStream = audioTrack->stream; + context->output.SwitchAudio(audioTrack->stream); ffmpeg_printf(10, "track %d\n", *arg); /* Hellmaster1024: nothing to do here! */ float sec = -5.0; diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index f87eeea..3cb8ed2 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -31,7 +31,7 @@ typedef enum { typedef struct Track_s { std::string Name; - int Id; + int pid; /* new field for ffmpeg - add at the end so no problem * can occur with not changed srt saa container @@ -53,7 +53,7 @@ typedef struct Track_s { int ac3flags; - Track_s() : Id(-1), language(NULL), duration(-1), avfc(NULL), stream(NULL), pending(0), is_static(0), chapter_start(0), chapter_end(0), ac3flags(-1) {} + Track_s() : pid(-1), language(NULL), duration(-1), avfc(NULL), stream(NULL), pending(0), is_static(0), chapter_start(0), chapter_end(0), ac3flags(-1) {} } Track_t; struct Player; diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index 7708376..8dc5016 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -4,6 +4,11 @@ #include #include + +#include +#include +#include + extern "C" { #include #include @@ -12,39 +17,38 @@ extern "C" { #include } -typedef enum { - OUTPUT_INIT, - OUTPUT_ADD, - OUTPUT_DEL, - OUTPUT_PLAY, - OUTPUT_STOP, - OUTPUT_PAUSE, - OUTPUT_OPEN, - OUTPUT_CLOSE, - OUTPUT_FLUSH, - OUTPUT_CONTINUE, - OUTPUT_FASTFORWARD, - OUTPUT_AVSYNC, - OUTPUT_CLEAR, - OUTPUT_PTS, - OUTPUT_SLOWMOTION, - OUTPUT_AUDIOMUTE, - OUTPUT_REVERSE, - OUTPUT_DISCONTINUITY_REVERSE, - OUTPUT_GET_FRAME_COUNT, -} OutputCmd_t; +#include "writer.h" -struct Player; - -typedef struct Output_s { - const char *Name; - int (*Command) (Player *, OutputCmd_t, const char *); - bool (*Write) (AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts); - const char **Capabilities; - -} Output_t; - -extern Output_t LinuxDvbOutput; -extern Output_t SubtitleOutput; +class Output +{ + private: + int videofd; + int audiofd; + Writer *videoWriter, *audioWriter; + OpenThreads::Mutex audioMutex, videoMutex; + AVStream *audioStream, *videoStream; + public: + Output(); + ~Output(); + bool Open(); + bool Close(); + bool Play(); + bool Stop(); + bool Pause(); + bool Continue(); + bool Mute(bool); + bool Flush(); + bool FastForward(int speed); + bool SlowMotion(int speed); + bool AVSync(bool); + bool Clear(); + bool ClearAudio(); + bool ClearVideo(); + bool GetPts(int64_t &pts); + bool GetFrameCount(int64_t &framecount); + bool SwitchAudio(AVStream *stream); + bool SwitchVideo(AVStream *stream); + bool Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts); +}; #endif diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index 02a3f66..ff1fccd 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -12,12 +12,13 @@ class Player { public: //FIXME PlaybackHandler_t *playback; ContainerHandler_t *container; - Output_t *output; ManagerHandler_t *manager; int64_t *currentAudioPtsP; public: Player(); ~Player(); + + Output output; }; int container_ffmpeg_update_tracks(Player * context, const char *filename); diff --git a/libeplayer3/manager/audio.cpp b/libeplayer3/manager/audio.cpp index 507dcba..1f46005 100644 --- a/libeplayer3/manager/audio.cpp +++ b/libeplayer3/manager/audio.cpp @@ -77,11 +77,11 @@ static int CurrentPid = -1; static int ManagerAdd(Player * context, Track_t track) { - Tracks[track.Id] = track; + Tracks[track.pid] = track; context->playback->isAudio = 1; if (CurrentPid < 0) - CurrentPid = track.Id; + CurrentPid = track.pid; return cERR_AUDIO_MGR_NO_ERROR; } @@ -95,7 +95,7 @@ static char **ManagerList(Player * context __attribute__ ((unused))) { size_t len = it->second.Name.length() + 20; char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); + snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); tracklist[j] = strdup(tmp); snprintf(tmp, len, "%d\n", it->second.ac3flags); tracklist[j + 1] = strdup(tmp); diff --git a/libeplayer3/manager/chapter.cpp b/libeplayer3/manager/chapter.cpp index 524a19e..66369d2 100644 --- a/libeplayer3/manager/chapter.cpp +++ b/libeplayer3/manager/chapter.cpp @@ -76,7 +76,7 @@ static std::map Tracks; static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) { - Tracks[track.Id] = track; + Tracks[track.pid] = track; return cERR_CHAPTER_MGR_NO_ERROR; } @@ -90,7 +90,7 @@ static char **ManagerList(Player * context __attribute__ ((unused))) { size_t len = it->second.Name.length() + 20; char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); + snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(""); j += 2; diff --git a/libeplayer3/manager/subtitle.cpp b/libeplayer3/manager/subtitle.cpp index 5668f42..8bd5226 100644 --- a/libeplayer3/manager/subtitle.cpp +++ b/libeplayer3/manager/subtitle.cpp @@ -77,7 +77,7 @@ static int CurrentPid = -1; static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) { - Tracks[track.Id] = track; + Tracks[track.pid] = track; context->playback->isAudio = 1; return cERR_SUBTITLE_MGR_NO_ERROR; @@ -92,7 +92,7 @@ static char **ManagerList(Player * context __attribute__ ((unused))) { size_t len = it->second.Name.length() + 20; char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); + snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(""); j += 2; diff --git a/libeplayer3/manager/teletext.cpp b/libeplayer3/manager/teletext.cpp index 7a596df..24ac281 100644 --- a/libeplayer3/manager/teletext.cpp +++ b/libeplayer3/manager/teletext.cpp @@ -77,7 +77,7 @@ static int CurrentPid = -1; static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) { - Tracks[track.Id] = track; + Tracks[track.pid] = track; context->playback->isAudio = 1; return cERR_TELETEXT_MGR_NO_ERROR; @@ -92,7 +92,7 @@ static char **ManagerList(Player * context __attribute__ ((unused))) { size_t len = it->second.Name.length() + 20; char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); + snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(""); j += 2; diff --git a/libeplayer3/manager/video.cpp b/libeplayer3/manager/video.cpp index 02b4a95..1bdfcee 100644 --- a/libeplayer3/manager/video.cpp +++ b/libeplayer3/manager/video.cpp @@ -77,11 +77,11 @@ static int CurrentPid = -1; static int ManagerAdd(Player * context, Track_t track) { - Tracks[track.Id] = track; + Tracks[track.pid] = track; context->playback->isVideo = 1; if (CurrentPid < 0) - CurrentPid = track.Id; + CurrentPid = track.pid; return cERR_VIDEO_MGR_NO_ERROR; } @@ -95,7 +95,7 @@ static char **ManagerList(Player * context __attribute__ ((unused))) { size_t len = it->second.Name.length() + 20; char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); + snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(""); j += 2; diff --git a/libeplayer3/output/linuxdvb.cpp b/libeplayer3/output/linuxdvb.cpp index f5b5942..013928f 100644 --- a/libeplayer3/output/linuxdvb.cpp +++ b/libeplayer3/output/linuxdvb.cpp @@ -47,17 +47,6 @@ #include "misc.h" #include "pes.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define LINUXDVB_DEBUG - -static const char FILENAME[] = __FILE__; - -#define cERR_LINUXDVB_NO_ERROR 0 -#define cERR_LINUXDVB_ERROR -1 - #define dioctl(fd,req,arg) ({ \ int _r = ioctl(fd,req,arg); \ if (_r) \ @@ -65,605 +54,342 @@ static const char FILENAME[] = __FILE__; _r; \ }) -static const char VIDEODEV[] = "/dev/dvb/adapter0/video0"; -static const char AUDIODEV[] = "/dev/dvb/adapter0/audio0"; +#define VIDEODEV "/dev/dvb/adapter0/video0" +#define AUDIODEV "/dev/dvb/adapter0/audio0" -static int videofd = -1; -static int audiofd = -1; - -static Writer *videoWriter = NULL; -static Writer *audioWriter = NULL; -OpenThreads::Mutex audioMutex, videoMutex; - -AVStream *audioStream = NULL; -AVStream *videoStream = NULL; - -unsigned long long int sCURRENT_PTS = 0; - -pthread_mutex_t LinuxDVBmutex; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ -int LinuxDvbStop(); - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -void getLinuxDVBMutex(const char *filename - __attribute__ ((unused)), const char *function - __attribute__ ((unused)), int line - __attribute__ ((unused))) +Output::Output() { - - - pthread_mutex_lock(&LinuxDVBmutex); - +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + videofd = audiofd = -1; + videoWriter = audioWriter = NULL; + videoStream = audioStream = NULL; } -void releaseLinuxDVBMutex(const char *filename - __attribute__ ((unused)), const char *function - __attribute__ ((unused)), int line - __attribute__ ((unused))) +Output::~Output() { - pthread_mutex_unlock(&LinuxDVBmutex); - - +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + Close(); } -int LinuxDvbOpen(Player * context __attribute__ ((unused)), char *) +bool Output::Open() { - if (videofd < 0) { - videofd = open(VIDEODEV, O_RDWR); +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); + + if (videofd < 0) + videofd = open(VIDEODEV, O_RDWR); - if (videofd < 0) { - return cERR_LINUXDVB_ERROR; - } + if (videofd < 0) + return false; dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); dioctl(videofd, VIDEO_SELECT_SOURCE, (void *) VIDEO_SOURCE_MEMORY); dioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) STREAM_TYPE_PROGRAM); dioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); - } - if (audiofd < 0) { - audiofd = open(AUDIODEV, O_RDWR); + if (audiofd < 0) + audiofd = open(AUDIODEV, O_RDWR); - if (audiofd < 0) { - - if (videofd < 0) + if (audiofd < 0 && videofd > -1) { close(videofd); - return cERR_LINUXDVB_ERROR; + videofd = -1; + return false; } dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); dioctl(audiofd, AUDIO_SELECT_SOURCE, (void *) AUDIO_SOURCE_MEMORY); dioctl(audiofd, AUDIO_SET_STREAMTYPE, (void *) STREAM_TYPE_PROGRAM); - } - return cERR_LINUXDVB_NO_ERROR; + return true; } -int LinuxDvbClose(Player * context, char *) +bool Output::Close() { +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + Stop(); - /* closing stand alone is not allowed, so prevent - * user from closing and dont call stop. stop will - * set default values for us (speed and so on). - */ - LinuxDvbStop(); - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (videofd > -1) { - close(videofd); - videofd = -1; - } - if (audiofd > -1) { - close(audiofd); - audiofd = -1; - } - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - return cERR_LINUXDVB_NO_ERROR; -} - -int LinuxDvbPlay(Player * context, char *) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - AVStream *_videoStream = videoStream; - AVStream *_audioStream = audioStream; - if (_videoStream) - videoWriter = Writer::GetWriter(_videoStream->codec->codec_id, _videoStream->codec->codec_type); - if (_audioStream) - audioWriter = Writer::GetWriter(_audioStream->codec->codec_id, _audioStream->codec->codec_type); - - if (_videoStream && videofd > -1) { - - if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(_videoStream->codec->codec_id)) - || dioctl(videofd, VIDEO_PLAY, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - if (_audioStream && audiofd > -1) { - if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(_audioStream->codec->codec_id)) - || dioctl(audiofd, AUDIO_PLAY, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - - return ret; -} - -int LinuxDvbStop() -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (videofd > -1) { - dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); - - /* set back to normal speed (end trickmodes) */ - dioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); - - if (dioctl(videofd, VIDEO_STOP, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - if (audiofd > -1) { - dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); - - /* set back to normal speed (end trickmodes) */ - dioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); - - if (dioctl(audiofd, AUDIO_STOP, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - return ret; -} - -int LinuxDvbPause(Player * context __attribute__ ((unused)), char *) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (videofd > -1) { - if (dioctl(videofd, VIDEO_FREEZE, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - if (audiofd > -1) { - if (dioctl(audiofd, AUDIO_PAUSE, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - return ret; -} - -int LinuxDvbContinue(Player * context __attribute__ ((unused)), char *) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - - if (videofd > -1) { - if (dioctl(videofd, VIDEO_CONTINUE, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - if (audiofd > -1) { - if (dioctl(audiofd, AUDIO_CONTINUE, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - - - - return ret; -} - -int LinuxDvbReverseDiscontinuity(Player * context - __attribute__ ((unused)), int *surplus) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; - - - dioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type); - - - return ret; -} - -int LinuxDvbAudioMute(Player * context __attribute__ ((unused)), char *flag) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - - if (audiofd != -1) { - if (*flag == '1') { - //AUDIO_SET_MUTE has no effect with new player - //if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1) - if (dioctl(audiofd, AUDIO_STOP, NULL)) - ret = cERR_LINUXDVB_ERROR; - } else { - //AUDIO_SET_MUTE has no effect with new player - //if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1) - if (dioctl(audiofd, AUDIO_PLAY, NULL)) - ret = cERR_LINUXDVB_ERROR; - } - } - - - return ret; -} - - -int LinuxDvbFlush(Player * context __attribute__ ((unused)), char *) -{ - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (videofd > -1) - dioctl(videofd, VIDEO_FLUSH, NULL); - - if (audiofd > -1) - dioctl(audiofd, AUDIO_FLUSH, NULL); - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - - return cERR_LINUXDVB_NO_ERROR; -} - -#ifndef use_set_speed_instead_ff -int LinuxDvbFastForward(Player * context, char *) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - if (videofd > -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - /* konfetti comment: speed is a value given in skipped frames */ - - if (dioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed)) - ret = cERR_LINUXDVB_ERROR; - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - - - return ret; -} -#else - -static unsigned int SpeedList[] = { 1000, 1100, 1200, 1300, 1500, 2000, 3000, 4000, 5000, 8000, 12000, 16000, 125, 250, 500, 700, 800, 900 }; - -int LinuxDvbFastForward(Player * context, char *type) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - int speedIndex; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); - - - if (video && videofd != -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); - - - if (dioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex])) - ret = cERR_LINUXDVB_ERROR; - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - - if (audio && audiofd != -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - speedIndex = - context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); - - - if (dioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex])) { - ret = cERR_LINUXDVB_ERROR; - } - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - - - return ret; -} -#endif - -int LinuxDvbSlowMotion(Player * context, char *type) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1) { - if (dioctl (videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion)) { - ret = cERR_LINUXDVB_ERROR; - } + close(videofd); + videofd = -1; + } + if (audiofd > -1) { + close(audiofd); + audiofd = -1; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - - return ret; + return true; } -int LinuxDvbAVSync(Player * context, char *type __attribute__ ((unused))) +bool Output::Play() { - int ret = cERR_LINUXDVB_NO_ERROR; - /* konfetti: this one is dedicated to audiofd so we - * are ignoring what is given by type! I think we should - * remove this param. Therefor we should add a variable - * setOn or something like that instead, this would remove - * using a variable inside the structure. - */ - if (audiofd > -1) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool ret = true; - if (dioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync)) - ret = cERR_LINUXDVB_ERROR; + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } + if (videoStream && videofd > -1) { + videoWriter = Writer::GetWriter(videoStream->codec->codec_id, videoStream->codec->codec_type); + if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(videoStream->codec->codec_id)) + || dioctl(videofd, VIDEO_PLAY, NULL)) + ret = false; + } - return ret; + if (audioStream && audiofd > -1) { + audioWriter = Writer::GetWriter(audioStream->codec->codec_id, audioStream->codec->codec_type); + if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(audioStream->codec->codec_id)) + || dioctl(audiofd, AUDIO_PLAY, NULL)) + ret = false; + } + + return ret; } -int LinuxDvbClearAudio() +bool Output::Stop() { - int ret = cERR_LINUXDVB_NO_ERROR; +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool ret = true; - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); + + if (videofd > -1) { + dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); + /* set back to normal speed (end trickmodes) */ + dioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); + if (dioctl(videofd, VIDEO_STOP, NULL)) + ret = false; + } if (audiofd > -1) { - if (dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL)) - ret = cERR_LINUXDVB_ERROR; - } + dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); + /* set back to normal speed (end trickmodes) */ + dioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); + if (dioctl(audiofd, AUDIO_STOP, NULL)) + ret = false; + } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - return ret; + return ret; } -int LinuxDvbClearVideo() +bool Output::Pause() { - int ret = cERR_LINUXDVB_NO_ERROR; +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool ret = true; - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1) { - if (dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL)) - ret = cERR_LINUXDVB_ERROR; + if (dioctl(videofd, VIDEO_FREEZE, NULL)) + ret = false; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (audiofd > -1) { + if (dioctl(audiofd, AUDIO_PAUSE, NULL)) + ret = false; + } - return ret; + return ret; } -int LinuxDvbClear() +bool Output::Continue() { - int ret = LinuxDvbClearAudio(); - if (ret == cERR_LINUXDVB_NO_ERROR) - ret = LinuxDvbClearVideo(); - else - LinuxDvbClearVideo(); - return ret; +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool ret = true; + + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); + + if (videofd > -1) { + if (dioctl(videofd, VIDEO_CONTINUE, NULL)) + ret = false; + } + + if (audiofd > -1) { + if (dioctl(audiofd, AUDIO_CONTINUE, NULL)) + ret = false; + } + + return ret; } -int LinuxDvbPts(Player * context - __attribute__ ((unused)), unsigned long long int *pts) +bool Output::Mute(bool b) { - int ret = cERR_LINUXDVB_ERROR; +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock a_lock(audioMutex); - - // pts is a non writting requests and can be done in parallel to other requests - //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - - if ((videofd > -1 && !dioctl(videofd, VIDEO_GET_PTS, (void *) &sCURRENT_PTS)) - || (audiofd > -1 && !dioctl(audiofd, AUDIO_GET_PTS, (void *) &sCURRENT_PTS))) - ret = cERR_LINUXDVB_NO_ERROR; - else - sCURRENT_PTS = 0; - - *((unsigned long long int *) pts) = (unsigned long long int) sCURRENT_PTS; - - //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - - return ret; -} - -int LinuxDvbGetFrameCount(Player * context - __attribute__ ((unused)), - unsigned long long int *frameCount) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - dvb_play_info_t playInfo; - - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (videofd > -1) { - if (dioctl(videofd, VIDEO_GET_PLAY_INFO, (void *) &playInfo)) - ret = cERR_LINUXDVB_ERROR; - } else if (audiofd > -1) { - if (dioctl(audiofd, AUDIO_GET_PLAY_INFO, (void *) &playInfo)) - ret = cERR_LINUXDVB_ERROR; - } else - ret = cERR_LINUXDVB_ERROR; - - if (ret == cERR_LINUXDVB_NO_ERROR) - *((unsigned long long int *) frameCount) = playInfo.frame_count; - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - return ret; -} - -bool output_switch_audio(AVStream *stream) -{ - if (audiofd < 0) + //AUDIO_SET_MUTE has no effect with new player + if (audiofd > -1 && dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL)) return false; - audioMutex.lock(); + + return true; +} + + +bool Output::Flush() +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool ret = true; + + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); + + if (videofd > -1 && dioctl(videofd, VIDEO_FLUSH, NULL)) + ret = false; + + if (audiofd > -1 && dioctl(audiofd, AUDIO_FLUSH, NULL)) + ret = false; + + return ret; +} + +bool Output::FastForward(int speed) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock v_lock(videoMutex); + + if (videofd > -1 && dioctl(videofd, VIDEO_FAST_FORWARD, speed)) + return false; + + return true; +} + +bool Output::SlowMotion(int speed) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock v_lock(videoMutex); + + if (videofd > -1 && dioctl(videofd, VIDEO_SLOWMOTION, speed)) + return false; + + return true; +} + +bool Output::AVSync(bool b) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock a_lock(audioMutex); + if (audiofd > -1 && dioctl(audiofd, AUDIO_SET_AV_SYNC, b)) + return false; + + return true; +} + +bool Output::ClearAudio() +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock a_lock(audioMutex); + if (audiofd > -1 && dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL)) + return false; + + return true; +} + +bool Output::ClearVideo() +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock v_lock(videoMutex); + if (videofd > -1 && dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL)) + return false; + + return true; +} + +bool Output::Clear() +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + bool aret = ClearAudio(); + bool vret = ClearVideo(); + return aret && vret; +} + +bool Output::GetPts(int64_t &pts) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + pts = 0; + return ((videofd > -1 && !dioctl(videofd, VIDEO_GET_PTS, (void *) &pts)) || + (audiofd > -1 && !dioctl(audiofd, AUDIO_GET_PTS, (void *) &pts))); +} + +bool Output::GetFrameCount(int64_t &framecount) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + dvb_play_info_t playInfo; + + if ((videofd > -1 && dioctl(videofd, VIDEO_GET_PLAY_INFO, (void *) &playInfo)) || + (audiofd > -1 && dioctl(audiofd, AUDIO_GET_PLAY_INFO, (void *) &playInfo))) { + framecount = playInfo.frame_count; + return true; + } + return false; +} + +bool Output::SwitchAudio(AVStream *stream) +{ +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock a_lock(audioMutex); + if (stream == audioStream) + return true; + if (audiofd > -1) { + dioctl(audiofd, AUDIO_STOP, NULL); + dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); + } audioStream = stream; - audioWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); - audio_encoding_t enc = Writer::GetAudioEncoding(stream->codec->codec_id); - dioctl(audiofd, AUDIO_STOP, NULL); - dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); - dioctl (audiofd, AUDIO_SET_ENCODING, (void *) enc); - dioctl(audiofd, AUDIO_PLAY, NULL); - audioMutex.unlock(); + if (stream) { + audioWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); + audioWriter->Init(); + if (audiofd > -1) { + dioctl (audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(stream->codec->codec_id)); + dioctl(audiofd, AUDIO_PLAY, NULL); + } + } return true; } -bool output_switch_video(AVStream *stream) +bool Output::SwitchVideo(AVStream *stream) { - if (videofd < 0) - return false; - videoMutex.lock(); +fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); + OpenThreads::ScopedLock v_lock(videoMutex); + if (stream == videoStream) + return true; + if (videofd > -1) { + dioctl(videofd, VIDEO_STOP, NULL); + dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); + } videoStream = stream; - videoWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); - video_encoding_t enc = Writer::GetVideoEncoding(stream->codec->codec_id); - dioctl(videofd, VIDEO_STOP, NULL); - dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); - dioctl(videofd, VIDEO_SET_ENCODING, (void *) enc); - dioctl(videofd, VIDEO_PLAY, NULL); - videoMutex.unlock(); + if (stream) { + videoWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); + videoWriter->Init(); + if (videofd > -1) { + dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(stream->codec->codec_id)); + dioctl(videofd, VIDEO_PLAY, NULL); + } + } return true; } -static bool Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts) +bool Output::Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts) { +//fprintf(stderr, "%s %d %s\n", __FILE__,__LINE__,__func__); switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - return videoWriter->Write(videofd, avfc, stream, packet, Pts); - case AVMEDIA_TYPE_AUDIO: - return audioWriter->Write(audiofd, avfc, stream, packet, Pts); + case AVMEDIA_TYPE_VIDEO: { + OpenThreads::ScopedLock v_lock(videoMutex); + if (videofd > -1 && videoWriter) + return videoWriter->Write(videofd, avfc, stream, packet, Pts); + return false; + } + case AVMEDIA_TYPE_AUDIO: { + OpenThreads::ScopedLock a_lock(audioMutex); + if (audiofd > -1 && audioWriter) + return audioWriter->Write(audiofd, avfc, stream, packet, Pts); + return false; + } default: return false; } } - -static int reset(Player * context) -{ - if (videoWriter) - videoWriter->Init(); - if (audioWriter) - audioWriter->Init(); - return cERR_LINUXDVB_NO_ERROR; -} - -static int Command(Player *context, OutputCmd_t command, const char *argument) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - - - switch (command) { - case OUTPUT_OPEN:{ - ret = LinuxDvbOpen(context, (char *) argument); - break; - } - case OUTPUT_CLOSE:{ - ret = LinuxDvbClose(context, (char *) argument); - reset(context); - sCURRENT_PTS = 0; - break; - } - case OUTPUT_PLAY:{ // 4 - sCURRENT_PTS = 0; - ret = LinuxDvbPlay(context, (char *) argument); - break; - } - case OUTPUT_STOP:{ - reset(context); - ret = LinuxDvbStop(); - sCURRENT_PTS = 0; - break; - } - case OUTPUT_FLUSH:{ - ret = LinuxDvbFlush(context, (char *) argument); - reset(context); - sCURRENT_PTS = 0; - break; - } - case OUTPUT_PAUSE:{ - ret = LinuxDvbPause(context, (char *) argument); - break; - } - case OUTPUT_CONTINUE:{ - ret = LinuxDvbContinue(context, (char *) argument); - break; - } - case OUTPUT_FASTFORWARD:{ - return LinuxDvbFastForward(context, (char *) argument); - break; - } - case OUTPUT_AVSYNC:{ - ret = LinuxDvbAVSync(context, (char *) argument); - break; - } - case OUTPUT_CLEAR:{ - ret = LinuxDvbClear(); - reset(context); - sCURRENT_PTS = 0; - break; - } - case OUTPUT_PTS:{ - unsigned long long int pts = 0; - ret = LinuxDvbPts(context, &pts); - *((unsigned long long int *) argument) = - (unsigned long long int) pts; - break; - } - case OUTPUT_SLOWMOTION:{ - return LinuxDvbSlowMotion(context, (char *) argument); - break; - } - case OUTPUT_AUDIOMUTE:{ - return LinuxDvbAudioMute(context, (char *) argument); - break; - } - case OUTPUT_DISCONTINUITY_REVERSE:{ - return LinuxDvbReverseDiscontinuity(context, (int *) argument); - break; - } - case OUTPUT_GET_FRAME_COUNT:{ - unsigned long long int frameCount = 0; - ret = LinuxDvbGetFrameCount(context, &frameCount); - *((unsigned long long int *) argument) = - (unsigned long long int) frameCount; - break; - } - default: - ret = cERR_LINUXDVB_ERROR; - break; - } - - - return ret; -} - -static const char *LinuxDvbCapabilities[] = { "audio", "video", NULL }; - -struct Output_s LinuxDvbOutput = { - "LinuxDvb", - &Command, - &Write, - LinuxDvbCapabilities -}; diff --git a/libeplayer3/playback/playback.cpp b/libeplayer3/playback/playback.cpp index 566afac..68f1948 100644 --- a/libeplayer3/playback/playback.cpp +++ b/libeplayer3/playback/playback.cpp @@ -29,7 +29,7 @@ #define PLAYBACK_DEBUG -static short debug_level = 0; +static short debug_level = 20; static const char *FILENAME = "playback.c"; #ifdef PLAYBACK_DEBUG @@ -181,15 +181,12 @@ static int PlaybackPlay(Player * context) if (!context->playback->isPlaying) { context->playback->AVSync = 1; - context->output->Command(context, OUTPUT_AVSYNC, NULL); + context->output.AVSync(true); context->playback->isCreationPhase = 1; // allows the created thread to go into wait mode - ret = context->output->Command(context, OUTPUT_PLAY, NULL); - - if (ret != 0) { - playback_err("OUTPUT_PLAY failed!\n"); - playback_err("clearing isCreationPhase!\n"); + ret = context->output.Play(); + if (!ret) { context->playback->isCreationPhase = 0; // allow thread to go into next state } else { context->playback->isPlaying = 1; @@ -197,7 +194,7 @@ static int PlaybackPlay(Player * context) context->playback->isForwarding = 0; if (context->playback->BackWard) { context->playback->BackWard = 0; - context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); + context->output.Mute(false); } context->playback->SlowMotion = 0; context->playback->Speed = 1; @@ -253,16 +250,16 @@ static int PlaybackPause(Player * context) if (context->playback->isPlaying && !context->playback->isPaused) { if (context->playback->SlowMotion) - context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output.Clear(); - context->output->Command(context, OUTPUT_PAUSE, NULL); + context->output.Pause(); context->playback->isPaused = 1; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; if (context->playback->BackWard) { context->playback->BackWard = 0; - context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); + context->output.Mute(false); } context->playback->SlowMotion = 0; context->playback->Speed = 1; @@ -288,16 +285,16 @@ static int PlaybackContinue(Player * context) || context->playback->SlowMotion)) { if (context->playback->SlowMotion) - context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output.Clear(); - context->output->Command(context, OUTPUT_CONTINUE, NULL); + context->output.Continue(); context->playback->isPaused = 0; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; if (context->playback->BackWard) { context->playback->BackWard = 0; - context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); + context->output.Mute(false); } context->playback->SlowMotion = 0; context->playback->Speed = 1; @@ -325,15 +322,13 @@ static int PlaybackStop(Player * context) context->playback->isForwarding = 0; if (context->playback->BackWard) { context->playback->BackWard = 0; - context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); + context->output.Mute(false); } context->playback->SlowMotion = 0; context->playback->Speed = 0; - context->output->Command(context, OUTPUT_STOP, NULL); - context->container->selectedContainer->Command(context, - CONTAINER_STOP, - NULL); + context->output.Stop(); + context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); } else { playback_err("stop not possible\n"); @@ -369,7 +364,7 @@ static int PlaybackTerminate(Player * context) if (context && context->playback && context->playback->isPlaying) { //First Flush and than delete container, else e2 cant read length of file anymore - if (!context->playback->abortRequested && context->output->Command(context, OUTPUT_FLUSH, NULL) < 0) { + if (!context->playback->abortRequested && !context->output.Flush()) { playback_err("failed to flush output.\n"); } @@ -437,7 +432,7 @@ static int PlaybackFastForward(Player * context, int *speed) playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed); - context->output->Command(context, OUTPUT_FASTFORWARD, NULL); + context->output.FastForward(*speed); } else { playback_err("fast forward not possible\n"); ret = cERR_PLAYBACK_ERROR; @@ -472,24 +467,25 @@ static int PlaybackFastBackward(Player * context, int *speed) context->playback->Speed = *speed; context->playback->BackWard = 1; - playback_printf(1, "S %d B %d\n", context->playback->Speed, - context->playback->BackWard); + playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); } - context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output.Clear(); +#if 0 if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0) { playback_err("OUTPUT_REVERSE failed\n"); context->playback->BackWard = 0; context->playback->Speed = 1; ret = cERR_PLAYBACK_ERROR; } +#endif } else { playback_err("fast backward not possible\n"); ret = cERR_PLAYBACK_ERROR; } if (context->playback->BackWard) - context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); + context->output.Mute(true); playback_printf(10, "exiting with value %d\n", ret); return ret; @@ -522,7 +518,7 @@ static int PlaybackSlowMotion(Player * context, int *speed) playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion); - context->output->Command(context, OUTPUT_SLOWMOTION, NULL); + context->output.SlowMotion(*speed); } else { playback_err("slowmotion not possible\n"); ret = cERR_PLAYBACK_ERROR; @@ -539,7 +535,7 @@ static int PlaybackSeek(Player * context, float *pos, int absolute) playback_printf(10, "pos: %f\n", *pos); - context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output.Clear(); if (absolute) context->container->selectedContainer->Command(context, CONTAINER_SEEK_ABS, (const char *)pos); @@ -551,16 +547,16 @@ static int PlaybackSeek(Player * context, float *pos, int absolute) return ret; } -static int PlaybackPts(Player * context, unsigned long long int *pts) +static int PlaybackPts(Player * context, int64_t &pts) { int ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "\n"); - *pts = 0; + pts = 0; if (context->playback->isPlaying) { - ret = context->output->Command(context, OUTPUT_PTS, (const char *)pts); + ret = !context->output.GetPts(pts); } else { playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; @@ -571,19 +567,16 @@ static int PlaybackPts(Player * context, unsigned long long int *pts) return ret; } -static int PlaybackGetFrameCount(Player * context, - unsigned long long int *frameCount) +static int PlaybackGetFrameCount(Player * context, int64_t &frameCount) { int ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "\n"); - *frameCount = 0; + frameCount = 0; if (context->playback->isPlaying) { - ret = - context->output->Command(context, OUTPUT_GET_FRAME_COUNT, - (const char *)frameCount); + ret = !context->output.GetFrameCount(frameCount); } else { playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; @@ -639,13 +632,10 @@ static int PlaybackSwitchAudio(Player * context, int *track) if (context->container && context->container->selectedContainer) context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, (const char *)&nextrackid); - //FIXME Track_t *t=NULL; context->manager->audio->Command(context, MANAGER_GET_TRACK, &t); -extern bool output_switch_audio(AVStream*); if(t) - output_switch_audio(t->stream); - //FIXME + context->output.SwitchAudio(t->stream); //PlaybackContinue(context); } @@ -773,8 +763,7 @@ static int Command(Player *context, PlaybackCmd_t command, void *argument) break; } case PLAYBACK_PTS:{ // 10 - ret = - PlaybackPts(context, (unsigned long long int *) argument); + ret = PlaybackPts(context, *((int64_t *) argument)); break; } case PLAYBACK_LENGTH:{ // 11 @@ -803,9 +792,7 @@ static int Command(Player *context, PlaybackCmd_t command, void *argument) } case PLAYBACK_GET_FRAME_COUNT:{ // 10 - ret = - PlaybackGetFrameCount(context, - (unsigned long long int *) argument); + ret = PlaybackGetFrameCount(context, *((int64_t *) argument)); break; } case PLAYBACK_SWITCH_TELETEXT:{ diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index 698e597..ce55aad 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -1,11 +1,8 @@ #include "player.h" #include -extern Output_t LinuxDvbOutput; - Player::Player() { - output = &LinuxDvbOutput; } Player::~Player() diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index 55f3845..6c309a8 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -8,7 +8,6 @@ #include #include -extern OutputHandler_t OutputHandler; extern PlaybackHandler_t PlaybackHandler; extern ContainerHandler_t ContainerHandler; extern ManagerHandler_t ManagerHandler; @@ -55,17 +54,8 @@ bool cPlayback::Open(playmode_t PlayMode) if(player) { player->playback = &PlaybackHandler; - player->output = &OutputHandler; player->container = &ContainerHandler; player->manager = &ManagerHandler; - - fprintf(stderr, "player output name: %s\n", player->output->Name); - } - - //Registration of output devices - if(player && player->output) { - player->output->Command(player,OUTPUT_ADD, "audio"); - player->output->Command(player,OUTPUT_ADD, "video"); } return 0; @@ -180,8 +170,8 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un } } - if (pm != PLAYMODE_TS && player && player->output && player->playback) { - player->output->Command(player, OUTPUT_OPEN, NULL); + if (pm != PLAYMODE_TS && player && player->playback) { + player->output.Open(); SetAPid(apid, 0); if ( player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0 ) // playback.c uses "int = 0" for "true" @@ -223,7 +213,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un struct stat s; if (!stat(filename, &s)) last_size = s.st_size; - if (player && player->output && player->playback) + if (player && player->playback) { ret = true; videoDecoder->Stop(false); @@ -242,13 +232,8 @@ bool cPlayback::Stop(void) if(player && player->playback) player->playback->Command(player, PLAYBACK_STOP, NULL); - if(player && player->output) - player->output->Command(player, OUTPUT_CLOSE, NULL); - - if(player && player->output) { - player->output->Command(player,OUTPUT_DEL, "audio"); - player->output->Command(player,OUTPUT_DEL, "video"); - } + if(player) + player->output.Close(); if(player && player->playback) player->playback->Command(player,PLAYBACK_CLOSE, NULL); @@ -307,8 +292,8 @@ bool cPlayback::SetSpeed(int speed) videoDecoder->closeDevice(); decoders_closed = true; usleep(500000); - if (player && player->output && player->playback) { - player->output->Command(player, OUTPUT_OPEN, NULL); + if (player && player->playback) { + player->output.Open(); if (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0) // playback.c uses "int = 0" for "true" playing = true; }