mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 15:02:58 +02:00
libeplayer3: subtitles will now be displayed by neutrino
This commit is contained in:
@@ -17,12 +17,11 @@ class cPlayback
|
||||
int mAudioStream;
|
||||
int mSubtitleStream;
|
||||
int mTeletextStream;
|
||||
void (*framebuffer_callback)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void), void (**)(void *, int64_t));
|
||||
public:
|
||||
cPlayback(int, void (*)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void), void (**)(void *, int64_t)) = NULL) { };
|
||||
cPlayback(int);
|
||||
bool Open(playmode_t PlayMode);
|
||||
void Close(void);
|
||||
bool Start(char * filename, int vpid, int vtype, int apid, bool ac3, int duration, bool no_probe = true);
|
||||
bool Start(char *filename, int vpid, int vtype, int apid, bool ac3, int duration, bool no_probe = true);
|
||||
bool Stop(void);
|
||||
bool SetAPid(int pid, bool ac3);
|
||||
bool SetSubtitlePid(int pid);
|
||||
|
@@ -6,15 +6,14 @@ AM_CPPFLAGS = \
|
||||
-I$(srcdir)/include
|
||||
|
||||
libeplayer3_la_SOURCES = \
|
||||
container/container.c container/container_ffmpeg.c container/text_srt.c \
|
||||
container/text_ssa.c container/container_ass.c \
|
||||
container/container.c container/container_ffmpeg.c \
|
||||
manager/audio.c manager/manager.c manager/subtitle.c manager/video.c \
|
||||
manager/teletext.c manager/chapter.c \
|
||||
output/output_subtitle.c output/linuxdvb.c output/output.c output/output_pipe.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 \
|
||||
output/writer/dts.c output/writer/mpeg2.c output/writer/mp3.c output/writer/misc.c \
|
||||
output/writer/h264.c output/writer/h263.c output/writer/vc1.c output/writer/framebuffer.c \
|
||||
output/writer/h264.c output/writer/h263.c output/writer/vc1.c \
|
||||
output/writer/flac.c output/writer/pcm.c
|
||||
|
||||
AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
||||
@@ -29,10 +28,10 @@ AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOUR
|
||||
|
||||
#libeplayer3_la_LIBADD = -lpthread -lavformat -lavcodec -lavutil -lz -lass -lm -lpng
|
||||
|
||||
LIBEPLAYER3_LIBS = libeplayer3.la -lpthread -lavformat -lavcodec -lavutil -lswresample -lz -lass -lm -lpng
|
||||
bin_PROGRAMS = eplayer3 meta
|
||||
eplayer3_SOURCES = tools/eplayer2.c
|
||||
eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
|
||||
LIBEPLAYER3_LIBS = libeplayer3.la -lpthread -lavformat -lavcodec -lavutil -lswresample -lm
|
||||
bin_PROGRAMS = meta
|
||||
#eplayer3_SOURCES = tools/eplayer2.c
|
||||
#eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
|
||||
|
||||
meta_SOURCES = tools/meta.c
|
||||
meta_LDADD = $(LIBEPLAYER3_LIBS)
|
||||
|
@@ -130,15 +130,8 @@ static int Command(void *_context, ContainerCmd_t command, void *argument)
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern Container_t SrtContainer;
|
||||
extern Container_t SsaContainer;
|
||||
extern Container_t ASSContainer;
|
||||
|
||||
ContainerHandler_t ContainerHandler = {
|
||||
"Output",
|
||||
NULL,
|
||||
&SrtContainer,
|
||||
&SsaContainer,
|
||||
&ASSContainer,
|
||||
Command
|
||||
};
|
||||
|
@@ -63,7 +63,7 @@
|
||||
|
||||
#ifdef FFMPEG_DEBUG
|
||||
|
||||
static short debug_level = 10;
|
||||
static short debug_level = 0;
|
||||
|
||||
#define ffmpeg_printf(level, fmt, x...) do { \
|
||||
if (debug_level >= level) printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0)
|
||||
@@ -227,35 +227,6 @@ long long int calcPts(AVStream * stream, int64_t pts)
|
||||
return pts;
|
||||
}
|
||||
|
||||
/*Hellmaster1024: get the Duration of the subtitle from the SSA line*/
|
||||
float getDurationFromSSALine(unsigned char *line)
|
||||
{
|
||||
int i, h, m, s, ms;
|
||||
char *Text = strdup((char *) line);
|
||||
char *ptr1;
|
||||
char *ptr[10];
|
||||
long int msec;
|
||||
|
||||
ptr1 = Text;
|
||||
ptr[0] = Text;
|
||||
for (i = 0; i < 3 && *ptr1 != '\0'; ptr1++) {
|
||||
if (*ptr1 == ',') {
|
||||
ptr[++i] = ptr1 + 1;
|
||||
*ptr1 = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
sscanf(ptr[2], "%d:%d:%d.%d", &h, &m, &s, &ms);
|
||||
msec = (ms * 10) + (s * 1000) + (m * 60 * 1000) + (h * 24 * 60 * 1000);
|
||||
sscanf(ptr[1], "%d:%d:%d.%d", &h, &m, &s, &ms);
|
||||
msec -= (ms * 10) + (s * 1000) + (m * 60 * 1000) + (h * 24 * 60 * 1000);
|
||||
|
||||
ffmpeg_printf(10, "%s %s %f\n", ptr[2], ptr[1], (float) msec / 1000.0);
|
||||
|
||||
free(Text);
|
||||
return (float) msec / 1000.0;
|
||||
}
|
||||
|
||||
/* search for metadata in context and stream
|
||||
* and map it to our metadata.
|
||||
*/
|
||||
@@ -280,7 +251,10 @@ static char *searchMeta(AVDictionary * metadata, char *ourTag)
|
||||
/* Worker Thread */
|
||||
/* **************************** */
|
||||
|
||||
extern void (*dvbsubWrite)(AVSubtitle *, int64_t);
|
||||
// from neutrino-mp/lib/dvbsub.cpp
|
||||
extern void dvbsub_write(AVSubtitle *, int64_t);
|
||||
extern void dvbsub_ass_write(AVCodecContext *c, AVSubtitle *sub, int pid);
|
||||
extern void dvbsub_ass_clear(void);
|
||||
|
||||
static void FFMPEGThread(Context_t * context)
|
||||
{
|
||||
@@ -658,27 +632,6 @@ static void FFMPEGThread(Context_t * context)
|
||||
if ((pts > latestPts) && (!videoTrack) && (!audioTrack))
|
||||
latestPts = pts;
|
||||
|
||||
/*Hellmaster1024: in mkv the duration for ID_TEXT is stored in convergence_duration */
|
||||
ffmpeg_printf(20, "Packet duration %d\n", packet.duration);
|
||||
ffmpeg_printf(20, "Packet convergence_duration %lld\n", packet.convergence_duration);
|
||||
|
||||
if (packet.duration != 0) // FIXME: packet.duration is 32 bit, AV_NOPTS_VALUE is 64 bit --martii
|
||||
duration = ((float) packet.duration) / 1000.0;
|
||||
else if (packet.convergence_duration != 0 && packet.convergence_duration != AV_NOPTS_VALUE)
|
||||
duration = ((float) packet.convergence_duration) / 1000.0;
|
||||
else if (((AVStream *) subtitleTrack->stream)->codec->codec_id == AV_CODEC_ID_SSA) {
|
||||
/*Hellmaster1024 if the duration is not stored in packet.duration or
|
||||
packet.convergence_duration we need to calculate it any other way, for SSA it is stored in
|
||||
the Text line */
|
||||
duration = getDurationFromSSALine(packet_data);
|
||||
} else {
|
||||
/* no clue yet */
|
||||
}
|
||||
|
||||
/* konfetti: I've found cases where the duration from getDurationFromSSALine
|
||||
* is zero (start end and are really the same in text). I think it make's
|
||||
* no sense to pass those.
|
||||
*/
|
||||
if (duration > 0.0) {
|
||||
/* is there a decoder ? */
|
||||
if (((AVStream *) subtitleTrack->stream)->codec->codec) {
|
||||
@@ -687,68 +640,17 @@ static void FFMPEGThread(Context_t * context)
|
||||
|
||||
if (avcodec_decode_subtitle2(((AVStream *) subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) {
|
||||
ffmpeg_err("error decoding subtitle\n");
|
||||
} else {
|
||||
unsigned int i;
|
||||
|
||||
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(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 (got_sub_ptr && sub.num_rects > 0) {
|
||||
unsigned int i;
|
||||
switch (sub.rects[0]->type) {
|
||||
case SUBTITLE_TEXT: // FIXME?
|
||||
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);
|
||||
dvbsub_ass_write(((AVStream *) subtitleTrack->stream)->codec, &sub, pid);
|
||||
break;
|
||||
case SUBTITLE_BITMAP:
|
||||
ffmpeg_printf(0, "bitmap\n");
|
||||
if (dvbsubWrite)
|
||||
(*dvbsubWrite)(&sub, pts);
|
||||
dvbsub_write(&sub, pts);
|
||||
// avsubtitle_free() will be called by handler
|
||||
break;
|
||||
default:
|
||||
@@ -784,6 +686,8 @@ static void FFMPEGThread(Context_t * context)
|
||||
if (context && context->playback && context->output && context->playback->abortRequested)
|
||||
context->output->Command(context, OUTPUT_CLEAR, NULL);
|
||||
|
||||
dvbsub_ass_clear();
|
||||
|
||||
if (swr)
|
||||
swr_free(&swr);
|
||||
if (decoded_frame)
|
||||
@@ -813,6 +717,91 @@ static void log_callback(void *ptr __attribute__ ((unused)), int lvl __attribute
|
||||
vfprintf(stderr, format, ap);
|
||||
}
|
||||
|
||||
static void container_ffmpeg_read_subtitle(Context_t * context, const char *filename, const char *format, int pid) {
|
||||
fprintf(stderr, "%s %d\n", __func__, __LINE__);
|
||||
char *lastDot = strrchr(filename, '.');
|
||||
if (!lastDot)
|
||||
return;
|
||||
fprintf(stderr, "%s %d\n", __func__, __LINE__);
|
||||
char *subfile = alloca(strlen(filename) + strlen(format));
|
||||
strcpy(subfile, filename);
|
||||
strcpy(subfile + (lastDot + 1 - filename), format);
|
||||
fprintf(stderr, "%s %d\n", __func__, __LINE__);
|
||||
|
||||
AVFormatContext *avfc = avformat_alloc_context();
|
||||
fprintf(stderr, "%s %d: %s\n", __func__, __LINE__, subfile);
|
||||
if (avformat_open_input(&avfc, subfile, av_find_input_format(format), 0)) {
|
||||
avformat_free_context(avfc);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s %d\n", __func__, __LINE__);
|
||||
avformat_find_stream_info(avfc, NULL);
|
||||
if (avfc->nb_streams != 1) {
|
||||
avformat_free_context(avfc);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s %d\n", __func__, __LINE__);
|
||||
|
||||
AVCodecContext *c = avfc->streams[0]->codec;
|
||||
AVCodec *codec = avcodec_find_decoder(c->codec_id);
|
||||
if (!codec) {
|
||||
avformat_free_context(avfc);
|
||||
return;
|
||||
}
|
||||
|
||||
// fprintf(stderr, "codec=%s\n", avcodec_get_name(c->codec_id));
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "%s %d: avcodec_open\n", __FILE__, __LINE__);
|
||||
avformat_free_context(avfc);
|
||||
return;
|
||||
}
|
||||
AVSubtitle sub;
|
||||
AVPacket avpkt;
|
||||
av_init_packet(&avpkt);
|
||||
#if 0
|
||||
// FIXME, use custom values
|
||||
if (c->subtitle_header && !strcmp(format, "srt")) {
|
||||
av_freep(&c->subtitle_header);
|
||||
|
||||
#define ASS_DEFAULT_FONT "Arial"
|
||||
#define ASS_DEFAULT_FONT_SIZE 16
|
||||
#define ASS_DEFAULT_COLOR 0xffffff
|
||||
|
||||
ff_ass_subtitle_header(c, ASS_DEFAULT_FONT, ASS_DEFAULT_FONT_SIZE, ASS_DEFAULT_COLOR, 0, 0, 0, 0, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c->subtitle_header)
|
||||
fprintf(stderr, "%s\n", c->subtitle_header);
|
||||
|
||||
while (av_read_frame(avfc, &avpkt) > -1) {
|
||||
int got_sub = 0;
|
||||
avcodec_decode_subtitle2(c, &sub, &got_sub, &avpkt);
|
||||
if (got_sub)
|
||||
dvbsub_ass_write(c, &sub, pid);
|
||||
av_free_packet(&avpkt);
|
||||
}
|
||||
avformat_close_input(&avfc);
|
||||
avformat_free_context(avfc);
|
||||
|
||||
Track_t track;
|
||||
memset(&track, 0, sizeof(track));
|
||||
track.Name = (char *) format;
|
||||
track.is_static = 1;
|
||||
track.Id = pid;
|
||||
track.Encoding = strcmp(format, "srt") ? "S_TEXT/ASS" : "S_TEXT/SRT";
|
||||
context->manager->subtitle->Command(context, MANAGER_ADD, &track);
|
||||
}
|
||||
|
||||
static void container_ffmpeg_read_subtitles(Context_t * context, const char *filename) {
|
||||
if (strncmp(filename, "file://", 7))
|
||||
return;
|
||||
filename += 7;
|
||||
container_ffmpeg_read_subtitle(context, filename, "srt", 0xFFFF);
|
||||
container_ffmpeg_read_subtitle(context, filename, "ass", 0xFFFE);
|
||||
container_ffmpeg_read_subtitle(context, filename, "ssa", 0xFFFD);
|
||||
}
|
||||
|
||||
int container_ffmpeg_init(Context_t * context, char *filename)
|
||||
{
|
||||
int err;
|
||||
@@ -889,6 +878,7 @@ int container_ffmpeg_init(Context_t * context, char *filename)
|
||||
terminating = 0;
|
||||
latestPts = 0;
|
||||
int res = container_ffmpeg_update_tracks(context, filename);
|
||||
container_ffmpeg_read_subtitles(context, filename);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -983,16 +973,16 @@ int container_ffmpeg_update_tracks(Context_t * context, char *filename)
|
||||
else
|
||||
track.TimeScale = 1000;
|
||||
|
||||
ffmpeg_printf(10, "bit_rate = %d\n", stream->codec->bit_rate);
|
||||
ffmpeg_printf(10, "flags = %d\n", stream->codec->flags);
|
||||
ffmpeg_printf(10, "frame_bits = %d\n", stream->codec->frame_bits);
|
||||
ffmpeg_printf(10, "time_base.den %d\n", stream->time_base.den);
|
||||
ffmpeg_printf(10, "time_base.num %d\n", stream->time_base.num);
|
||||
ffmpeg_printf(10, "frame_rate %d\n", stream->r_frame_rate.num);
|
||||
ffmpeg_printf(10, "TimeScale %d\n", stream->r_frame_rate.den);
|
||||
ffmpeg_printf(20, "bit_rate = %d\n", stream->codec->bit_rate);
|
||||
ffmpeg_printf(20, "flags = %d\n", stream->codec->flags);
|
||||
ffmpeg_printf(20, "frame_bits = %d\n", stream->codec->frame_bits);
|
||||
ffmpeg_printf(20, "time_base.den %d\n", stream->time_base.den);
|
||||
ffmpeg_printf(20, "time_base.num %d\n", stream->time_base.num);
|
||||
ffmpeg_printf(20, "frame_rate %d\n", stream->r_frame_rate.num);
|
||||
ffmpeg_printf(20, "TimeScale %d\n", stream->r_frame_rate.den);
|
||||
|
||||
ffmpeg_printf(10, "frame_rate %d\n", track.frame_rate);
|
||||
ffmpeg_printf(10, "TimeScale %d\n", track.TimeScale);
|
||||
ffmpeg_printf(20, "frame_rate %d\n", track.frame_rate);
|
||||
ffmpeg_printf(20, "TimeScale %d\n", track.TimeScale);
|
||||
|
||||
track.Name = "und";
|
||||
track.Encoding = encoding;
|
||||
@@ -1234,17 +1224,10 @@ int container_ffmpeg_update_tracks(Context_t * context, char *filename)
|
||||
track.extraData = stream->codec->extradata;
|
||||
track.extraSize = stream->codec->extradata_size;
|
||||
|
||||
ffmpeg_printf(1, "subtitle codec %d\n", stream->codec->codec_id);
|
||||
ffmpeg_printf(1, "subtitle width %d\n", stream->codec->width);
|
||||
ffmpeg_printf(1, "subtitle height %d\n", stream->codec->height);
|
||||
ffmpeg_printf(1, "subtitle stream %p\n", stream);
|
||||
|
||||
if (stream->duration == AV_NOPTS_VALUE) {
|
||||
ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
|
||||
track.duration = (double) avContext->duration / 1000.0;
|
||||
} else {
|
||||
track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0;
|
||||
}
|
||||
ffmpeg_printf(10, "subtitle codec %d\n", stream->codec->codec_id);
|
||||
ffmpeg_printf(10, "subtitle width %d\n", stream->codec->width);
|
||||
ffmpeg_printf(10, "subtitle height %d\n", stream->codec->height);
|
||||
ffmpeg_printf(10, "subtitle stream %p\n", stream);
|
||||
|
||||
ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name);
|
||||
|
||||
|
@@ -37,10 +37,6 @@ extern Container_t FFMPEGContainer;
|
||||
typedef struct ContainerHandler_s {
|
||||
char *Name;
|
||||
Container_t *selectedContainer;
|
||||
Container_t *textSrtContainer;
|
||||
Container_t *textSsaContainer;
|
||||
Container_t *assContainer;
|
||||
|
||||
int (*Command) ( /*Context_t */ void *, ContainerCmd_t, void *);
|
||||
} ContainerHandler_t;
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if 0
|
||||
#define DEFAULT_ASS_HEAD "[Script Info]\n\
|
||||
Original Script: (c) 2008\n\
|
||||
ScriptType: v4.00\n\
|
||||
@@ -76,7 +77,6 @@ typedef enum {
|
||||
eSub_Txt
|
||||
} SubType_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int len;
|
||||
@@ -102,6 +102,7 @@ typedef struct {
|
||||
SubGfx_t gfx;
|
||||
} u;
|
||||
} SubtitleOut_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
@@ -115,13 +116,9 @@ typedef struct {
|
||||
} SubtitleData_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t *destination;
|
||||
unsigned int screen_width;
|
||||
unsigned int screen_height;
|
||||
unsigned int destStride;
|
||||
|
||||
void (*framebufferBlit) (void);
|
||||
void (*dvbsubWrite) (void *, int64_t);
|
||||
void (*dvbsubAssWrite)(void /*AVCodecContext*/ *c, void /*AVSubtitle*/ *sub, int pid);
|
||||
void (*dvbsubAssClear) (void);
|
||||
} SubtitleOutputDef_t;
|
||||
|
||||
#endif
|
||||
|
@@ -20,24 +20,6 @@ typedef struct {
|
||||
unsigned char Version;
|
||||
} WriterAVCallData_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
unsigned int Width;
|
||||
unsigned int Height;
|
||||
unsigned int Stride;
|
||||
unsigned int color;
|
||||
|
||||
unsigned int x; /* dst x ->given by ass */
|
||||
unsigned int y; /* dst y ->given by ass */
|
||||
|
||||
/* destination values if we use a shared framebuffer */
|
||||
int fd;
|
||||
unsigned int Screen_Width;
|
||||
unsigned int Screen_Height;
|
||||
uint32_t *destination;
|
||||
unsigned int destStride;
|
||||
} WriterFBCallData_t;
|
||||
|
||||
typedef struct WriterCaps_s {
|
||||
char *name;
|
||||
eWriterType_t type;
|
||||
@@ -75,7 +57,6 @@ extern Writer_t WriterVideoMSCOMP;
|
||||
extern Writer_t WriterVideoH263;
|
||||
extern Writer_t WriterVideoFLV;
|
||||
extern Writer_t WriterVideoVC1;
|
||||
extern Writer_t WriterFramebuffer;
|
||||
extern Writer_t WriterPipe;
|
||||
extern Writer_t WriterDVBSubtitle;
|
||||
|
||||
|
@@ -65,7 +65,6 @@ static const char *FILENAME = "output.c";
|
||||
|
||||
static Output_t *AvailableOutput[] = {
|
||||
&LinuxDvbOutput,
|
||||
&SubtitleOutput,
|
||||
&PipeOutput,
|
||||
NULL
|
||||
};
|
||||
@@ -115,10 +114,6 @@ static void OutputAdd(Context_t * context, char *port)
|
||||
context->output->video = AvailableOutput[i];
|
||||
return;
|
||||
}
|
||||
if (!strcmp("subtitle", port)) {
|
||||
context->output->subtitle = AvailableOutput[i];
|
||||
return;
|
||||
}
|
||||
if (!strcmp("teletext", port)) {
|
||||
context->output->teletext = AvailableOutput[i];
|
||||
return;
|
||||
@@ -134,8 +129,6 @@ static void OutputDel(Context_t * context, char *port)
|
||||
context->output->audio = NULL;
|
||||
else if (!strcmp("video", port))
|
||||
context->output->video = NULL;
|
||||
else if (!strcmp("subtitle", port))
|
||||
context->output->subtitle = NULL;
|
||||
else if (!strcmp("teletext", port))
|
||||
context->output->teletext = NULL;
|
||||
|
||||
@@ -162,11 +155,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_OPEN,
|
||||
"audio");
|
||||
if (context->playback->isSubtitle)
|
||||
ret |=
|
||||
context->output->subtitle->Command(context,
|
||||
OUTPUT_OPEN,
|
||||
"subtitle");
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -188,11 +176,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_CLOSE,
|
||||
"audio");
|
||||
if (context->playback->isSubtitle)
|
||||
ret |=
|
||||
context->output->subtitle->Command(context,
|
||||
OUTPUT_CLOSE,
|
||||
"subtitle");
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -229,13 +212,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
OUTPUT_PLAY,
|
||||
"audio");
|
||||
|
||||
if (!ret) { // success or not executed, dunn care
|
||||
if (context->playback->isSubtitle)
|
||||
ret =
|
||||
context->output->subtitle->Command(context,
|
||||
OUTPUT_PLAY,
|
||||
"subtitle");
|
||||
}
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -258,11 +234,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_STOP,
|
||||
"audio");
|
||||
if (context->playback->isSubtitle)
|
||||
ret |=
|
||||
context->output->subtitle->Command(context,
|
||||
OUTPUT_STOP,
|
||||
"subtitle");
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -284,8 +255,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_FLUSH,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle)
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
@@ -302,8 +271,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_PAUSE,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle)
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
@@ -320,8 +287,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_FASTFORWARD,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle)
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
@@ -354,8 +319,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_CONTINUE,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle)
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -391,8 +354,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_CLEAR,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
|
||||
if (context->playback->isTeletext)
|
||||
ret |=
|
||||
context->output->teletext->Command(context,
|
||||
@@ -412,8 +373,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
return context->output->audio->Command(context,
|
||||
OUTPUT_PTS,
|
||||
argument);
|
||||
//if (context->playback->isSubtitle)
|
||||
// return context->output->subtitle->Command(context, OUTPUT_PTS, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
@@ -449,8 +408,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
context->output->audio->Command(context,
|
||||
OUTPUT_SLOWMOTION,
|
||||
"audio");
|
||||
//if (context->playback->isSubtitle)
|
||||
// ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
@@ -487,8 +444,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
return context->output->audio->Command(context,
|
||||
OUTPUT_GET_FRAME_COUNT,
|
||||
argument);
|
||||
//if (context->playback->isSubtitle)
|
||||
// return context->output->subtitle->Command(context, OUTPUT_GET_FRAME_COUNT, "subtitle");
|
||||
} else
|
||||
ret = cERR_OUTPUT_INTERNAL_ERROR;
|
||||
break;
|
||||
|
@@ -105,12 +105,10 @@ static int readPointer = 0;
|
||||
static int writePointer = 0;
|
||||
static int hasThreadStarted = 0;
|
||||
static int isSubtitleOpened = 0;
|
||||
static int screen_width = 0;
|
||||
static int screen_height = 0;
|
||||
static int destStride = 0;
|
||||
static void (*framebufferBlit) = NULL;
|
||||
static uint32_t *destination = NULL;
|
||||
void (*dvbsubWrite)(AVSubtitle *, int64_t) = NULL;
|
||||
void (*dvbsubAssWrite)(AVCodecContext *, AVSubtitle *, int) = NULL;
|
||||
void (*dvbsubAssClear)(void) = NULL;
|
||||
|
||||
|
||||
/* ***************************** */
|
||||
/* Prototypes */
|
||||
@@ -784,22 +782,16 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
}
|
||||
case OUTPUT_GET_SUBTITLE_OUTPUT:{
|
||||
SubtitleOutputDef_t *out = (SubtitleOutputDef_t *) 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;
|
||||
out->dvbsubAssWrite = (void (*)(void *, void *, int))dvbsubAssWrite;
|
||||
out->dvbsubAssClear = (void (*)(void))dvbsubAssClear;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_SET_SUBTITLE_OUTPUT:{
|
||||
SubtitleOutputDef_t *out = (SubtitleOutputDef_t *) 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;
|
||||
dvbsubAssWrite = (void (*)(AVCodecContext *, AVSubtitle *, int))out->dvbsubAssWrite;
|
||||
dvbsubAssClear = (void (*)(void))out->dvbsubAssClear;
|
||||
break;
|
||||
}
|
||||
case OUTPUT_SUBTITLE_REGISTER_FUNCTION:{
|
||||
@@ -825,7 +817,6 @@ static int Command(void *_context, OutputCmd_t command, void *argument)
|
||||
ret = cERR_SUBTITLE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
subtitle_err("OutputCmd %d not supported!\n", command);
|
||||
ret = cERR_SUBTITLE_ERROR;
|
||||
|
@@ -81,7 +81,6 @@ static Writer_t *AvailableWriter[] = {
|
||||
&WriterVideoH263,
|
||||
&WriterVideoFLV,
|
||||
&WriterVideoVC1,
|
||||
&WriterFramebuffer,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@@ -126,25 +126,6 @@ static int PlaybackOpen(Context_t * context, char *uri)
|
||||
extension = getExtension(context->playback->uri + 7);
|
||||
if (!extension)
|
||||
return cERR_PLAYBACK_ERROR;
|
||||
|
||||
//CHECK FOR SUBTITLES
|
||||
if (context->container && context->container->textSrtContainer)
|
||||
context->container->textSrtContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
context->playback->
|
||||
uri + 7);
|
||||
|
||||
if (context->container && context->container->textSsaContainer)
|
||||
context->container->textSsaContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
context->playback->
|
||||
uri + 7);
|
||||
|
||||
if (context->container && context->container->assContainer)
|
||||
context->container->assContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
NULL);
|
||||
|
||||
} else if (strstr(uri, "://")) {
|
||||
context->playback->isHttp = 1;
|
||||
extension = "mp3";
|
||||
@@ -184,14 +165,6 @@ static int PlaybackClose(Context_t * context)
|
||||
playback_err("container delete failed\n");
|
||||
}
|
||||
|
||||
if (context->container && context->container->textSrtContainer)
|
||||
context->container->textSrtContainer->Command(context,
|
||||
CONTAINER_DEL, NULL);
|
||||
|
||||
if (context->container && context->container->textSsaContainer)
|
||||
context->container->textSsaContainer->Command(context,
|
||||
CONTAINER_DEL, NULL);
|
||||
|
||||
context->manager->audio->Command(context, MANAGER_DEL, NULL);
|
||||
context->manager->video->Command(context, MANAGER_DEL, NULL);
|
||||
context->manager->subtitle->Command(context, MANAGER_DEL, NULL);
|
||||
@@ -726,56 +699,7 @@ static int PlaybackSwitchSubtitle(Context_t * context, int *track)
|
||||
playback_err("manager set track failed\n");
|
||||
}
|
||||
|
||||
if (*track < 0 && !strcmp(context->playback->uri, "file://")) {
|
||||
//CHECK FOR SUBTITLES
|
||||
if (context->container
|
||||
&& context->container->textSrtContainer)
|
||||
context->container->textSrtContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
context->playback->uri
|
||||
+ 7);
|
||||
|
||||
if (context->container
|
||||
&& context->container->textSsaContainer)
|
||||
context->container->textSsaContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
context->playback->uri
|
||||
+ 7);
|
||||
|
||||
if (context->container && context->container->assContainer)
|
||||
context->container->assContainer->Command(context,
|
||||
CONTAINER_INIT,
|
||||
NULL);
|
||||
}
|
||||
|
||||
context->manager->subtitle->Command(context, MANAGER_GET,
|
||||
&trackid);
|
||||
|
||||
/* konfetti: I make this hack a little bit nicer,
|
||||
* but its still a hack in my opinion ;)
|
||||
*/
|
||||
if (context->container && context->container->assContainer)
|
||||
context->container->assContainer->Command(context,
|
||||
CONTAINER_SWITCH_SUBTITLE,
|
||||
&trackid);
|
||||
|
||||
if (trackid >= TEXTSRTOFFSET) {
|
||||
if (context->container
|
||||
&& context->container->textSrtContainer)
|
||||
context->container->textSrtContainer->Command(context,
|
||||
CONTAINER_SWITCH_SUBTITLE,
|
||||
&trackid);
|
||||
}
|
||||
if (trackid >= TEXTSSAOFFSET) {
|
||||
if (context->container
|
||||
&& context->container->textSsaContainer)
|
||||
context->container->textSsaContainer->Command(context,
|
||||
CONTAINER_SWITCH_SUBTITLE,
|
||||
&trackid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
context->manager->subtitle->Command(context, MANAGER_GET, &trackid);
|
||||
} else {
|
||||
ret = cERR_PLAYBACK_ERROR;
|
||||
playback_err("no subtitle\n");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
noinst_LTLIBRARIES = libspark.la
|
||||
|
||||
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
|
||||
AM_CPPFLAGS = \
|
||||
AM_CPPFLAGS += \
|
||||
-I$(top_srcdir)/common \
|
||||
-I$(top_srcdir)/libeplayer3/include
|
||||
|
||||
|
@@ -67,15 +67,7 @@ bool cPlayback::Open(playmode_t PlayMode)
|
||||
if(player && player->output) {
|
||||
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*)"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, &so.dvbsubWrite);
|
||||
player->output->subtitle->Command(player, OUTPUT_SET_SUBTITLE_OUTPUT, (void*)&so);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -686,11 +678,10 @@ 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), void (**)(void *, int64_t)))
|
||||
cPlayback::cPlayback(int num __attribute__((unused)))
|
||||
{
|
||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||
playing=false;
|
||||
framebuffer_callback = fbcb;
|
||||
}
|
||||
|
||||
cPlayback::~cPlayback()
|
||||
|
@@ -18,10 +18,9 @@ class cPlayback
|
||||
int mAudioStream;
|
||||
int mSubtitleStream;
|
||||
int mTeletextStream;
|
||||
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), void (**)(void *, int64_t)) = NULL);
|
||||
cPlayback(int num = 0);
|
||||
~cPlayback();
|
||||
|
||||
bool Open(playmode_t PlayMode);
|
||||
|
Reference in New Issue
Block a user