mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 15:02:58 +02:00
libeplayer3: let neutrino handle bitmap subtitles
This commit is contained in:
@@ -5,11 +5,11 @@ CXXFLAGS = -Wall
|
||||
AM_CPPFLAGS = \
|
||||
-I$(srcdir)/include
|
||||
|
||||
libeplayer3_la_SOURCES = \
|
||||
libeplayer3_la_SOURCES = \
|
||||
container/container.c container/container_ffmpeg.c container/text_srt.c \
|
||||
container/text_ssa.c container/container_ass.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 \
|
||||
|
@@ -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,80 +690,73 @@ 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) {
|
||||
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);
|
||||
ffmpeg_printf(50, "Sub line is %s\n", line);
|
||||
ffmpeg_printf(20, "videoPts %lld %f\n", currentVideoPts, currentVideoPts / 90000.0);
|
||||
SubtitleData_t data;
|
||||
data.data = line;
|
||||
data.len = strlen((char *) line);
|
||||
data.extradata = (unsigned char *) DEFAULT_ASS_HEAD;
|
||||
data.extralen = strlen(DEFAULT_ASS_HEAD);
|
||||
data.pts = pts;
|
||||
data.duration = duration;
|
||||
|
||||
context->container->assContainer->Command(context, CONTAINER_DATA, &data);
|
||||
free(line);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
data.data = line;
|
||||
data.len = strlen((char *) line);
|
||||
data.extradata = (unsigned char *) DEFAULT_ASS_HEAD;
|
||||
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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
};
|
@@ -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
|
||||
};
|
||||
|
@@ -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,7 +270,8 @@ static int Command(void *_context, ManagerCmd_t command, void *argument)
|
||||
case MANAGER_INIT_UPDATE:{
|
||||
int i;
|
||||
for (i = 0; i < TrackCount; i++)
|
||||
Tracks[i].pending = 1;
|
||||
if (!Tracks[i].is_static)
|
||||
Tracks[i].pending = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user