libeplayer3: let neutrino handle bitmap subtitles

This commit is contained in:
martii
2014-03-16 07:29:38 +01:00
parent 12b070bc88
commit d9e8e98678
22 changed files with 116 additions and 661 deletions

View File

@@ -9,7 +9,7 @@ libeplayer3_la_SOURCES = \
container/container.c container/container_ffmpeg.c container/text_srt.c \
container/text_ssa.c container/container_ass.c \
manager/audio.c manager/manager.c manager/subtitle.c manager/video.c \
manager/dvbsubtitle.c manager/teletext.c manager/chapter.c \
manager/teletext.c manager/chapter.c \
output/output_subtitle.c output/linuxdvb.c output/output.c output/output_pipe.c \
playback/playback.c output/writer/writer.c output/writer/aac.c output/writer/wmv.c \
output/writer/ac3.c output/writer/divx.c output/writer/wma.c output/writer/pes.c \

View File

@@ -280,6 +280,8 @@ static char *searchMeta(AVDictionary * metadata, char *ourTag)
/* Worker Thread */
/* **************************** */
extern void (*dvbsubWrite)(AVSubtitle *, int64_t);
static void FFMPEGThread(Context_t * context)
{
char threadname[17];
@@ -405,7 +407,6 @@ static void FFMPEGThread(Context_t * context)
Track_t *videoTrack = NULL;
Track_t *audioTrack = NULL;
Track_t *subtitleTrack = NULL;
Track_t *dvbsubtitleTrack = NULL;
Track_t *teletextTrack = NULL;
context->playback->readCount += packet_size;
@@ -421,9 +422,6 @@ static void FFMPEGThread(Context_t * context)
if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0)
ffmpeg_err("error getting subtitle track\n");
if (context->manager->dvbsubtitle->Command(context, MANAGER_GET_TRACK, &dvbsubtitleTrack) < 0)
ffmpeg_err("error getting dvb subtitle track\n");
if (context->manager->teletext->Command(context, MANAGER_GET_TRACK, &teletextTrack) < 0)
ffmpeg_err("error getting teletext track\n");
@@ -692,46 +690,47 @@ static void FFMPEGThread(Context_t * context)
} else {
unsigned int i;
ffmpeg_printf(0, "format %d\n", sub.format);
ffmpeg_printf(0, "start_display_time %d\n", sub.start_display_time);
ffmpeg_printf(0, "end_display_time %d\n", sub.end_display_time);
ffmpeg_printf(0, "num_rects %d\n", sub.num_rects);
ffmpeg_printf(0, "pts %lld\n", sub.pts);
ffmpeg_printf(20, "format %d\n", sub.format);
ffmpeg_printf(20, "start_display_time %d\n", sub.start_display_time);
ffmpeg_printf(20, "end_display_time %d\n", sub.end_display_time);
ffmpeg_printf(20, "num_rects %d\n", sub.num_rects);
ffmpeg_printf(20, "pts %lld\n", sub.pts);
for (i = 0; i < sub.num_rects; i++) {
ffmpeg_printf(0, "x %d\n", sub.rects[i]->x);
ffmpeg_printf(0, "y %d\n", sub.rects[i]->y);
ffmpeg_printf(0, "w %d\n", sub.rects[i]->w);
ffmpeg_printf(0, "h %d\n", sub.rects[i]->h);
ffmpeg_printf(0, "nb_colors %d\n", sub.rects[i]->nb_colors);
ffmpeg_printf(0, "type %d\n", sub.rects[i]->type);
ffmpeg_printf(0, "text %s\n", sub.rects[i]->text);
ffmpeg_printf(0, "ass %s\n", sub.rects[i]->ass);
ffmpeg_printf(20, "x %d\n", sub.rects[i]->x);
ffmpeg_printf(20, "y %d\n", sub.rects[i]->y);
ffmpeg_printf(20, "w %d\n", sub.rects[i]->w);
ffmpeg_printf(20, "h %d\n", sub.rects[i]->h);
ffmpeg_printf(20, "nb_colors %d\n", sub.rects[i]->nb_colors);
ffmpeg_printf(20, "type %d\n", sub.rects[i]->type);
// pict ->AVPicture
}
}
if (((AVStream *) subtitleTrack->stream)->codec->codec_id == AV_CODEC_ID_SSA) {
if (got_sub_ptr && sub.num_rects > 0) {
unsigned int i;
switch (sub.rects[0]->type) {
case SUBTITLE_ASS:
for (i = 0; i < sub.num_rects && sub.rects[i]->type == SUBTITLE_ASS; i++) {
ffmpeg_printf(0, "ass %s\n", sub.rects[i]->ass);
ffmpeg_printf(20, "videoPts %lld %f\n", currentVideoPts, currentVideoPts / 90000.0);
SubtitleData_t data;
ffmpeg_printf(10, "videoPts %lld\n", currentVideoPts);
data.data = packet_data;
data.len = packet_size;
data.extradata = subtitleTrack->extraData;
data.extralen = subtitleTrack->extraSize;
data.pts = pts;
data.duration = duration;
context->container->assContainer->Command(context, CONTAINER_DATA, &data);
} else {
/* hopefully native text ;) */
unsigned char *line = text_to_ass((char *) packet_data, pts / 90,
duration);
ffmpeg_printf(50, "text line is %s\n", (char *) packet_data);
}
avsubtitle_free(&sub);
break;
case SUBTITLE_TEXT:
for (i = 0; i < sub.num_rects && sub.rects[i]->type == SUBTITLE_TEXT; i++) {
ffmpeg_printf(0, "text %s\n", sub.rects[i]->text);
unsigned char *line = text_to_ass(sub.rects[i]->text, pts / 90, duration);
ffmpeg_printf(50, "Sub line is %s\n", line);
ffmpeg_printf(20, "videoPts %lld %f\n", currentVideoPts, currentVideoPts / 90000.0);
SubtitleData_t data;
@@ -741,31 +740,23 @@ static void FFMPEGThread(Context_t * context)
data.extralen = strlen(DEFAULT_ASS_HEAD);
data.pts = pts;
data.duration = duration;
context->container->assContainer->Command(context, CONTAINER_DATA, &data);
free(line);
}
avsubtitle_free(&sub);
break;
case SUBTITLE_BITMAP:
ffmpeg_printf(0, "bitmap\n");
if (dvbsubWrite)
(*dvbsubWrite)(&sub, pts);
// avsubtitle_free() will be called by handler
break;
default:
break;
}
}
}
} /* duration */
} else if (dvbsubtitleTrack && (dvbsubtitleTrack->Id == pid)) {
dvbsubtitleTrack->pts = pts = calcPts(dvbsubtitleTrack->stream, packet.pts);
ffmpeg_printf(200, "DvbSubTitle index = %d\n", pid);
avOut.data = packet_data;
avOut.len = packet_size;
avOut.pts = pts;
avOut.extradata = NULL;
avOut.extralen = 0;
avOut.frameRate = 0;
avOut.timeScale = 0;
avOut.width = 0;
avOut.height = 0;
avOut.type = "dvbsubtitle";
if (context->output->dvbsubtitle->Write(context, &avOut) < 0) {
//ffmpeg_err("writing data to dvbsubtitle fifo failed\n");
}
} else if (teletextTrack && (teletextTrack->Id == pid)) {
teletextTrack->pts = pts = calcPts(teletextTrack->stream, packet.pts);
@@ -897,11 +888,11 @@ int container_ffmpeg_init(Context_t * context, char *filename)
terminating = 0;
latestPts = 0;
int res = container_ffmpeg_update_tracks(context, filename, 1);
int res = container_ffmpeg_update_tracks(context, filename);
return res;
}
int container_ffmpeg_update_tracks(Context_t * context, char *filename, int initial)
int container_ffmpeg_update_tracks(Context_t * context, char *filename)
{
if (terminating)
return cERR_CONTAINER_FFMPEG_NO_ERROR;
@@ -928,12 +919,8 @@ int container_ffmpeg_update_tracks(Context_t * context, char *filename, int init
context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL);
if (context->manager->audio)
context->manager->audio->Command(context, MANAGER_INIT_UPDATE, NULL);
#if 0
if (context->manager->subtitle)
context->manager->subtitle->Command(context, MANAGER_INIT_UPDATE, NULL);
#endif
if (context->manager->dvbsubtitle)
context->manager->dvbsubtitle->Command(context, MANAGER_INIT_UPDATE, NULL);
if (context->manager->teletext)
context->manager->teletext->Command(context, MANAGER_INIT_UPDATE, NULL);
@@ -1276,13 +1263,7 @@ int container_ffmpeg_update_tracks(Context_t * context, char *filename, int init
}
i++;
} while (t);
} else if (stream->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE && context->manager->dvbsubtitle) {
ffmpeg_printf(10, "dvb_subtitle\n");
lang = av_dict_get(stream->metadata, "language", NULL, 0);
if (context->manager->dvbsubtitle->Command(context, MANAGER_ADD, &track) < 0) {
ffmpeg_err("failed to add dvbsubtitle track %d\n", n);
}
} else if (initial && context->manager->subtitle) {
} else if (context->manager->subtitle) {
if (!stream->codec->codec) {
stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id);
if (!stream->codec->codec)
@@ -1443,11 +1424,6 @@ static int container_ffmpeg_switch_subtitle(Context_t * context __attribute__ ((
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
static int container_ffmpeg_switch_dvbsubtitle(Context_t * context __attribute__ ((unused)), int *arg __attribute__ ((unused)))
{
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
static int container_ffmpeg_switch_teletext(Context_t * context __attribute__ ((unused)), int *arg __attribute__ ((unused)))
{
return cERR_CONTAINER_FFMPEG_NO_ERROR;
@@ -1634,10 +1610,6 @@ static int Command(void *_context, ContainerCmd_t command, void *argument)
*((long long int *) argument) = latestPts;
break;
}
case CONTAINER_SWITCH_DVBSUBTITLE:{
ret = container_ffmpeg_switch_dvbsubtitle(context, (int *) argument);
break;
}
case CONTAINER_SWITCH_TELETEXT:{
ret = container_ffmpeg_switch_teletext(context, (int *) argument);
break;

View File

@@ -381,10 +381,9 @@ static int SrtGetSubtitle(Context_t * context, char *Filename)
memset(&Subtitle, 0, sizeof(Subtitle));
Subtitle.Name = subtitleExtension;
Subtitle.Encoding = "S_TEXT/SRT";
Subtitle.Id = i++,
context->manager->subtitle->Command(context,
MANAGER_ADD,
&Subtitle);
Subtitle.Id = i++;
Subtitle.is_static = 1;
context->manager->subtitle->Command(context, MANAGER_ADD, &Subtitle);
}
} /* while */
closedir(dir);
@@ -487,6 +486,7 @@ static int Command(void *_context, ContainerCmd_t command, void *argument)
switch (command) {
case CONTAINER_INIT:{
char *filename = (char *) argument;
SrtDel(context);
ret = SrtGetSubtitle(context, filename);
break;
}

View File

@@ -375,8 +375,8 @@ static int SsaGetSubtitle(Context_t * context, char *Filename)
Subtitle.Name = subtitleExtension;
Subtitle.Encoding = "S_TEXT/SSA";
Subtitle.Id = i++;
context->manager->subtitle->Command(context, MANAGER_ADD,
&Subtitle);
Subtitle.is_static = 1;
context->manager->subtitle->Command(context, MANAGER_ADD, &Subtitle);
}
} /* while */
closedir(dir);
@@ -480,6 +480,7 @@ static int Command(void *_context, ContainerCmd_t command, void *argument)
switch (command) {
case CONTAINER_INIT:{
char *filename = (char *) argument;
SsaDel(context);
ret = SsaGetSubtitle(context, filename);
break;
}

View File

@@ -14,5 +14,5 @@ typedef struct Context_s {
ManagerHandler_t *manager;
} Context_t;
int container_ffmpeg_update_tracks(Context_t * context, char *filename, int initial);
int container_ffmpeg_update_tracks(Context_t * context, char *filename);
#endif

View File

@@ -59,6 +59,7 @@ typedef struct Track_s {
int inject_raw_pcm;
int pending;
int is_static;
long long int chapter_start;
long long int chapter_end;
} Track_t;
@@ -75,7 +76,6 @@ typedef struct ManagerHandler_s {
Manager_t *audio;
Manager_t *video;
Manager_t *subtitle;
Manager_t *dvbsubtitle;
Manager_t *teletext;
Manager_t *chapter;
} ManagerHandler_t;

View File

@@ -67,7 +67,6 @@ typedef struct OutputHandler_s {
Output_t *audio;
Output_t *video;
Output_t *subtitle;
Output_t *dvbsubtitle;
Output_t *teletext;
int (*Command) ( /*Context_t */ void *, OutputCmd_t, void *);
} OutputHandler_t;

View File

@@ -21,6 +21,8 @@
*
*/
#include <sys/types.h>
#define DEFAULT_ASS_HEAD "[Script Info]\n\
Original Script: (c) 2008\n\
ScriptType: v4.00\n\
@@ -119,6 +121,7 @@ typedef struct {
unsigned int destStride;
void (*framebufferBlit) (void);
void (*dvbsubWrite) (void *, int64_t);
} SubtitleOutputDef_t;
#endif

View File

@@ -200,8 +200,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri,
0);
container_ffmpeg_update_tracks(context, context->playback->uri);
*((char ***) argument) = (char **) ManagerList(context);
break;
}

View File

@@ -189,7 +189,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
container_ffmpeg_update_tracks(context, context->playback->uri);
*((char ***) argument) = (char **) ManagerList(context);
break;
}

View File

@@ -1,296 +0,0 @@
/*
* dvbsubtitle 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 <libavformat/avformat.h>
#include "manager.h"
#include "common.h"
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define TRACKWRAP 20
#define DVBSUBTITLE_MGR_DEBUG
#ifdef DVBSUBTITLE_MGR_DEBUG
static short debug_level = 0;
#define dvbsubtitle_mgr_printf(level, x...) do { \
if (debug_level >= level) printf(x); } while (0)
#else
#define dvbsubtitle_mgr_printf(level, x...)
#endif
#ifndef DVBSUBTITLE_MGR_SILENT
#define dvbsubtitle_mgr_err(x...) do { printf(x); } while (0)
#else
#define dvbsubtitle_mgr_err(x...)
#endif
/* Error Constants */
#define cERR_DVBSUBTITLE_MGR_NO_ERROR 0
#define cERR_DVBSUBTITLE_MGR_ERROR -1
static const char FILENAME[] = __FILE__;
/* ***************************** */
/* Types */
/* ***************************** */
/* ***************************** */
/* Varaibles */
/* ***************************** */
static Track_t *Tracks = NULL;
static int TrackCount = 0;
static int CurrentTrack = -1;
/* ***************************** */
/* Prototypes */
/* ***************************** */
/* ***************************** */
/* Functions */
/* ***************************** */
static int ManagerAdd(Context_t * context, Track_t track)
{
dvbsubtitle_mgr_printf(10,
"%s::%s name=\"%s\" encoding=\"%s\" id=%d\n",
FILENAME, __FUNCTION__, track.Name,
track.Encoding, track.Id);
if (Tracks == NULL) {
Tracks = malloc(sizeof(Track_t) * TRACKWRAP);
int i;
for (i = 0; i < TRACKWRAP; i++)
Tracks[i].Id = -1;
}
if (Tracks == NULL) {
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME,
__FUNCTION__);
return cERR_DVBSUBTITLE_MGR_ERROR;
}
int i;
for (i = 0; i < TRACKWRAP; i++) {
if (Tracks[i].Id == track.Id) {
Tracks[i].pending = 0;
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
}
}
if (TrackCount < TRACKWRAP) {
copyTrack(&Tracks[TrackCount], &track);
TrackCount++;
} else {
dvbsubtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n",
FILENAME, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_DVBSUBTITLE_MGR_ERROR;
}
if (TrackCount > 0)
context->playback->isDvbSubtitle = 1;
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
}
static char **ManagerList(Context_t * context __attribute__ ((unused)))
{
int i = 0, j = 0;
char **tracklist = NULL;
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
if (Tracks != NULL) {
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
if (tracklist == NULL) {
dvbsubtitle_mgr_err("%s:%s malloc failed\n", FILENAME,
__FUNCTION__);
return NULL;
}
for (i = 0, j = 0; i < TrackCount; i++, j += 2) {
if (Tracks[i].pending)
continue;
size_t len = strlen(Tracks[i].Name) + 20;
char tmp[len];
snprintf(tmp, len, "%d %s\n", Tracks[i].Id, Tracks[i].Name);
tracklist[j] = strdup(tmp);
tracklist[j + 1] = strdup(Tracks[i].Encoding);
}
tracklist[j] = NULL;
}
dvbsubtitle_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME,
__FUNCTION__, tracklist, j, TrackCount);
return tracklist;
}
static int ManagerDel(Context_t * context)
{
int i = 0;
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
if (Tracks != NULL) {
for (i = 0; i < TrackCount; i++) {
freeTrack(&Tracks[i]);
}
free(Tracks);
Tracks = NULL;
} else {
dvbsubtitle_mgr_err("%s::%s nothing to delete!\n", FILENAME,
__FUNCTION__);
return cERR_DVBSUBTITLE_MGR_ERROR;
}
TrackCount = 0;
CurrentTrack = -1;
context->playback->isDvbSubtitle = 0;
dvbsubtitle_mgr_printf(10, "%s::%s return no error\n", FILENAME,
__FUNCTION__);
return cERR_DVBSUBTITLE_MGR_NO_ERROR;
}
static int Command(void *_context, ManagerCmd_t command, void *argument)
{
Context_t *context = (Context_t *) _context;
int ret = cERR_DVBSUBTITLE_MGR_NO_ERROR;
dvbsubtitle_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__);
switch (command) {
case MANAGER_ADD:{
Track_t *track = argument;
ret = ManagerAdd(context, *track);
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri,
0);
*((char ***) argument) = (char **) ManagerList(context);
break;
}
case MANAGER_GET:{
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME,
__FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0))
*((int *) argument) = (int) Tracks[CurrentTrack].Id;
else
*((int *) argument) = (int) -1;
break;
}
case MANAGER_GET_TRACK:{
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n",
FILENAME, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0))
*((Track_t **) argument) =
(Track_t *) & Tracks[CurrentTrack];
else
*((Track_t **) argument) = NULL;
break;
}
case MANAGER_GETENCODING:{
if ((TrackCount > 0) && (CurrentTrack >= 0))
*((char **) argument) =
(char *) strdup(Tracks[CurrentTrack].Encoding);
else
*((char **) argument) = (char *) strdup("");
break;
}
case MANAGER_GETNAME:{
if ((TrackCount > 0) && (CurrentTrack >= 0))
*((char **) argument) =
(char *) strdup(Tracks[CurrentTrack].Name);
else
*((char **) argument) = (char *) strdup("");
break;
}
case MANAGER_SET:{
int i;
dvbsubtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n",
FILENAME, __FUNCTION__,
*((int *) argument));
for (i = 0; i < TrackCount; i++)
if (Tracks[i].Id == *((int *) argument)) {
CurrentTrack = i;
break;
}
if (i == TrackCount) {
dvbsubtitle_mgr_err("%s::%s track id %d unknown\n",
FILENAME, __FUNCTION__,
*((int *) argument));
ret = cERR_DVBSUBTITLE_MGR_ERROR;
}
break;
}
case MANAGER_DEL:{
ret = ManagerDel(context);
break;
}
case MANAGER_INIT_UPDATE:{
int i;
for (i = 0; i < TrackCount; i++)
Tracks[i].pending = 1;
break;
}
default:
dvbsubtitle_mgr_err("%s::%s ContainerCmd %d not supported!\n",
FILENAME, __FUNCTION__, command);
ret = cERR_DVBSUBTITLE_MGR_ERROR;
break;
}
dvbsubtitle_mgr_printf(10, "%s:%s: returning %d\n", FILENAME,
__FUNCTION__, ret);
return ret;
}
struct Manager_s DvbSubtitleManager = {
"DvbSubtitle",
&Command,
NULL
};

