diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index cc18b74..a1734ac 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -9,9 +9,7 @@ AM_CPPFLAGS += -ggdb libeplayer3_la_SOURCES = \ container/container.cpp container/container_ffmpeg.cpp \ - manager/audio.cpp manager/manager.cpp manager/subtitle.cpp manager/video.cpp \ - manager/teletext.cpp manager/chapter.cpp \ - output/linuxdvb.cpp player.cpp \ + manager/manager.cpp output/output.cpp player.cpp \ playback/playback.cpp output/writer/writer.cpp output/writer/wmv.cpp \ output/writer/ac3.cpp output/writer/divx.cpp output/writer/pes.cpp \ output/writer/dts.cpp output/writer/mpeg2.cpp output/writer/mp3.cpp output/writer/misc.cpp \ diff --git a/libeplayer3/container/container_ffmpeg.cpp b/libeplayer3/container/container_ffmpeg.cpp index 0ee772c..c0b1995 100644 --- a/libeplayer3/container/container_ffmpeg.cpp +++ b/libeplayer3/container/container_ffmpeg.cpp @@ -91,6 +91,11 @@ static const char *FILENAME = "container_ffmpeg.c"; /* ***************************** */ +static Track *videoTrack = NULL; +static Track *audioTrack = NULL; +static Track *subtitleTrack = NULL; +static Track *teletextTrack = NULL; + static pthread_t PlayThread; static int hasPlayThreadStarted = 0; static AVFormatContext *avContext = NULL; @@ -249,59 +254,49 @@ static void *FFMPEGThread(void *arg) break; // while } long long int pts; - Track_t *videoTrack = NULL; - Track_t *audioTrack = NULL; - Track_t *subtitleTrack = NULL; - Track_t *teletextTrack = NULL; context->playback->readCount += packet.size; int pid = avContext->streams[packet.stream_index]->id; - if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) - ffmpeg_err("error getting video track\n"); - - if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0) - ffmpeg_err("error getting audio track\n"); - - if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0) - ffmpeg_err("error getting subtitle track\n"); - - if (context->manager->teletext->Command(context, MANAGER_GET_TRACK, &teletextTrack) < 0) - ffmpeg_err("error getting teletext track\n"); - ffmpeg_printf(200, "packet_size %d - index %d\n", packet.size, pid); - if (videoTrack && (videoTrack->pid == pid)) { - currentVideoPts = pts = calcPts(avContext, videoTrack->stream, packet.pts); +Track *_videoTrack = videoTrack; +Track *_audioTrack = audioTrack; +Track *_subtitleTrack = subtitleTrack; +Track *_teletextTrack = teletextTrack; + + + 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)) + if (!context->output.Write(avContext, _videoTrack->stream, &packet, currentVideoPts)) ;//ffmpeg_err("writing data to video device failed\n"); - } else if (audioTrack && (audioTrack->pid == pid)) { + } 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)) + 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"); } - } else if (subtitleTrack && (subtitleTrack->pid == pid)) { + } else if (_subtitleTrack && (_subtitleTrack->pid == pid)) { float duration = 3.0; - ffmpeg_printf(100, "subtitleTrack->stream %p \n", subtitleTrack->stream); + ffmpeg_printf(100, "subtitleTrack->stream %p \n", _subtitleTrack->stream); - pts = calcPts(avContext, subtitleTrack->stream, packet.pts); + pts = calcPts(avContext, _subtitleTrack->stream, packet.pts); if (duration > 0.0) { /* is there a decoder ? */ - if (((AVStream *) subtitleTrack->stream)->codec->codec) { + if (((AVStream *) _subtitleTrack->stream)->codec->codec) { AVSubtitle sub; memset(&sub, 0, sizeof(sub)); int got_sub_ptr; - if (avcodec_decode_subtitle2(((AVStream *) subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) { + if (avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) { ffmpeg_err("error decoding subtitle\n"); } @@ -309,7 +304,7 @@ static void *FFMPEGThread(void *arg) switch (sub.rects[0]->type) { case SUBTITLE_TEXT: // FIXME? case SUBTITLE_ASS: - dvbsub_ass_write(((AVStream *) subtitleTrack->stream)->codec, &sub, pid); + dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid); break; case SUBTITLE_BITMAP: ffmpeg_printf(0, "bitmap\n"); @@ -322,7 +317,7 @@ static void *FFMPEGThread(void *arg) } } } /* duration */ - } else if (teletextTrack && (teletextTrack->pid == pid)) { + } else if (_teletextTrack && (_teletextTrack->pid == pid)) { teletext_write(pid, packet.data, packet.size); } @@ -409,11 +404,11 @@ static void container_ffmpeg_read_subtitle(Player * context, const char *filenam avformat_close_input(&avfc); avformat_free_context(avfc); - Track_t track; + Track track; track.Name = format; track.is_static = 1; track.pid = pid; - context->manager->subtitle->Command(context, MANAGER_ADD, &track); + context->manager.addSubtitleTrack(track); } static void container_ffmpeg_read_subtitles(Player * context, const char *filename) { @@ -461,6 +456,10 @@ int container_ffmpeg_init(Player * context, const char *filename) context->playback->abortRequested = 0; context->playback->abortPlayback = 0; + videoTrack = NULL; + audioTrack = NULL; + subtitleTrack = NULL; + teletextTrack = NULL; avContext = avformat_alloc_context(); avContext->interrupt_callback.callback = interrupt_cb; avContext->interrupt_callback.opaque = context->playback; @@ -502,36 +501,19 @@ int container_ffmpeg_init(Player * context, const char *filename) terminating = 0; int res = container_ffmpeg_update_tracks(context, filename); -AVStream *audioStream = NULL; -AVStream *videoStream = NULL; - - unsigned int n, found_av = 0; - for (n = 0; n < avContext->nb_streams; n++) { - AVStream *stream = avContext->streams[n]; - switch (stream->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (!audioStream) - audioStream = stream; - found_av = 1; - break; - case AVMEDIA_TYPE_VIDEO: - if (!videoStream) - videoStream = stream; - found_av = 1; - break; - default: - break; - } - } - context->output.SwitchAudio(audioStream); - context->output.SwitchVideo(videoStream); - if (!found_av) { + if (!videoTrack && !audioTrack) { avformat_close_input(&avContext); isContainerRunning = 0; return cERR_CONTAINER_FFMPEG_STREAM; } + if (videoTrack) + context->output.SwitchVideo(videoTrack->stream); + if (audioTrack) + context->output.SwitchAudio(audioTrack->stream); + container_ffmpeg_read_subtitles(context, filename); + return res; } @@ -540,11 +522,12 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) if (terminating) return cERR_CONTAINER_FFMPEG_NO_ERROR; +#if 0 // FIXME if (context->manager->chapter) { unsigned int i; context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); for (i = 0; i < avContext->nb_chapters; i++) { - Track_t track; + Track track; track.pid = i; AVDictionaryEntry *title; AVChapter *ch = avContext->chapters[i]; @@ -556,15 +539,9 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) context->manager->chapter->Command(context, MANAGER_ADD, &track); } } +#endif - if (context->manager->video) - context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); - if (context->manager->audio) - context->manager->audio->Command(context, MANAGER_INIT_UPDATE, NULL); - if (context->manager->subtitle) - context->manager->subtitle->Command(context, MANAGER_INIT_UPDATE, NULL); - if (context->manager->teletext) - context->manager->teletext->Command(context, MANAGER_INIT_UPDATE, NULL); + context->manager.initTrackUpdate(); ffmpeg_printf(20, "dump format\n"); av_dump_format(avContext, 0, filename, 0); @@ -574,7 +551,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) unsigned int n; for (n = 0; n < avContext->nb_streams; n++) { - Track_t track; + Track track; AVStream *stream = avContext->streams[n]; if (!stream->id) @@ -598,12 +575,9 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; } - if (context->manager->video) - if (context->manager->video->Command(context, MANAGER_ADD, &track) < 0) { - /* konfetti: fixme: is this a reason to return with error? */ - ffmpeg_err("failed to add track %d\n", n); - } - + context->manager.addVideoTrack(track); + if (!videoTrack) + videoTrack = context->manager.getVideoTrack(track.pid); break; case AVMEDIA_TYPE_AUDIO: ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", stream->codec->codec_type); @@ -648,12 +622,9 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) default: track.ac3flags = 0; } - if (context->manager->audio) { - if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0) { - /* konfetti: fixme: is this a reason to return with error? */ - ffmpeg_err("failed to add track %d\n", n); - } - } + context->manager.addAudioTrack(track); + if (!audioTrack) + audioTrack = context->manager.getAudioTrack(track.pid); break; case AVMEDIA_TYPE_SUBTITLE: @@ -683,7 +654,7 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name.c_str()); - if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && context->manager->teletext) { + if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) { ffmpeg_printf(10, "dvb_teletext\n"); int i = 0; AVDictionaryEntry *t = NULL; @@ -692,13 +663,15 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) snprintf(tmp, sizeof(tmp), "teletext_%d", i); t = av_dict_get(stream->metadata, tmp, NULL, 0); if (t) { - track.Name = t->value; - if (context->manager->teletext->Command(context, MANAGER_ADD, &track) < 0) - ffmpeg_err("failed to add teletext track %d\n", n); + char lang[strlen(t->value)]; + if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) { + track.Name = lang; + context->manager.addTeletextTrack(track); + } } i++; } while (t); - } else if (context->manager->subtitle) { + } else { if (!stream->codec->codec) { stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id); if (!stream->codec->codec) @@ -708,18 +681,12 @@ int container_ffmpeg_update_tracks(Player * context, const char *filename) stream->codec->codec = NULL; } } - if (stream->codec->codec && context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0) { - /* konfetti: fixme: is this a reason to return with error? */ - ffmpeg_err("failed to add subtitle track %d\n", n); - } - } + if (stream->codec->codec) + context->manager.addSubtitleTrack(track); + } break; } - case AVMEDIA_TYPE_UNKNOWN: - case AVMEDIA_TYPE_DATA: - case AVMEDIA_TYPE_ATTACHMENT: - case AVMEDIA_TYPE_NB: default: ffmpeg_err("not handled or unknown codec_type %d\n", stream->codec->codec_type); break; @@ -804,36 +771,23 @@ static int container_ffmpeg_seek(Player * context __attribute__ ((unused)), floa static int container_ffmpeg_get_length(Player * context, double *length) { ffmpeg_printf(50, "\n"); - Track_t *videoTrack = NULL; - Track_t *audioTrack = NULL; - Track_t *subtitleTrack = NULL; - Track_t *current = NULL; + Track *current = NULL; - if (length == NULL) { - ffmpeg_err("null pointer passed\n"); - return cERR_CONTAINER_FFMPEG_ERR; - } - - context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); - context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); - context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack); - - if (videoTrack != NULL) + if (videoTrack) current = videoTrack; - else if (audioTrack != NULL) + else if (audioTrack) current = audioTrack; - else if (subtitleTrack != NULL) + else if (subtitleTrack) current = subtitleTrack; *length = 0.0; - if (current != NULL) { + if (current) { if (current->duration == 0) return cERR_CONTAINER_FFMPEG_ERR; - else - *length = (current->duration / 1000.0); + *length = (current->duration / 1000.0); } else { - if (avContext != NULL) { + if (avContext) { *length = (avContext->duration / 1000.0); } else { ffmpeg_err("no Track not context ->no problem :D\n"); @@ -844,35 +798,37 @@ static int container_ffmpeg_get_length(Player * context, double *length) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int container_ffmpeg_switch_audio(Player * context, int *arg) +static int container_ffmpeg_switch_audio(Player * context, Track *track) { - Track_t *audioTrack = NULL; - context->manager->audio->Command(context, MANAGER_GET_TRACK, &arg); - if (audioTrack) { - context->output.SwitchAudio(audioTrack->stream); - ffmpeg_printf(10, "track %d\n", *arg); - /* Hellmaster1024: nothing to do here! */ - float sec = -5.0; - context->playback->Command(context, PLAYBACK_SEEK, (void *) &sec); - } + audioTrack = track; + context->output.SwitchAudio(track ? track->stream : NULL); + float sec = -5.0; + context->playback->Command(context, PLAYBACK_SEEK, (void *) &sec); return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int container_ffmpeg_switch_subtitle(Player * context __attribute__ ((unused)), int *arg __attribute__ ((unused))) +static int container_ffmpeg_switch_subtitle(Player * context, Track *track) { - /* Hellmaster1024: nothing to do here! */ + subtitleTrack = track; return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int container_ffmpeg_switch_teletext(Player * context __attribute__ ((unused)), int *arg __attribute__ ((unused))) +static int container_ffmpeg_switch_teletext(Player * context, Track *track) { + teletextTrack = track; + return cERR_CONTAINER_FFMPEG_NO_ERROR; +} + +static int container_ffmpeg_switch_video(Player * context, Track *track) +{ + videoTrack = track; return cERR_CONTAINER_FFMPEG_NO_ERROR; } static int container_ffmpeg_get_metadata(Player * context, char ***p) { - Track_t *videoTrack = NULL; - Track_t *audioTrack = NULL; + Track *videoTrack = NULL; + Track *audioTrack = NULL; AVDictionaryEntry *tag = NULL; size_t psize = 1; char **pp; @@ -887,9 +843,6 @@ static int container_ffmpeg_get_metadata(Player * context, char ***p) return cERR_CONTAINER_FFMPEG_ERR; } - context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); - context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); - if (avContext->metadata) psize += av_dict_count(avContext->metadata); if (videoTrack) @@ -969,11 +922,11 @@ static int Command(Player *context, ContainerCmd_t command, const char *argument break; } case CONTAINER_SWITCH_AUDIO:{ - ret = container_ffmpeg_switch_audio(context, (int *) argument); + ret = container_ffmpeg_switch_audio(context, (Track *) argument); break; } case CONTAINER_SWITCH_SUBTITLE:{ - ret = container_ffmpeg_switch_subtitle(context, (int *) argument); + ret = container_ffmpeg_switch_subtitle(context, (Track *) argument); break; } case CONTAINER_METADATA:{ @@ -981,7 +934,7 @@ static int Command(Player *context, ContainerCmd_t command, const char *argument break; } case CONTAINER_SWITCH_TELETEXT:{ - ret = container_ffmpeg_switch_teletext(context, (int *) argument); + ret = container_ffmpeg_switch_teletext(context, (Track *) argument); break; } default: diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index 3cb8ed2..311e8cb 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -4,6 +4,12 @@ #include #include #include +#include +#include + +#include +#include +#include extern "C" { #include @@ -24,57 +30,52 @@ typedef enum { MANAGER_INIT_UPDATE } ManagerCmd_t; -typedef enum { - eTypeES, - eTypePES -} eTrackTypeEplayer; +struct Track +{ + std::string Name; + int pid; -typedef struct Track_s { - std::string Name; - int pid; + /* length of track */ + int64_t duration; - /* new field for ffmpeg - add at the end so no problem - * can occur with not changed srt saa container - */ - char *language; + /* context from ffmpeg */ + AVFormatContext *avfc; + /* stream from ffmpeg */ + AVStream *stream; - /* length of track */ - int64_t duration; + bool inactive; + bool is_static; - /* context from ffmpeg */ - AVFormatContext *avfc; - /* stream from ffmpeg */ - AVStream *stream; + int ac3flags; + int type, mag, page; // for teletext - int pending; - int is_static; - long long int chapter_start; - long long int chapter_end; + Track() : pid(-1), duration(-1), avfc(NULL), stream(NULL), inactive(0), is_static(0), ac3flags(-1) {} +}; - int ac3flags; +class Manager +{ + private: + OpenThreads::Mutex mutex; + std::map videoTracks, audioTracks, subtitleTracks, teletextTracks; + public: + void addVideoTrack(Track &track); + void addAudioTrack(Track &track); + void addSubtitleTrack(Track &track); + void addTeletextTrack(Track &track); - 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; + std::vector getVideoTracks(); + std::vector getAudioTracks(); + std::vector getSubtitleTracks(); + std::vector getTeletextTracks(); -struct Player; + Track *getVideoTrack(int pid); + Track *getAudioTrack(int pid); + Track *getSubtitleTrack(int pid); + Track *getTeletextTrack(int pid); -typedef struct Manager_s { - const char *Name; - int (*Command) (Player *, ManagerCmd_t, void *); - const char **Capabilities; - -} Manager_t; - -typedef struct ManagerHandler_s { - const char *Name; - Manager_t *audio; - Manager_t *video; - Manager_t *subtitle; - Manager_t *teletext; - Manager_t *chapter; -} ManagerHandler_t; - -void freeTrack(Track_t * track); -void copyTrack(Track_t * to, Track_t * from); + bool initTrackUpdate(); + void clearTracks(); + ~Manager(); +}; #endif diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index ff1fccd..54e3938 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -12,13 +12,13 @@ class Player { public: //FIXME PlaybackHandler_t *playback; ContainerHandler_t *container; - ManagerHandler_t *manager; int64_t *currentAudioPtsP; public: Player(); ~Player(); Output output; + Manager manager; }; int container_ffmpeg_update_tracks(Player * context, const char *filename); diff --git a/libeplayer3/manager/audio.cpp b/libeplayer3/manager/audio.cpp deleted file mode 100644 index 1f46005..0000000 --- a/libeplayer3/manager/audio.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * audio manager handling. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include -#include -#include - -#include "manager.h" -#include "player.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define AUDIO_MGR_DEBUG - -#ifdef AUDIO_MGR_DEBUG - -static short debug_level = 0; - -#define audio_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define audio_mgr_printf(level, x...) -#endif - -#ifndef AUDIO_MGR_SILENT -#define audio_mgr_err(x...) do { printf(x); } while (0) -#else -#define audio_mgr_err(x...) -#endif - -/* Error Constants */ -#define cERR_AUDIO_MGR_NO_ERROR 0 -#define cERR_AUDIO_MGR_ERROR -1 - -static const char FILENAME[] = __FILE__; - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static std::map Tracks; -static int CurrentPid = -1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -static int ManagerAdd(Player * context, Track_t track) -{ - Tracks[track.pid] = track; - context->playback->isAudio = 1; - - if (CurrentPid < 0) - CurrentPid = track.pid; - - return cERR_AUDIO_MGR_NO_ERROR; -} - -static char **ManagerList(Player * context __attribute__ ((unused))) -{ - int j = 0; - char **tracklist = (char **) malloc(sizeof(char *) * ((Tracks.size() * 2) + 1)); - - for(std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - { - size_t len = it->second.Name.length() + 20; - char tmp[len]; - 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); - j += 2; - } - tracklist[j] = NULL; - - return tracklist; -} - -static int ManagerDel(Player * context) -{ - Tracks.clear(); - CurrentPid = -1; - context->playback->isAudio = 0; - return cERR_AUDIO_MGR_NO_ERROR; -} - - -static int Command(Player *context, ManagerCmd_t command, void *argument) -{ - int ret = cERR_AUDIO_MGR_NO_ERROR; - - audio_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); - - switch (command) { - case MANAGER_ADD:{ - Track_t *track = (Track_t *) argument; - ret = ManagerAdd(context, *track); - break; - } - case MANAGER_LIST:{ - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - *((char ***) argument) = (char **) ManagerList(context); - break; - } - case MANAGER_GET:{ - *((int *) argument) = (int) CurrentPid; - break; - } - case MANAGER_GET_TRACK:{ - if (CurrentPid > -1) - *((Track_t **) argument) = &Tracks[CurrentPid]; - else - *((Track_t **) argument) = NULL; - break; - } - case MANAGER_GETNAME:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); - else - *((char **) argument) = strdup(""); - break; - } - case MANAGER_SET:{ - std::map::iterator it = Tracks.find(*((int *) argument)); - if (it != Tracks.end()) - CurrentPid = *((int *) argument); - else - ret = cERR_AUDIO_MGR_ERROR; - break; - } - case MANAGER_DEL:{ - ret = ManagerDel(context); - break; - } - case MANAGER_INIT_UPDATE:{ - for (std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - it->second.pending = 1; - break; - } - default: - audio_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command); - ret = cERR_AUDIO_MGR_ERROR; - break; - } - - audio_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, ret); - - return ret; -} - - -struct Manager_s AudioManager = { - "Audio", - &Command, - NULL -}; diff --git a/libeplayer3/manager/chapter.cpp b/libeplayer3/manager/chapter.cpp deleted file mode 100644 index 66369d2..0000000 --- a/libeplayer3/manager/chapter.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * chapter manager handling. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include -#include -#include - -#include "manager.h" -#include "player.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define CHAPTER_MGR_DEBUG - -#ifdef CHAPTER_MGR_DEBUG - -static short debug_level = 0; - -#define chapter_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define chapter_mgr_printf(level, x...) -#endif - -#ifndef CHAPTER_MGR_SILENT -#define chapter_mgr_err(x...) do { printf(x); } while (0) -#else -#define chapter_mgr_err(x...) -#endif - -/* Error Constants */ -#define cERR_CHAPTER_MGR_NO_ERROR 0 -#define cERR_CHAPTER_MGR_ERROR -1 - -static const char FILENAME[] = __FILE__; - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static std::map Tracks; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) -{ - Tracks[track.pid] = track; - - return cERR_CHAPTER_MGR_NO_ERROR; -} - -static char **ManagerList(Player * context __attribute__ ((unused))) -{ - int j = 0; - char **tracklist = (char **) malloc(sizeof(char *) * ((Tracks.size() * 2) + 1)); - - for(std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - { - size_t len = it->second.Name.length() + 20; - char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); - tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(""); - j += 2; - } - tracklist[j] = NULL; - - return tracklist; -} - -static int ManagerDel(Player * context __attribute__((unused))) -{ - Tracks.clear(); - return cERR_CHAPTER_MGR_NO_ERROR; -} - -static int Command(Player *context, ManagerCmd_t command, void *argument) -{ - int ret = cERR_CHAPTER_MGR_NO_ERROR; - - chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); - - switch (command) { - case MANAGER_ADD:{ - Track_t *track = (Track_t *) argument; - ret = ManagerAdd(context, *track); - break; - } - case MANAGER_LIST:{ - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - *((char ***) argument) = (char **) ManagerList(context); - break; - } - case MANAGER_DEL:{ - ret = ManagerDel(context); - break; - } - case MANAGER_INIT_UPDATE:{ - for (std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - it->second.pending = 1; - break; - } - default: - chapter_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command); - ret = cERR_CHAPTER_MGR_ERROR; - break; - } - - chapter_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, - ret); - - return ret; -} - - -struct Manager_s ChapterManager = { - "Chapter", - &Command, - NULL -}; diff --git a/libeplayer3/manager/manager.cpp b/libeplayer3/manager/manager.cpp index a1088cf..00ac330 100644 --- a/libeplayer3/manager/manager.cpp +++ b/libeplayer3/manager/manager.cpp @@ -25,52 +25,159 @@ #include #include "manager.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -extern Manager_t AudioManager; -extern Manager_t VideoManager; -extern Manager_t SubtitleManager; -extern Manager_t TeletextManager; -extern Manager_t ChapterManager; - -ManagerHandler_t ManagerHandler = { - "ManagerHandler", - &AudioManager, - &VideoManager, - &SubtitleManager, - &TeletextManager, - &ChapterManager -}; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ -void copyTrack(Track_t * to, Track_t * from) +void Manager::addVideoTrack(Track &track) { - *to = *from; - - if (from->language != NULL) - to->language = strdup(from->language); - else - to->language = strdup("Unknown"); + OpenThreads::ScopedLock m_lock(mutex); + Track *t = new Track; + *t = track; + videoTracks[track.pid] = t; } -void freeTrack(Track_t * track) +void Manager::addAudioTrack(Track &track) { - if (track->language != NULL) - free(track->language); + OpenThreads::ScopedLock m_lock(mutex); + Track *t = new Track; + *t = track; + audioTracks[track.pid] = t; +} + +void Manager::addSubtitleTrack(Track &track) +{ + OpenThreads::ScopedLock m_lock(mutex); + Track *t = new Track; + *t = track; + subtitleTracks[track.pid] = t; +} + +void Manager::addTeletextTrack(Track &track) +{ + OpenThreads::ScopedLock m_lock(mutex); + Track *t = new Track; + *t = track; + teletextTracks[track.pid] = t; +} + +std::vector Manager::getVideoTracks() +{ +// input.UpdateTracks(); + std::vector res; + OpenThreads::ScopedLock m_lock(mutex); + for(std::map::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it) + if (!it->second->inactive) + res.push_back(*it->second); + return res; +} + +std::vector Manager::getAudioTracks() +{ +// input.UpdateTracks(); + std::vector res; + OpenThreads::ScopedLock m_lock(mutex); + for(std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) + if (!it->second->inactive) + res.push_back(*it->second); + return res; +} + +std::vector Manager::getSubtitleTracks() +{ +// input.UpdateTracks(); + std::vector res; + OpenThreads::ScopedLock m_lock(mutex); + for(std::map::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it) + if (!it->second->inactive) + res.push_back(*it->second); + return res; +} + +std::vector Manager::getTeletextTracks() +{ +// input.UpdateTracks(); + std::vector res; + OpenThreads::ScopedLock m_lock(mutex); + for(std::map::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it) + if (!it->second->inactive) + res.push_back(*it->second); + return res; +} + +Track *Manager::getVideoTrack(int pid) +{ + OpenThreads::ScopedLock m_lock(mutex); + std::map::iterator it = videoTracks.find(pid); + if (it != videoTracks.end() && !it->second->inactive) + return it->second; + return NULL; +} + +Track *Manager::getAudioTrack(int pid) +{ + OpenThreads::ScopedLock m_lock(mutex); + std::map::iterator it = audioTracks.find(pid); + if (it != audioTracks.end() && !it->second->inactive) + return it->second; + return NULL; +} + +Track *Manager::getSubtitleTrack(int pid) +{ + OpenThreads::ScopedLock m_lock(mutex); + std::map::iterator it = subtitleTracks.find(pid); + if (it != subtitleTracks.end() && !it->second->inactive) + return it->second; + return NULL; +} + +Track *Manager::getTeletextTrack(int pid) +{ + OpenThreads::ScopedLock m_lock(mutex); + std::map::iterator it = teletextTracks.find(pid); + if (it != teletextTracks.end() && !it->second->inactive) + return it->second; + return NULL; +} + +bool Manager::initTrackUpdate() +{ + OpenThreads::ScopedLock m_lock(mutex); + + for (std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) + it->second->inactive = !it->second->is_static; + + for (std::map::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it) + it->second->inactive = !it->second->is_static; + + for (std::map::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it) + it->second->inactive = !it->second->is_static; + + for (std::map::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it) + it->second->inactive = !it->second->is_static; + + return true; +} + +void Manager::clearTracks() +{ + OpenThreads::ScopedLock m_lock(mutex); + + for (std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) + delete it->second; + audioTracks.clear(); + + for (std::map::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it) + delete it->second; + videoTracks.clear(); + + for (std::map::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it) + delete it->second; + subtitleTracks.clear(); + + for (std::map::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it) + delete it->second; + teletextTracks.clear(); +} + +Manager::~Manager() +{ + clearTracks(); } diff --git a/libeplayer3/manager/subtitle.cpp b/libeplayer3/manager/subtitle.cpp deleted file mode 100644 index 8bd5226..0000000 --- a/libeplayer3/manager/subtitle.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * subtitle manager handling. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include -#include -#include - -#include "manager.h" -#include "player.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define SUBTITLE_MGR_DEBUG - -#ifdef SUBTITLE_MGR_DEBUG - -static short debug_level = 10; - -#define subtitle_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define subtitle_mgr_printf(level, x...) -#endif - -#ifndef SUBTITLE_MGR_SILENT -#define subtitle_mgr_err(x...) do { printf(x); } while (0) -#else -#define subtitle_mgr_err(x...) -#endif - -/* Error Constants */ -#define cERR_SUBTITLE_MGR_NO_ERROR 0 -#define cERR_SUBTITLE_MGR_ERROR -1 - -static const char FILENAME[] = __FILE__; - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static std::map Tracks; -static int CurrentPid = -1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) -{ - Tracks[track.pid] = track; - context->playback->isAudio = 1; - - return cERR_SUBTITLE_MGR_NO_ERROR; -} - -static char **ManagerList(Player * context __attribute__ ((unused))) -{ - int j = 0; - char **tracklist = (char **) malloc(sizeof(char *) * ((Tracks.size() * 2) + 1)); - - for(std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - { - size_t len = it->second.Name.length() + 20; - char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); - tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(""); - j += 2; - } - tracklist[j] = NULL; - - return tracklist; -} - -static int ManagerDel(Player * context __attribute__((unused))) -{ - Tracks.clear(); - CurrentPid = -1; - return cERR_SUBTITLE_MGR_NO_ERROR; -} - -static int Command(Player *context, ManagerCmd_t command, void *argument) -{ - int ret = cERR_SUBTITLE_MGR_NO_ERROR; - - subtitle_mgr_printf(50, "%s::%s %d\n", FILENAME, __FUNCTION__, command); - - switch (command) { - case MANAGER_ADD:{ - Track_t *track = (Track_t *) argument; - ret = ManagerAdd(context, *track); - break; - } - case MANAGER_LIST:{ - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - *((char ***) argument) = (char **) ManagerList(context); - break; - } - case MANAGER_GET:{ - *((int *) argument) = (int) CurrentPid; - break; - } - case MANAGER_GET_TRACK:{ - if (CurrentPid > -1) - *((Track_t **) argument) = &Tracks[CurrentPid]; - else - *((Track_t **) argument) = NULL; - break; - } - case MANAGER_GETNAME:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); - else - *((char **) argument) = strdup(""); - break; - } - case MANAGER_SET:{ - std::map::iterator it = Tracks.find(*((int *) argument)); - if (it != Tracks.end()) - CurrentPid = *((int *) argument); - else - ret = cERR_SUBTITLE_MGR_ERROR; - break; - } - case MANAGER_DEL:{ - ret = ManagerDel(context); - break; - } - case MANAGER_INIT_UPDATE:{ - for (std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - it->second.pending = 1; - break; - } - default: - subtitle_mgr_err("%s:%s: ConatinerCmd not supported!", FILENAME, __FUNCTION__); - ret = cERR_SUBTITLE_MGR_ERROR; - break; - } - - subtitle_mgr_printf(50, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, ret); - - return ret; -} - - -struct Manager_s SubtitleManager = { - "Subtitle", - &Command, - NULL -}; diff --git a/libeplayer3/manager/teletext.cpp b/libeplayer3/manager/teletext.cpp deleted file mode 100644 index 24ac281..0000000 --- a/libeplayer3/manager/teletext.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * teletext manager handling. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include -#include -#include - -#include "manager.h" -#include "player.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define TELETEXT_MGR_DEBUG - -#ifdef TELETEXT_MGR_DEBUG - -static short debug_level = 0; - -#define teletext_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define teletext_mgr_printf(level, x...) -#endif - -#ifndef TELETEXT_MGR_SILENT -#define teletext_mgr_err(x...) do { printf(x); } while (0) -#else -#define teletext_mgr_err(x...) -#endif - -/* Error Constants */ -#define cERR_TELETEXT_MGR_NO_ERROR 0 -#define cERR_TELETEXT_MGR_ERROR -1 - -static const char FILENAME[] = __FILE__; - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static std::map Tracks; -static int CurrentPid = -1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -static int ManagerAdd(Player * context __attribute__((unused)), Track_t track) -{ - Tracks[track.pid] = track; - context->playback->isAudio = 1; - - return cERR_TELETEXT_MGR_NO_ERROR; -} - -static char **ManagerList(Player * context __attribute__ ((unused))) -{ - int j = 0; - char **tracklist = (char **) malloc(sizeof(char *) * ((Tracks.size() * 2) + 1)); - - for(std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - { - size_t len = it->second.Name.length() + 20; - char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); - tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(""); - j += 2; - } - tracklist[j] = NULL; - - return tracklist; -} - -static int ManagerDel(Player * context __attribute__((unused))) -{ - Tracks.clear(); - CurrentPid = -1; - return cERR_TELETEXT_MGR_NO_ERROR; -} - - -static int Command(Player *context, ManagerCmd_t command, void *argument) -{ - int ret = cERR_TELETEXT_MGR_NO_ERROR; - - teletext_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); - - switch (command) { - case MANAGER_ADD:{ - Track_t *track = (Track_t *) argument; - ret = ManagerAdd(context, *track); - break; - } - case MANAGER_LIST:{ - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - *((char ***) argument) = (char **) ManagerList(context); - break; - } - case MANAGER_GET:{ - *((int *) argument) = (int) CurrentPid; - break; - } - case MANAGER_GET_TRACK:{ - if (CurrentPid > -1) - *((Track_t **) argument) = &Tracks[CurrentPid]; - else - *((Track_t **) argument) = NULL; - break; - } - case MANAGER_GETNAME:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); - else - *((char **) argument) = strdup(""); - break; - } - case MANAGER_SET:{ - std::map::iterator it = Tracks.find(*((int *) argument)); - if (it != Tracks.end()) - CurrentPid = *((int *) argument); - else - ret = cERR_TELETEXT_MGR_ERROR; - break; - } - case MANAGER_DEL:{ - ret = ManagerDel(context); - break; - } - case MANAGER_INIT_UPDATE:{ - for (std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - it->second.pending = 1; - break; - } - default: - teletext_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command); - ret = cERR_TELETEXT_MGR_ERROR; - break; - } - - teletext_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, ret); - - return ret; -} - - -struct Manager_s TeletextManager = { - "Teletext", - &Command, - NULL -}; diff --git a/libeplayer3/manager/video.cpp b/libeplayer3/manager/video.cpp deleted file mode 100644 index 1bdfcee..0000000 --- a/libeplayer3/manager/video.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * video manager handling. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include -#include -#include - -#include "manager.h" -#include "player.h" - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define VIDEO_MGR_DEBUG - -#ifdef VIDEO_MGR_DEBUG - -static short debug_level = 0; - -#define video_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define video_mgr_printf(level, x...) -#endif - -#ifndef VIDEO_MGR_SILENT -#define video_mgr_err(x...) do { printf(x); } while (0) -#else -#define video_mgr_err(x...) -#endif - -/* Error Constants */ -#define cERR_VIDEO_MGR_NO_ERROR 0 -#define cERR_VIDEO_MGR_ERROR -1 - -static const char FILENAME[] = __FILE__; - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static std::map Tracks; -static int CurrentPid = -1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -static int ManagerAdd(Player * context, Track_t track) -{ - Tracks[track.pid] = track; - context->playback->isVideo = 1; - - if (CurrentPid < 0) - CurrentPid = track.pid; - - return cERR_VIDEO_MGR_NO_ERROR; -} - -static char **ManagerList(Player * context __attribute__ ((unused))) -{ - int j = 0; - char **tracklist = (char **) malloc(sizeof(char *) * ((Tracks.size() * 2) + 1)); - - for(std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - { - size_t len = it->second.Name.length() + 20; - char tmp[len]; - snprintf(tmp, len, "%d %s\n", it->second.pid, it->second.Name.c_str()); - tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(""); - j += 2; - } - tracklist[j] = NULL; - - return tracklist; -} - -static int ManagerDel(Player * context) -{ - Tracks.clear(); - CurrentPid = -1; - context->playback->isAudio = 0; - return cERR_VIDEO_MGR_NO_ERROR; -} - -static int Command(Player *context, ManagerCmd_t command, void *argument) -{ - int ret = cERR_VIDEO_MGR_NO_ERROR; - - video_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); - - switch (command) { - case MANAGER_ADD:{ - Track_t *track = (Track_t *)argument; - ret = ManagerAdd(context, *track); - break; - } - case MANAGER_LIST:{ - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - *((char ***) argument) = (char **) ManagerList(context); - break; - } - case MANAGER_GET:{ - *((int *) argument) = (int) CurrentPid; - break; - } - case MANAGER_GET_TRACK:{ - if (CurrentPid > -1) - *((Track_t **) argument) = &Tracks[CurrentPid]; - else - *((Track_t **) argument) = NULL; - break; - } - case MANAGER_GETNAME:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); - else - *((char **) argument) = strdup(""); - break; - } - case MANAGER_SET:{ - std::map::iterator it = Tracks.find(*((int *) argument)); - if (it != Tracks.end()) - CurrentPid = *((int *) argument); - else - ret = cERR_VIDEO_MGR_ERROR; - break; - } - case MANAGER_DEL:{ - ret = ManagerDel(context); - break; - } - case MANAGER_INIT_UPDATE:{ - for (std::map::iterator it = Tracks.begin(); it != Tracks.end(); ++it) - it->second.pending = 1; - break; - } - default: - video_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, __FUNCTION__, command); - ret = cERR_VIDEO_MGR_ERROR; - break; - } - - video_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, ret); - - return ret; -} - - -struct Manager_s VideoManager = { - "Video", - &Command, - NULL -}; diff --git a/libeplayer3/playback/playback.cpp b/libeplayer3/playback/playback.cpp index 68f1948..da0735a 100644 --- a/libeplayer3/playback/playback.cpp +++ b/libeplayer3/playback/playback.cpp @@ -132,6 +132,7 @@ static int PlaybackOpen(Player * context, char *uri) playback_err("Unknown stream (%s)\n", uri); return cERR_PLAYBACK_ERROR; } + context->manager.clearTracks(); if ((context->container->Command(context, CONTAINER_ADD, NULL) < 0) || (!context->container->selectedContainer) @@ -153,11 +154,6 @@ static int PlaybackClose(Player * context) playback_err("container delete failed\n"); } - context->manager->audio->Command(context, MANAGER_DEL, NULL); - context->manager->video->Command(context, MANAGER_DEL, NULL); - context->manager->subtitle->Command(context, MANAGER_DEL, NULL); - context->manager->teletext->Command(context, MANAGER_DEL, NULL); - context->manager->chapter->Command(context, MANAGER_DEL, NULL); context->playback->isPaused = 0; context->playback->isPlaying = 0; @@ -610,97 +606,28 @@ static int PlaybackLength(Player * context, double *length) return ret; } -static int PlaybackSwitchAudio(Player * context, int *track) +static int PlaybackSwitchAudio(Player * context, int *pid) { - int ret = cERR_PLAYBACK_NO_ERROR; - int curtrackid = 0; - int nextrackid = 0; - - playback_printf(10, "\n"); - - if (context->playback->isPlaying) { - if (context->manager && context->manager->audio) { - context->manager->audio->Command(context, MANAGER_GET, &curtrackid); - context->manager->audio->Command(context, MANAGER_SET, track); - context->manager->audio->Command(context, MANAGER_GET, &nextrackid); - } - - if (nextrackid != curtrackid) { - - //PlaybackPause(context); - - if (context->container && context->container->selectedContainer) - context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, (const char *)&nextrackid); - - Track_t *t=NULL; - context->manager->audio->Command(context, MANAGER_GET_TRACK, &t); - if(t) - context->output.SwitchAudio(t->stream); - - //PlaybackContinue(context); - } - } else { - playback_err("switch audio not possible\n"); - ret = cERR_PLAYBACK_ERROR; - } - - playback_printf(10, "exiting with value %d\n", ret); - - return ret; + Track *track = context->manager.getAudioTrack(*pid); + if (track) + context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, (const char*) track); + return 0; } -static int PlaybackSwitchSubtitle(Player * context, int *track) +static int PlaybackSwitchSubtitle(Player * context, int *pid) { - int ret = cERR_PLAYBACK_NO_ERROR; - - playback_printf(10, "Track: %d\n", *track); - - if (context && context->playback && context->playback->isPlaying) { - if (context->manager && context->manager->subtitle) { - int trackid; - - if (context->manager-> - subtitle->Command(context, MANAGER_SET, track) < 0) { - playback_err("manager set track failed\n"); - } - - context->manager->subtitle->Command(context, MANAGER_GET, &trackid); - } else { - ret = cERR_PLAYBACK_ERROR; - playback_err("no subtitle\n"); - } - } else { - playback_err("not possible\n"); - ret = cERR_PLAYBACK_ERROR; - } - - playback_printf(10, "exiting with value %d\n", ret); - - return ret; + Track *track = context->manager.getSubtitleTrack(*pid); + if (track) + context->container->selectedContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, (const char*) track); + return 0; } static int PlaybackSwitchTeletext(Player * context, int *pid) { - int ret = cERR_PLAYBACK_NO_ERROR; - - playback_printf(10, "Track: %d\n", *pid); - - if (context && context->manager && context->manager->teletext) { - if (context->manager-> - teletext->Command(context, - *pid < 0 ? MANAGER_DEL : MANAGER_SET, pid)) { - playback_err("ttxsub manager set track failed\n"); - ret = cERR_PLAYBACK_ERROR; - } - } else - playback_err("no ttxsubtitle\n"); - - if (*pid < 0) - container_ffmpeg_update_tracks(context, context->playback->uri.c_str()); - - playback_printf(10, "exiting with value %d\n", ret); - - return ret; + Track *track = context->manager.getTeletextTrack(*pid); + if (track) + context->container->selectedContainer->Command(context, CONTAINER_SWITCH_TELETEXT, (const char*) track); + return 0; } static int PlaybackMetadata(Player * context, char ***metadata) diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index 6c309a8..f9598da 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -10,7 +10,6 @@ #include extern PlaybackHandler_t PlaybackHandler; extern ContainerHandler_t ContainerHandler; -extern ManagerHandler_t ManagerHandler; #include "playback_libeplayer3.h" @@ -55,7 +54,6 @@ bool cPlayback::Open(playmode_t PlayMode) if(player) { player->playback = &PlaybackHandler; player->container = &ContainerHandler; - player->manager = &ManagerHandler; } return 0; @@ -107,69 +105,6 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un //try to open file if(player && player->playback && player->playback->Command(player, PLAYBACK_OPEN, file) >= 0) { - //AUDIO - if(player && player->manager && player->manager->audio) { - char ** TrackList = NULL; - player->manager->audio->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("AudioTrack List\n"); - int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - } - } - - //SUB - if(player && player->manager && player->manager->subtitle) { - char ** TrackList = NULL; - player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("SubtitleTrack List\n"); - int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - } - } - - //Teletext - if(player && player->manager && player->manager->teletext) { - char ** TrackList = NULL; - player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("TeletextTrack List\n"); - int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - } - } - //Chapters - if(player && player->manager && player->manager->chapter) { - char ** TrackList = NULL; - player->manager->chapter->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("Chapter List\n"); - int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - } - } - if (pm != PLAYMODE_TS && player && player->playback) { player->output.Open(); @@ -458,128 +393,70 @@ bool cPlayback::SetPosition(int position, bool absolute) return true; } -void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language) +void cPlayback::FindAllPids(int *pids, unsigned int *ac3flags, unsigned int *numpids, std::string *language) { printf("%s:%s\n", FILENAME, __FUNCTION__); - int max_numpida = *numpida; - *numpida = 0; - if(player && player->manager && player->manager->audio) { - char ** TrackList = NULL; - player->manager->audio->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("AudioTrack List\n"); - int i = 0,j=0; - for (i = 0,j=0; TrackList[i] != NULL; i+=2,j++) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - if (j < max_numpida) { - int _pid; - char _lang[strlen(TrackList[i])]; - if (2 == sscanf(TrackList[i], "%d %s\n", &_pid, _lang)) { - apids[j]=_pid; - // atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC - ac3flags[j] = atoi(TrackList[i+1]); - language[j]=std::string(_lang); - } - } - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - *numpida=j; + unsigned int i = 0; + + if(player) { + std::vector tracks = player->manager.getAudioTracks(); + for (std::vector::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) { + pids[i] = it->pid; + ac3flags[i] = it->ac3flags; + language[i] = it->Name; + i++; } } + *numpids = i; } void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language) { printf("%s:%s\n", FILENAME, __FUNCTION__); - int max_numpids = *numpids; - *numpids = 0; - if(player && player->manager && player->manager->subtitle) { - char ** TrackList = NULL; - player->manager->subtitle->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("SubtitleTrack List\n"); - int i = 0,j=0; - for (i = 0,j=0; TrackList[i] != NULL; i+=2,j++) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - if (j < max_numpids) { - int _pid; - char _lang[strlen(TrackList[i])]; - if (2 == sscanf(TrackList[i], "%d %s\n", &_pid, _lang)) { - pids[j]=_pid; - language[j]=std::string(_lang); - } - } - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - *numpids=j; + unsigned int i = 0; + + if(player) { + std::vector tracks = player->manager.getSubtitleTracks(); + for (std::vector::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) { + pids[i] = it->pid; + language[i] = it->Name; + i++; } } + *numpids = i; } void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, std::string *language) { printf("%s:%s\n", FILENAME, __FUNCTION__); - int max_numpids = *numpids; - *numpids = 0; - if(player && player->manager && player->manager->teletext) { - char ** TrackList = NULL; - player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("Teletext List\n"); - int i = 0,j=0; - for (i = 0,j=0; TrackList[i] != NULL; i+=2) { - int type = 0; - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - if (j < max_numpids) { - int _pid; - if (2 != sscanf(TrackList[i], "%*d %d %*s %d %*d %*d", &_pid, &type)) - continue; - if (type != 2 && type != 5) // return subtitles only - continue; - pids[j]=_pid; - language[j]=std::string(TrackList[i]); - j++; - } - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); - *numpids=j; + unsigned int i = 0; + + if(player) { + std::vector tracks = player->manager.getTeletextTracks(); + for (std::vector::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) { + pids[i] = it->pid; + if (it->type != 2 && it->type != 5) // return subtitles only + continue; + char tmp[80]; + snprintf(tmp, sizeof(tmp), "%d %d %s %d %d %d", it->pid, it->pid, it->Name.c_str(), it->type, it->mag, it->page); //FIXME + language[i] = std::string(tmp); + i++; } } + *numpids = i; } int cPlayback::GetTeletextPid(void) { printf("%s:%s\n", FILENAME, __FUNCTION__); - int pid = -1; - if(player && player->manager && player->manager->teletext) { - char ** TrackList = NULL; - player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); - if (TrackList != NULL) { - printf("Teletext List\n"); - int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) { - int type = 0; - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); - if (pid < 0) { - if (2 != sscanf(TrackList[i], "%*d %d %*s %d %*d %*d", &pid, &type)) - continue; - if (type != 1) - pid = -1; - } - free(TrackList[i]); - free(TrackList[i+1]); - } - free(TrackList); + if(player) { + std::vector tracks = player->manager.getTeletextTracks(); + for (std::vector::iterator it = tracks.begin(); it != tracks.end(); ++it) { + if (it->type == 1) + return it->pid; } } - printf("teletext pid id %d (0x%x)\n", pid, pid); - return pid; + return -1; } #if 0 @@ -601,6 +478,7 @@ void cPlayback::GetChapters(std::vector &positions, std::vectormanager && player->manager->chapter) { char ** TrackList = NULL; player->manager->chapter->Command(player, MANAGER_LIST, &TrackList); @@ -619,10 +497,12 @@ void cPlayback::GetChapters(std::vector &positions, std::vector &keys, std::vector &values) { +#if 0 // FIXME ... later keys.clear(); values.clear(); char **metadata = NULL; @@ -638,6 +518,7 @@ void cPlayback::GetMetadata(std::vector &keys, std::vector