mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-libstb-hal.git
synced 2025-08-26 15:02:43 +02:00
libeplayer3: implement Manager class
Origin commit data
------------------
Branch: master
Commit: 6c1f7c13bd
Author: martii <m4rtii@gmx.de>
Date: 2014-04-06 (Sun, 06 Apr 2014)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
@@ -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 \
|
||||
|
@@ -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:
|
||||
|
@@ -4,6 +4,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Thread>
|
||||
#include <OpenThreads/Condition>
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/avutil.h>
|
||||
@@ -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<int,Track *> 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<Track> getVideoTracks();
|
||||
std::vector<Track> getAudioTracks();
|
||||
std::vector<Track> getSubtitleTracks();
|
||||
std::vector<Track> 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
|
||||
|
@@ -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);
|
||||
|
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#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<int,Track_t> 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<int,Track_t>::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<int,Track_t>::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<int,Track_t>::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
|
||||
};
|
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#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<int,Track_t> 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<int,Track_t>::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<int,Track_t>::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
|
||||
};
|
@@ -25,52 +25,159 @@
|
||||
#include <string.h>
|
||||
#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<OpenThreads::Mutex> 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<OpenThreads::Mutex> m_lock(mutex);
|
||||
Track *t = new Track;
|
||||
*t = track;
|
||||
audioTracks[track.pid] = t;
|
||||
}
|
||||
|
||||
void Manager::addSubtitleTrack(Track &track)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
Track *t = new Track;
|
||||
*t = track;
|
||||
subtitleTracks[track.pid] = t;
|
||||
}
|
||||
|
||||
void Manager::addTeletextTrack(Track &track)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
Track *t = new Track;
|
||||
*t = track;
|
||||
teletextTracks[track.pid] = t;
|
||||
}
|
||||
|
||||
std::vector<Track> Manager::getVideoTracks()
|
||||
{
|
||||
// input.UpdateTracks();
|
||||
std::vector<Track> res;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
for(std::map<int,Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
|
||||
if (!it->second->inactive)
|
||||
res.push_back(*it->second);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<Track> Manager::getAudioTracks()
|
||||
{
|
||||
// input.UpdateTracks();
|
||||
std::vector<Track> res;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
for(std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
|
||||
if (!it->second->inactive)
|
||||
res.push_back(*it->second);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<Track> Manager::getSubtitleTracks()
|
||||
{
|
||||
// input.UpdateTracks();
|
||||
std::vector<Track> res;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
for(std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it)
|
||||
if (!it->second->inactive)
|
||||
res.push_back(*it->second);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<Track> Manager::getTeletextTracks()
|
||||
{
|
||||
// input.UpdateTracks();
|
||||
std::vector<Track> res;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
for(std::map<int,Track*>::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<OpenThreads::Mutex> m_lock(mutex);
|
||||
std::map<int,Track*>::iterator it = videoTracks.find(pid);
|
||||
if (it != videoTracks.end() && !it->second->inactive)
|
||||
return it->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *Manager::getAudioTrack(int pid)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
std::map<int,Track*>::iterator it = audioTracks.find(pid);
|
||||
if (it != audioTracks.end() && !it->second->inactive)
|
||||
return it->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *Manager::getSubtitleTrack(int pid)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
std::map<int,Track*>::iterator it = subtitleTracks.find(pid);
|
||||
if (it != subtitleTracks.end() && !it->second->inactive)
|
||||
return it->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Track *Manager::getTeletextTrack(int pid)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
std::map<int,Track*>::iterator it = teletextTracks.find(pid);
|
||||
if (it != teletextTracks.end() && !it->second->inactive)
|
||||
return it->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Manager::initTrackUpdate()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
|
||||
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
|
||||
it->second->inactive = !it->second->is_static;
|
||||
|
||||
for (std::map<int, Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
|
||||
it->second->inactive = !it->second->is_static;
|
||||
|
||||
for (std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it)
|
||||
it->second->inactive = !it->second->is_static;
|
||||
|
||||
for (std::map<int,Track*>::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it)
|
||||
it->second->inactive = !it->second->is_static;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Manager::clearTracks()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
|
||||
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
|
||||
delete it->second;
|
||||
audioTracks.clear();
|
||||
|
||||
for (std::map<int, Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
|
||||
delete it->second;
|
||||
videoTracks.clear();
|
||||
|
||||
for (std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it)
|
||||
delete it->second;
|
||||
subtitleTracks.clear();
|
||||
|
||||
for (std::map<int,Track*>::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it)
|
||||
delete it->second;
|
||||
teletextTracks.clear();
|
||||
}
|
||||
|
||||
Manager::~Manager()
|
||||
{
|
||||
clearTracks();
|
||||
}
|
||||
|
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#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<int,Track_t> 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<int,Track_t>::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<int,Track_t>::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<int,Track_t>::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
|
||||
};
|
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#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<int,Track_t> 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<int,Track_t>::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<int,Track_t>::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<int,Track_t>::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
|
||||
};
|
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#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<int,Track_t> 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<int,Track_t>::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<int,Track_t>::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<int,Track_t>::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
|
||||
};
|
@@ -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)
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include <player.h>
|
||||
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<Track> tracks = player->manager.getAudioTracks();
|
||||
for (std::vector<Track>::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<Track> tracks = player->manager.getSubtitleTracks();
|
||||
for (std::vector<Track>::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<Track> tracks = player->manager.getTeletextTracks();
|
||||
for (std::vector<Track>::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<Track> tracks = player->manager.getTeletextTracks();
|
||||
for (std::vector<Track>::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<int> &positions, std::vector<std::string
|
||||
positions.clear();
|
||||
titles.clear();
|
||||
|
||||
#if 0 // FIXME ... later
|
||||
if(player && player->manager && player->manager->chapter) {
|
||||
char ** TrackList = NULL;
|
||||
player->manager->chapter->Command(player, MANAGER_LIST, &TrackList);
|
||||
@@ -619,10 +497,12 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
|
||||
free(TrackList);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
|
||||
{
|
||||
#if 0 // FIXME ... later
|
||||
keys.clear();
|
||||
values.clear();
|
||||
char **metadata = NULL;
|
||||
@@ -638,6 +518,7 @@ void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::str
|
||||
free(metadata);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
Reference in New Issue
Block a user