View File

@@ -40,7 +40,6 @@
extern Manager_t AudioManager;
extern Manager_t VideoManager;
extern Manager_t SubtitleManager;
extern Manager_t DvbSubtitleManager;
extern Manager_t TeletextManager;
extern Manager_t ChapterManager;
@@ -49,7 +48,6 @@ ManagerHandler_t ManagerHandler = {
&AudioManager,
&VideoManager,
&SubtitleManager,
&DvbSubtitleManager,
&TeletextManager,
&ChapterManager
};

View File

@@ -200,8 +200,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri,
0);
container_ffmpeg_update_tracks(context, context->playback->uri);
*((char ***) argument) = (char **) ManagerList(context);
break;
}
@@ -247,6 +246,11 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", FILENAME,
__FUNCTION__, *((int *) argument));
if (*((int *) argument) < 0) {
CurrentTrack = -1;
break;
}
for (i = 0; i < TrackCount; i++)
if (Tracks[i].Id == *((int *) argument)) {
CurrentTrack = i;
@@ -266,6 +270,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
case MANAGER_INIT_UPDATE:{
int i;
for (i = 0; i < TrackCount; i++)
if (!Tracks[i].is_static)
Tracks[i].pending = 1;
break;
}

View File

@@ -201,8 +201,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri,
0);
container_ffmpeg_update_tracks(context, context->playback->uri);
*((char ***) argument) = (char **) ManagerList(context);
break;
}

View File

@@ -194,8 +194,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
break;
}
case MANAGER_LIST:{
container_ffmpeg_update_tracks(context, context->playback->uri,
0);
container_ffmpeg_update_tracks(context, context->playback->uri);
*((char ***) argument) = (char **) ManagerList(context);
break;
}

View File

@@ -119,10 +119,6 @@ static void OutputAdd(Context_t * context, char *port)
context->output->subtitle = AvailableOutput[i];
return;
}
if (!strcmp("dvbsubtitle", port)) {
context->output->dvbsubtitle = AvailableOutput[i];
return;
}
if (!strcmp("teletext", port)) {
context->output->teletext = AvailableOutput[i];
return;
@@ -140,8 +136,6 @@ static void OutputDel(Context_t * context, char *port)
context->output->video = NULL;
else if (!strcmp("subtitle", port))
context->output->subtitle = NULL;
else if (!strcmp("dvbsubtitle", port))
context->output->dvbsubtitle = NULL;
else if (!strcmp("teletext", port))
context->output->teletext = NULL;
@@ -173,11 +167,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
context->output->subtitle->Command(context,
OUTPUT_OPEN,
"subtitle");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -204,11 +193,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
context->output->subtitle->Command(context,
OUTPUT_CLOSE,
"subtitle");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -252,11 +236,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
OUTPUT_PLAY,
"subtitle");
}
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -284,11 +263,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
context->output->subtitle->Command(context,
OUTPUT_STOP,
"subtitle");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -382,11 +356,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
"audio");
//if (context->playback->isSubtitle)
// ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -424,11 +393,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
"audio");
//if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
// ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -464,11 +428,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
return context->output->video->Command(context,
OUTPUT_SWITCH,
"video");
if (context->playback->isDvbSubtitle)
ret |=
context->output->dvbsubtitle->Command(context,
command,
"dvbsubtitle");
if (context->playback->isTeletext)
ret |=
context->output->teletext->Command(context,
@@ -552,7 +511,6 @@ OutputHandler_t OutputHandler = {
NULL,
NULL,
NULL,
NULL, // dvbsubtitle
NULL, // teletext
&Command
};

View File

@@ -71,10 +71,8 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x );
#define cERR_PIPE_ERROR -1
static const char TELETEXTPIPE[] = "/tmp/.eplayer3_teletext";
static const char DVBSUBTITLEPIPE[] = "/tmp/.eplayer3_dvbsubtitle";
static int teletextfd = -1;
static int dvbsubtitlefd = -1;
pthread_mutex_t Pipemutex;
@@ -114,9 +112,8 @@ void releasePipeMutex(const char *filename
int PipeOpen(Context_t * context __attribute__ ((unused)), char *type)
{
unsigned char teletext = !strcmp("teletext", type);
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
pipe_printf(10, "t%d\n", teletext);
if (teletext && teletextfd == -1) {
mkfifo(TELETEXTPIPE, 0644);
@@ -129,27 +126,15 @@ int PipeOpen(Context_t * context __attribute__ ((unused)), char *type)
return cERR_PIPE_ERROR;
}
}
if (dvbsubtitle && dvbsubtitlefd == -1) {
mkfifo(DVBSUBTITLEPIPE, 0644);
dvbsubtitlefd = open(DVBSUBTITLEPIPE, O_RDWR | O_NONBLOCK);
if (dvbsubtitlefd < 0) {
pipe_err("failed to open %s - errno %d\n", DVBSUBTITLEPIPE,
errno);
pipe_err("%s\n", strerror(errno));
return cERR_PIPE_ERROR;
}
}
return cERR_PIPE_NO_ERROR;
}
int PipeClose(Context_t * context, char *type)
{
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
pipe_printf(10, "t%d\n", teletext);
/* closing stand alone is not allowed, so prevent
* user from closing and dont call stop. stop will
@@ -159,10 +144,6 @@ int PipeClose(Context_t * context, char *type)
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
if (dvbsubtitle && dvbsubtitlefd != -1) {
close(dvbsubtitlefd);
dvbsubtitlefd = -1;
}
if (teletext && teletextfd != -1) {
close(teletextfd);
teletextfd = -1;
@@ -178,13 +159,10 @@ int PipePlay(Context_t * context __attribute__ ((unused)), char *type
int ret = cERR_PIPE_NO_ERROR;
#if 0
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
pipe_printf(10, "t%d\n", teletext);
if (dvbsubtitle && dvbsubtitlefd != -1) {
}
if (teletext && teletextfd != -1) {
}
#endif
@@ -197,15 +175,12 @@ int PipeStop(Context_t * context __attribute__ ((unused)), char *type
int ret = cERR_PIPE_NO_ERROR;
#if 0
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
pipe_printf(10, "t%d\n", teletext);
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
if (dvbsubtitle && dvbsubtitlefd != -1) {
}
if (teletext && teletextfd != -1) {
}
@@ -217,19 +192,13 @@ int PipeStop(Context_t * context __attribute__ ((unused)), char *type
int PipeFlush(Context_t * context __attribute__ ((unused)), char *type)
{
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "t%d d%d\n", teletext, dvbsubtitle);
pipe_printf(10, "t%d\n", teletext);
if ((dvbsubtitle && dvbsubtitlefd != -1)
|| (teletext && teletextfd != -1)) {
if (teletext && teletextfd != -1) {
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
if (dvbsubtitle && dvbsubtitlefd != -1) {
char buf[65536];
while (0 < read(dvbsubtitlefd, buf, sizeof(buf)));
}
if (teletext && teletextfd != -1) {
char buf[65536];
while (0 < read(teletextfd, buf, sizeof(buf)));
@@ -246,19 +215,13 @@ int PipeFlush(Context_t * context __attribute__ ((unused)), char *type)
int PipeClear(Context_t * context __attribute__ ((unused)), char *type)
{
int ret = cERR_PIPE_NO_ERROR;
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
pipe_printf(10, "v%d\n", teletext);
if ((dvbsubtitle && dvbsubtitlefd != -1)
|| (teletext && teletextfd != -1)) {
if (teletext && teletextfd != -1) {
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
if (dvbsubtitle && dvbsubtitlefd != -1) {
char buf[65536];
while (0 < read(dvbsubtitlefd, buf, sizeof(buf)));
}
if (teletext && teletextfd != -1) {
char buf[65536];
while (0 < read(teletextfd, buf, sizeof(buf)));
@@ -276,21 +239,16 @@ int PipeSwitch(Context_t * context __attribute__ ((unused)), char *type
__attribute__ ((unused)))
{
#if 0
unsigned char dvbsubtitle = !strcmp("dvbsubtitle", type);
unsigned char teletext = !strcmp("teletext", type);
pipe_printf(10, "v%d a%d\n", dvbsubtitle, teletext);
pipe_printf(10, "t%d\n", teletext);
if ((dvbsubtitle && dvbsubtitlefd != -1)
|| (teletext && teletextfd != -1)) {
if (teletext && teletextfd != -1) {
getPipeMutex(FILENAME, __FUNCTION__, __LINE__);
if (teletext && teletextfd != -1) {
}
if (dvbsubtitle && dvbsubtitlefd != -1) {
}
releasePipeMutex(FILENAME, __FUNCTION__, __LINE__);
}
@@ -327,54 +285,11 @@ static int writePESDataTeletext(int fd, unsigned char *data,
return len;
}
static int writePESDataDvbsubtitle(int fd, unsigned char *data,
size_t data_len, int64_t pts)
{
int len = 0;
if (data_len > 0) {
len = data_len + 10;
char header[16];
memset(header, 0, sizeof(header));
header[2] = 0x01;
header[3] = 0xbd;
header[4] = (len >> 8) & 0xff;
header[5] = len & 0xff;
if (pts) {
header[7] = 0x80;
header[13] = 0x01 | ((pts << 1) & 0xff);
pts >>= 7;
header[12] = pts & 0xff;
pts >>= 8;
header[11] = 0x01 | ((pts << 1) & 0xff);
pts >>= 7;
header[10] = pts & 0xff;
pts >>= 8;
header[9] = 0x21 | ((pts << 1) & 0xff);
}
header[8] = 14 - 9;
header[14] = 0x20;
struct iovec iov[2];
iov[0].iov_base = header;
iov[0].iov_len = 16;
iov[1].iov_base = data;
iov[1].iov_len = data_len;
len = writev(fd, iov, 2);
if (len != (int) (iov[0].iov_len + iov[1].iov_len)) {
// writing to pipe failed, clear it.
char buf[65536];
while (0 < read(fd, buf, sizeof(buf)));
}
}
return len;
}
static int Write(void *_context __attribute__ ((unused)), void *_out)
{
AudioVideoOut_t *out = (AudioVideoOut_t *) _out;
int ret = cERR_PIPE_NO_ERROR;
int res = 0;
unsigned char dvbsubtitle;
unsigned char teletext;
if (out == NULL) {
@@ -382,23 +297,14 @@ static int Write(void *_context __attribute__ ((unused)), void *_out)
return cERR_PIPE_ERROR;
}
dvbsubtitle = !strcmp("dvbsubtitle", out->type);
teletext = !strcmp("teletext", out->type);
pipe_printf(20,
"DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n",
out->len, out->extralen, out->pts, out->frameRate);
pipe_printf(20, "v%d a%d\n", dvbsubtitle, teletext);
pipe_printf(20, "t%d\n", teletext);
if (dvbsubtitle) {
res =
writePESDataDvbsubtitle(dvbsubtitlefd, out->data, out->len,
out->pts);
if (res <= 0) {
ret = cERR_PIPE_ERROR;
}
} else if (teletext) {
if (teletext) {
res = writePESDataTeletext(teletextfd, out->data, out->len);
if (res <= 0) {
@@ -466,10 +372,10 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
return ret;
}
static char *PipeCapabilities[] = { "teletext", "dvbsubtitle", NULL };
static char *PipeCapabilities[] = { "teletext", NULL };
struct Output_s PipeOutput = {
"DVBSubTitle",
"TeleText",
&Command,
&Write,
PipeCapabilities

View File

@@ -38,6 +38,8 @@
#include "output.h"
#include "subtitle.h"
#include <libavcodec/avcodec.h>
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
@@ -108,6 +110,7 @@ static int screen_height = 0;
static int destStride = 0;
static void (*framebufferBlit) = NULL;
static uint32_t *destination = NULL;
void (*dvbsubWrite)(AVSubtitle *, int64_t) = NULL;
/* ***************************** */
/* Prototypes */
@@ -784,6 +787,7 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
out->screen_width = screen_width;
out->screen_height = screen_height;
out->framebufferBlit = framebufferBlit;
out->dvbsubWrite = (void (*)(void *, int64_t))dvbsubWrite;
out->destination = destination;
out->destStride = destStride;
break;
@@ -793,6 +797,7 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
screen_width = out->screen_width;
screen_height = out->screen_height;
framebufferBlit = out->framebufferBlit;
dvbsubWrite = (void (*)(AVSubtitle *, int64_t))out->dvbsubWrite;
destination = out->destination;
destStride = out->destStride;
break;

View File

@@ -195,7 +195,6 @@ static int PlaybackClose(Context_t * context)
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->dvbsubtitle->Command(context, MANAGER_DEL, NULL);
context->manager->teletext->Command(context, MANAGER_DEL, NULL);
context->manager->chapter->Command(context, MANAGER_DEL, NULL);
@@ -726,8 +725,8 @@ static int PlaybackSwitchSubtitle(Context_t * context, int *track)
subtitle->Command(context, MANAGER_SET, track) < 0) {
playback_err("manager set track failed\n");
}
#if 0
if (*track < 0) {
if (*track < 0 && !strcmp(context->playback->uri, "file://")) {
//CHECK FOR SUBTITLES
if (context->container
&& context->container->textSrtContainer)
@@ -748,7 +747,7 @@ static int PlaybackSwitchSubtitle(Context_t * context, int *track)
CONTAINER_INIT,
NULL);
}
#endif
context->manager->subtitle->Command(context, MANAGER_GET,
&trackid);
@@ -791,31 +790,6 @@ static int PlaybackSwitchSubtitle(Context_t * context, int *track)
return ret;
}
static int PlaybackSwitchDVBSubtitle(Context_t * context, int *pid)
{
int ret = cERR_PLAYBACK_NO_ERROR;
playback_printf(10, "Track: %d\n", *pid);
if (context && context->manager && context->manager->dvbsubtitle) {
if (context->manager->
dvbsubtitle->Command(context,
*pid < 0 ? MANAGER_DEL : MANAGER_SET,
pid) < 0) {
playback_err("dvbsub manager set track failed\n");
ret = cERR_PLAYBACK_ERROR;
}
} else
playback_err("no dvbsubtitle\n");
if (*pid < 0)
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
playback_printf(10, "exiting with value %d\n", ret);
return ret;
}
static int PlaybackSwitchTeletext(Context_t * context, int *pid)
{
int ret = cERR_PLAYBACK_NO_ERROR;
@@ -833,7 +807,7 @@ static int PlaybackSwitchTeletext(Context_t * context, int *pid)
playback_err("no ttxsubtitle\n");
if (*pid < 0)
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
container_ffmpeg_update_tracks(context, context->playback->uri);
playback_printf(10, "exiting with value %d\n", ret);
@@ -962,10 +936,6 @@ static int Command(void *_context, PlaybackCmd_t command, void *argument)
(unsigned long long int *) argument);
break;
}
case PLAYBACK_SWITCH_DVBSUBTITLE:{
ret = PlaybackSwitchDVBSubtitle(context, (int *) argument);
break;
}
case PLAYBACK_SWITCH_TELETEXT:{
ret = PlaybackSwitchTeletext(context, (int *) argument);
break;

View File

@@ -1,5 +1,6 @@
noinst_LTLIBRARIES = libspark.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS = \
-I$(top_srcdir)/common \
-I$(top_srcdir)/libeplayer3/include

View File

@@ -68,13 +68,12 @@ bool cPlayback::Open(playmode_t PlayMode)
player->output->Command(player,OUTPUT_ADD, (void*)"audio");
player->output->Command(player,OUTPUT_ADD, (void*)"video");
player->output->Command(player,OUTPUT_ADD, (void*)"subtitle");
player->output->Command(player,OUTPUT_ADD, (void*)"dvbsubtitle");
player->output->Command(player,OUTPUT_ADD, (void*)"teletext");
if (framebuffer_callback) {
SubtitleOutputDef_t so;
memset(&so, 0, sizeof(so));
framebuffer_callback(&so.destination, &so.screen_width, &so.screen_height, &so.destStride, &so.framebufferBlit);
framebuffer_callback(&so.destination, &so.screen_width, &so.screen_height, &so.destStride, &so.framebufferBlit, &so.dvbsubWrite);
player->output->subtitle->Command(player, OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&so);
}
}
@@ -110,7 +109,6 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
//create playback path
mAudioStream=0;
mSubtitleStream=-1;
mDvbsubtitleStream=-1;
mTeletextStream=-1;
char file[strlen(filename) + 1];
*file = 0;
@@ -160,21 +158,6 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
free(TrackList);
}
}
//DVBSUB
if(player && player->manager && player->manager->dvbsubtitle) {
char ** TrackList = NULL;
player->manager->dvbsubtitle->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("DVBSubtitleTrack 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) {
@@ -276,7 +259,6 @@ bool cPlayback::Stop(void)
player->output->Command(player,OUTPUT_DEL, (void*)"audio");
player->output->Command(player,OUTPUT_DEL, (void*)"video");
player->output->Command(player,OUTPUT_DEL, (void*)"subtitle");
player->output->Command(player,OUTPUT_DEL, (void*)"dvbsubtitle");
player->output->Command(player,OUTPUT_DEL, (void*)"teletext");
}
@@ -314,18 +296,6 @@ bool cPlayback::SetSubtitlePid(int pid)
return true;
}
bool cPlayback::SetDvbsubtitlePid(int pid)
{
printf("%s:%s\n", FILENAME, __FUNCTION__);
int i=pid;
if(pid!=mDvbsubtitleStream){
if(player && player->playback)
player->playback->Command(player, PLAYBACK_SWITCH_DVBSUBTITLE, (void*)&i);
mDvbsubtitleStream=pid;
}
return true;
}
bool cPlayback::SetTeletextPid(int pid)
{
printf("%s:%s\n", FILENAME, __FUNCTION__);
@@ -595,36 +565,6 @@ void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::strin
}
}
void cPlayback::FindAllDvbsubtitlePids(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->dvbsubtitle) {
char ** TrackList = NULL;
player->manager->dvbsubtitle->Command(player, MANAGER_LIST, &TrackList);
if (TrackList != NULL) {
printf("DvbsubtitleTrack 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;
}
}
}
void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, std::string *language)
{
printf("%s:%s\n", FILENAME, __FUNCTION__);
@@ -746,7 +686,7 @@ void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::str
}
//
cPlayback::cPlayback(int num __attribute__((unused)), void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void)))
cPlayback::cPlayback(int num __attribute__((unused)), void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void), void (**)(void *, int64_t)))
{
printf("%s:%s\n", FILENAME, __FUNCTION__);
playing=false;

View File

@@ -17,12 +17,11 @@ class cPlayback
int nPlaybackSpeed;
int mAudioStream;
int mSubtitleStream;
int mDvbsubtitleStream;
int mTeletextStream;
void (*framebuffer_callback)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void));
void (*framebuffer_callback)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void), void (**)(void *, int64_t));
bool Stop(void);
public:
cPlayback(int num = 0, void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void)) = NULL);
cPlayback(int num = 0, void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void), void (**)(void *, int64_t)) = NULL);
~cPlayback();
bool Open(playmode_t PlayMode);
@@ -31,11 +30,9 @@ class cPlayback
int ac3, unsigned int duration, bool no_probe = true);
bool SetAPid(int pid, bool ac3);
bool SetSubtitlePid(int pid);
bool SetDvbsubtitlePid(int pid);
bool SetTeletextPid(int pid);
int GetAPid(void) { return mAudioStream; }
int GetSubtitlePid(void) { return mSubtitleStream; }
int GetDvbsubtitlePid(void) { return mDvbsubtitleStream; }
int GetTeletextPid(void);
void SuspendSubtitle(bool);
bool SetSpeed(int speed);
@@ -45,7 +42,6 @@ class cPlayback
bool SetPosition(int position, bool absolute = false);
void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language);
void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language);
void FindAllDvbsubtitlePids(int *pids, unsigned int *numpidd, std::string *language);
void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage);
void RequestAbort(void);
bool IsPlaying(void);