summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-05-17 23:47:27 +0000
committeralbeu <albeu@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-05-17 23:47:27 +0000
commit7562937d959ec617d4f78fd6d06aed7164b22255 (patch)
treecb02ee86d7cd802d4e20e0f077e07b57b9c188b0
parent517a1ee64f4c6caf9b542bdf18f2a95c5298a3e0 (diff)
downloadmpv-7562937d959ec617d4f78fd6d06aed7164b22255.tar.bz2
mpv-7562937d959ec617d4f78fd6d06aed7164b22255.tar.xz
Improvment for spu subtitles.
Removed the integreted spudec in vobsub. Various cleanup/bugfix in vobsub (no more auto palette when a true one is here) HW spu rendering moved in spudec because we first need to reassable the packet before sending them to the hw. Spudec is now created only if nedded. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6111 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--libvo/sub.c12
-rw-r--r--libvo/sub.h1
-rw-r--r--libvo/video_out.h1
-rw-r--r--mencoder.c2
-rw-r--r--mp_msg.h2
-rw-r--r--mplayer.c95
-rw-r--r--spudec.c63
-rw-r--r--spudec.h5
-rw-r--r--vobsub.c160
-rw-r--r--vobsub.h8
10 files changed, 191 insertions, 158 deletions
diff --git a/libvo/sub.c b/libvo/sub.c
index 00780cf7ce..5e44238121 100644
--- a/libvo/sub.c
+++ b/libvo/sub.c
@@ -390,12 +390,6 @@ int vo_update_osd(int dxs,int dys){
else
obj->flags&=~OSDFLAG_VISIBLE;
break;
- case OSDTYPE_VOBSUB:
- if(vo_vobsub)
- obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED;
- else
- obj->flags&=~OSDFLAG_VISIBLE;
- break;
case OSDTYPE_OSD:
if(vo_font && vo_osd_text && vo_osd_text[0]){
vo_update_text_osd(obj,dxs,dys); // update bbox
@@ -443,13 +437,12 @@ void vo_init_osd(){
draw_alpha_init_flag=1;
vo_draw_alpha_init();
}
- if(vo_osd_list) free_osd_list;
+ if(vo_osd_list) free_osd_list();
// temp hack, should be moved to mplayer/mencoder later
new_osd_obj(OSDTYPE_OSD);
new_osd_obj(OSDTYPE_SUBTITLE);
new_osd_obj(OSDTYPE_PROGBAR);
new_osd_obj(OSDTYPE_SPU);
- new_osd_obj(OSDTYPE_VOBSUB);
}
int vo_osd_changed_flag=0;
@@ -482,9 +475,6 @@ void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h,
case OSDTYPE_SPU:
spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); // FIXME
break;
- case OSDTYPE_VOBSUB:
- vobsub_draw(vo_vobsub, dxs, dys, draw_alpha); // FIXME
- break;
case OSDTYPE_OSD:
vo_draw_text_osd(obj,draw_alpha);
break;
diff --git a/libvo/sub.h b/libvo/sub.h
index 21482eea80..c15a2a99d0 100644
--- a/libvo/sub.h
+++ b/libvo/sub.h
@@ -10,7 +10,6 @@ typedef struct mp_osd_bbox_s {
#define OSDTYPE_SUBTITLE 2
#define OSDTYPE_PROGBAR 3
#define OSDTYPE_SPU 4
-#define OSDTYPE_VOBSUB 5
#define OSDFLAG_VISIBLE 1
#define OSDFLAG_CHANGED 2
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 62b20a3a60..1490048c72 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -39,6 +39,7 @@
/* libmpcodecs direct rendering: */
#define VOCTRL_GET_IMAGE 9
#define VOCTRL_DRAW_IMAGE 13
+#define VOCTRL_SET_SPU_PALETTE 14
/* decoding ahead: */
#define VOCTRL_GET_NUM_FRAMES 10
#define VOCTRL_GET_FRAME_NUM 11
diff --git a/mencoder.c b/mencoder.c
index 3efac12a0d..a5440f28c1 100644
--- a/mencoder.c
+++ b/mencoder.c
@@ -508,7 +508,7 @@ if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf)){
if (spudec_ifo) {
unsigned int palette[16], width, height;
- if (vobsub_parse_ifo(spudec_ifo, palette, &width, &height, 1) >= 0)
+ if (vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1) >= 0)
vo_spudec=spudec_new_scaled(palette, sh_video->disp_w, sh_video->disp_h);
}
#ifdef USE_DVDREAD
diff --git a/mp_msg.h b/mp_msg.h
index 1809455a13..db149c64f8 100644
--- a/mp_msg.h
+++ b/mp_msg.h
@@ -78,6 +78,8 @@ extern int verbose; // defined in mplayer.c
#define MSGT_SWS 34
+#define MSGT_VOBSUB 35
+
#define MSGT_MAX 64
void mp_msg_init();
diff --git a/mplayer.c b/mplayer.c
index 9b9c38afa2..e670d24e07 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -279,6 +279,7 @@ static unsigned int inited_flags=0;
#define INITED_SPUDEC 32
#define INITED_STREAM 64
#define INITED_INPUT 128
+#define INITED_VOBSUB 256
#define INITED_ALL 0xFFFF
void uninit_player(unsigned int mask){
@@ -310,6 +311,13 @@ void uninit_player(unsigned int mask){
getch2_disable();
}
+ if(mask&INITED_VOBSUB){
+ inited_flags&=~INITED_VOBSUB;
+ current_module="uninit_vobsub";
+ vobsub_close(vo_vobsub);
+ vo_vobsub=NULL;
+ }
+
if (mask&INITED_SPUDEC){
inited_flags&=~INITED_SPUDEC;
current_module="uninit_spudec";
@@ -854,7 +862,7 @@ if(!use_stdin && !slave_mode){
current_module="vobsub";
if (vobsub_name){
- vo_vobsub=vobsub_open(vobsub_name,1);
+ vo_vobsub=vobsub_open(vobsub_name,spudec_ifo,1,&vo_spudec);
if(vo_vobsub==NULL)
mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadSub,vobsub_name);
}else if(sub_auto && filename && (strlen(filename)>=5)){
@@ -862,7 +870,7 @@ if(!use_stdin && !slave_mode){
char *buf = malloc((strlen(filename)-3) * sizeof(char));
memset(buf,0,strlen(filename)-3); // make sure string is terminated
strncpy(buf, filename, strlen(filename)-4);
- vo_vobsub=vobsub_open(buf,0);
+ vo_vobsub=vobsub_open(buf,spudec_ifo,0,&vo_spudec);
free(buf);
}
if(vo_vobsub)
@@ -1149,12 +1157,12 @@ if(!sh_video && !sh_audio){
demux_info_print(demuxer);
//================== Read SUBTITLES (DVD & TEXT) ==========================
-if(sh_video){
+if(d_dvdsub->id >= 0 && vo_spudec==NULL && sh_video){
if (spudec_ifo) {
unsigned int palette[16], width, height;
current_module="spudec_init_vobsub";
- if (vobsub_parse_ifo(spudec_ifo, palette, &width, &height, 1) >= 0)
+ if (vobsub_parse_ifo(NULL,spudec_ifo, palette, &width, &height, 1) >= 0)
vo_spudec=spudec_new_scaled(palette, sh_video->disp_w, sh_video->disp_h);
}
@@ -1177,13 +1185,16 @@ if (vo_spudec==NULL && stream->type==STREAMTYPE_DVD) {
if (vo_spudec==NULL) {
current_module="spudec_init_normal";
vo_spudec=spudec_new_scaled(NULL, sh_video->disp_w, sh_video->disp_h);
- spudec_set_font_factor(font_factor);
+ spudec_set_font_factor(vo_spudec,font_factor);
}
if (vo_spudec!=NULL)
inited_flags|=INITED_SPUDEC;
+}
+
#ifdef USE_SUB
+if(sh_video) {
// after reading video params we should load subtitles because
// we know fps so now we can adjust subtitles time to ~6 seconds AST
// check .sub
@@ -1198,9 +1209,9 @@ if (vo_spudec!=NULL)
}
if(subtitles && stream_dump_type==3) list_sub_file(subtitles);
if(subtitles && stream_dump_type==4) dump_mpsub(subtitles, sh_video->fps);
-#endif
-
}
+#endif
+
//================== Init AUDIO (codec) ==========================
current_module="find_audio_codec";
@@ -1335,6 +1346,9 @@ current_module="init_vo_vaa";
}
}
+ if(vo_flags & 0x08 && vo_spudec)
+ spudec_set_hw_spu(vo_spudec,video_out);
+
//================== MAIN: ==========================
main:
if(!sh_video) osd_level = 0;
@@ -2896,43 +2910,44 @@ if(rel_seek_secs || abs_seek_pos){
}
#endif
-
- // VobSub subtitles
- if(vo_vobsub){
- current_module="vobsub";
- if(d_video->pts+sub_delay>=0)
- vobsub_process(vo_vobsub,d_video->pts+sub_delay);
-
- /* Don't know how to detect wether the sub has changed or not */
- vo_osd_changed(OSDTYPE_VOBSUB);
- current_module=NULL;
- }
-
// DVD sub:
- if(vo_flags & 0x08){
- static vo_mpegpes_t packet;
- static vo_mpegpes_t *pkg=&packet;
- packet.timestamp=sh_video->timer*90000.0;
- packet.id=0x20; /* Subpic */
- while((packet.size=ds_get_packet_sub(d_dvdsub,&packet.data))>0){
- mp_msg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d v_pts=%5.3f s_pts=%5.3f \n",packet.size,d_video->pts,d_dvdsub->pts);
- if(vo_config_count) video_out->draw_frame(&pkg);
- }
- }else if(vo_spudec){
- unsigned char* packet=NULL;
- int len;
- current_module="spudec";
- while((len=ds_get_packet_sub(d_dvdsub,&packet))>0){
- mp_msg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d v_pts=%5.3f s_pts=%5.3f \n",len,d_video->pts,d_dvdsub->pts);
- spudec_assemble(vo_spudec,packet,len,90000*d_dvdsub->pts);
+if(vo_config_count && vo_spudec) {
+ unsigned char* packet=NULL;
+ int len,timestamp;
+ // Get a sub packet from the dvd or a vobsub and make a timestamp relative to sh_video->timer
+ int get_sub_packet(void) {
+ // Vobsub
+ len = 0;
+ if(vo_vobsub) {
+ if(d_video->pts+sub_delay>=0) {
+ // The + next_frame_time is there because we'll display the sub at the next frame
+ len = vobsub_get_packet(vo_vobsub,d_video->pts+sub_delay+next_frame_time,(void**)&packet,&timestamp);
+ if(len > 0) {
+ timestamp -= (d_video->pts + sub_delay - sh_video->timer)*90000;
+ mp_dbg(MSGT_CPLAYER,MSGL_V,"\rVOB sub: len=%d v_pts=%5.3f v_timer=%5.3f sub=%5.3f ts=%d \n",len,d_video->pts,sh_video->timer,timestamp / 90000.0);
+ }
+ }
+ } else {
+ // DVD sub
+ len = ds_get_packet_sub(d_dvdsub,(unsigned char**)&packet);
+ if(len > 0) {
+ timestamp = 90000*(sh_video->timer + d_dvdsub->pts + sub_delay - d_video->pts);
+ mp_dbg(MSGT_CPLAYER,MSGL_V,"\rDVD sub: len=%d v_pts=%5.3f s_pts=%5.3f ts=%d \n",len,d_video->pts,d_dvdsub->pts,timestamp);
+ }
}
- spudec_heartbeat(vo_spudec,90000*d_video->pts);
-
- /* Don't know how to detect wether the sub has changed or not */
- vo_osd_changed(OSDTYPE_SPU);
- current_module=NULL;
+ return len;
+ }
+ current_module="spudec";
+ spudec_heartbeat(vo_spudec,90000*sh_video->timer);
+ while(get_sub_packet()>0 && packet){
+ spudec_assemble(vo_spudec,packet,len,timestamp);
}
+ /* Don't know how to detect wether the sub has changed or not */
+ vo_osd_changed(OSDTYPE_SPU);
+ current_module=NULL;
+}
+
} // while(!eof)
mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d \n",eof);
diff --git a/spudec.c b/spudec.c
index 58cfba0443..887bb37a3e 100644
--- a/spudec.c
+++ b/spudec.c
@@ -29,6 +29,7 @@
#if ANTIALIASING_ALGORITHM == 2
#include <math.h>
#endif
+#include "libvo/video_out.h"
#include "spudec.h"
#define MIN(a, b) ((a)<(b)?(a):(b))
@@ -63,12 +64,11 @@ typedef struct {
size_t scaled_image_size;
unsigned char *scaled_image;
unsigned char *scaled_aimage;
+ int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
+ int font_start_level; /* Darkest value used for the computed font */
+ vo_functions_t *hw_spu;
} spudec_handle_t;
-/* 1 if we lack a palette and must use an heuristic. */
-static int auto_palette = 0;
-/* Darkest value used for the computed font */
-static int font_start_level = 0;
static inline unsigned int get_be16(const unsigned char *p)
{
@@ -219,8 +219,8 @@ static void compute_palette(spudec_handle_t *this)
start = 0x80;
step = 0;
} else {
- start = font_start_level;
- step = (0xF0-font_start_level)/(cused-1);
+ start = this->font_start_level;
+ step = (0xF0-this->font_start_level)/(cused-1);
}
memset(used, 0, sizeof(used));
for (i=0; i<4; i++) {
@@ -286,7 +286,10 @@ static void spudec_process_control(spudec_handle_t *this, unsigned int pts100)
this->alpha[1] = this->packet[off] & 0xf;
this->alpha[2] = this->packet[off + 1] >> 4;
this->alpha[3] = this->packet[off + 1] & 0xf;
- if (auto_palette) compute_palette(this);
+ if (this->auto_palette) {
+ compute_palette(this);
+ this->auto_palette = 0;
+ }
mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Alpha %d, %d, %d, %d\n",
this->alpha[0], this->alpha[1], this->alpha[2], this->alpha[3]);
off+=2;
@@ -333,8 +336,17 @@ static void spudec_process_control(spudec_handle_t *this, unsigned int pts100)
static void spudec_decode(spudec_handle_t *this, unsigned int pts100)
{
- spudec_process_control(this, pts100);
- spudec_process_data(this);
+ if(this->hw_spu) {
+ static vo_mpegpes_t packet = { NULL, 0, 0x20, 0 };
+ static vo_mpegpes_t *pkg=&packet;
+ packet.data = this->packet;
+ packet.size = this->packet_size;
+ packet.timestamp = pts100;
+ this->hw_spu->draw_frame((uint8_t**)&pkg);
+ } else {
+ spudec_process_control(this, pts100);
+ spudec_process_data(this);
+ }
}
@@ -721,13 +733,17 @@ void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*dra
void spudec_update_palette(void * this, unsigned int *palette)
{
spudec_handle_t *spu = (spudec_handle_t *) this;
- if (spu && palette)
+ if (spu && palette) {
memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
+ if(spu->hw_spu)
+ spu->hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+ }
}
-void spudec_set_font_factor(double factor)
+void spudec_set_font_factor(void * this, double factor)
{
- font_start_level = (int)(0xF0-(0xE0*factor));
+ spudec_handle_t *spu = (spudec_handle_t *) this;
+ spu->font_start_level = (int)(0xF0-(0xE0*factor));
}
void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height)
@@ -736,11 +752,11 @@ void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigne
if (this) {
if (palette) {
memcpy(this->global_palette, palette, sizeof(this->global_palette));
- auto_palette = 0;
+ this->auto_palette = 0;
}
else {
/* No palette, compute one */
- auto_palette = 1;
+ this->auto_palette = 1;
}
this->packet = NULL;
this->image = NULL;
@@ -749,7 +765,7 @@ void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigne
this->orig_frame_height = frame_height;
}
else
- perror("FATAL: spudec_init: calloc");
+ mp_msg(MSGT_SPUDEC,MSGL_FATAL, "FATAL: spudec_init: calloc");
return this;
}
@@ -766,19 +782,19 @@ void *spudec_new_scaled_vobsub(unsigned int *palette, unsigned int *cuspal, unsi
this->orig_frame_height = frame_height;
this->custom = custom;
// set up palette:
- auto_palette = 1;
+ this->auto_palette = 1;
if (palette){
memcpy(this->global_palette, palette, sizeof(this->global_palette));
- auto_palette = 0;
+ this->auto_palette = 0;
}
this->custom = custom;
if (custom && cuspal) {
memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
- auto_palette = 0;
+ this->auto_palette = 0;
}
}
else
- perror("FATAL: spudec_init: calloc");
+ mp_msg(MSGT_SPUDEC,MSGL_FATAL, "FATAL: spudec_init: calloc");
return this;
}
@@ -800,3 +816,12 @@ void spudec_free(void *this)
free(spu);
}
}
+
+void spudec_set_hw_spu(void *this, vo_functions_t *hw_spu)
+{
+ spudec_handle_t *spu = (spudec_handle_t*)this;
+ if (!spu)
+ return;
+ spu->hw_spu = hw_spu;
+ hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
+}
diff --git a/spudec.h b/spudec.h
index 81ce6013da..5cea2330df 100644
--- a/spudec.h
+++ b/spudec.h
@@ -7,11 +7,12 @@ void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsi
void spudec_draw_scaled(void *this, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
void spudec_update_palette(void *this, unsigned int *palette);
void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height);
+void *spudec_new_scaled_vobsub(unsigned int *palette, unsigned int *cuspal, unsigned int custom, unsigned int frame_width, unsigned int frame_height);
void *spudec_new(unsigned int *palette);
void spudec_free(void *this);
void spudec_reset(void *this); // called after seek
int spudec_visible(void *this); // check if spu is visible
-void spudec_set_font_factor(double factor); // sets the equivalent to ffactor
-
+void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor
+void spudec_set_hw_spu(void *this, vo_functions_t *hw_spu);
#endif
diff --git a/vobsub.c b/vobsub.c
index 138cbf0071..2f90338938 100644
--- a/vobsub.c
+++ b/vobsub.c
@@ -17,6 +17,7 @@
#include "stream.h"
#include "vobsub.h"
+#include "libvo/video_out.h"
#include "spudec.h"
#include "mp_msg.h"
@@ -165,7 +166,7 @@ mpeg_run(mpeg_t *mpeg)
else if ((c & 0xf0) == 0x20)
version = 2;
else {
- fprintf(stderr, "Unsupported MPEG version: 0x%02x", c);
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Unsupported MPEG version: 0x%02x", c);
return -1;
}
if (version == 4) {
@@ -214,7 +215,7 @@ mpeg_run(mpeg_t *mpeg)
hdrlen = c;
dataidx = mpeg_tell(mpeg) + hdrlen;
if (dataidx > idx + len) {
- fprintf(stderr, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n",
hdrlen, len, idx, dataidx);
return -1;
}
@@ -222,7 +223,7 @@ mpeg_run(mpeg_t *mpeg)
if (stream_read(mpeg->stream, buf, 5) != 5)
return -1;
if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) && (buf[4] & 1))) {
- fprintf(stderr, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n",
buf[0], buf[1], buf[2], buf[3], buf[4]);
mpeg->pts = 0;
}
@@ -237,7 +238,7 @@ mpeg_run(mpeg_t *mpeg)
stream_seek(mpeg->stream, dataidx);
mpeg->aid = stream_read_char(mpeg->stream);
if (mpeg->aid < 0) {
- fprintf(stderr, "Bogus aid %d\n", mpeg->aid);
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bogus aid %d\n", mpeg->aid);
return -1;
}
mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx);
@@ -249,13 +250,13 @@ mpeg_run(mpeg_t *mpeg)
mpeg->packet_reserve = mpeg->packet_size;
}
if (mpeg->packet == NULL) {
- perror("malloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
mpeg->packet_reserve = 0;
mpeg->packet_size = 0;
return -1;
}
- if (stream_read(mpeg->stream, mpeg->packet, mpeg->packet_size) != mpeg->packet_size) {
- perror("stream_read failure");
+ if ((unsigned int)stream_read(mpeg->stream, mpeg->packet, mpeg->packet_size) != mpeg->packet_size) {
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"stream_read failure");
mpeg->packet_size = 0;
return -1;
}
@@ -280,7 +281,7 @@ mpeg_run(mpeg_t *mpeg)
}
else {
- fprintf(stderr, "unknown header 0x%02X%02X%02X%02X\n",
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"unknown header 0x%02X%02X%02X%02X\n",
buf[0], buf[1], buf[2], buf[3]);
return -1;
}
@@ -353,7 +354,7 @@ packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
if (queue->packets) {
packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t));
if (tmp == NULL) {
- perror("realloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_FATAL,"realloc failure");
return -1;
}
queue->packets = tmp;
@@ -362,7 +363,7 @@ packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size)
else {
queue->packets = malloc(sizeof(packet_t));
if (queue->packets == NULL) {
- perror("malloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");
return -1;
}
queue->packets_reserve = 1;
@@ -407,7 +408,6 @@ packet_queue_insert(packet_queue_t *queue)
**********************************************************************/
typedef struct {
- void *spudec;
unsigned int palette[16];
unsigned int cuspal[4];
int delay;
@@ -430,7 +430,7 @@ vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
if (vob->spu_streams) {
packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t));
if (tmp == NULL) {
- perror("vobsub_ensure_spu_stream: realloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: realloc failure");
return -1;
}
vob->spu_streams = tmp;
@@ -438,7 +438,7 @@ vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index)
else {
vob->spu_streams = malloc((index + 1) * sizeof(packet_queue_t));
if (vob->spu_streams == NULL) {
- perror("vobsub_ensure_spu_stream: malloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: malloc failure");
return -1;
}
}
@@ -460,7 +460,7 @@ vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int in
free(vob->spu_streams[index].id);
vob->spu_streams[index].id = malloc(idlen + 1);
if (vob->spu_streams[index].id == NULL) {
- perror("vobsub_add_id: malloc failure");
+ mp_msg(MSGT_VOBSUB,MSGL_FATAL,"vobsub_add_id: malloc failure");
return -1;
}
vob->spu_streams[index].id[idlen] = 0;
@@ -468,7 +468,7 @@ vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int in
}
vob->spu_streams_current = index;
if (verbose)
- fprintf(stderr, "[vobsub] subtitle (vobsubid): %d language %s\n",
+ mp_msg(MSGT_VOBSUB,MSGL_V,"[vobsub] subtitle (vobsubid): %d language %s\n",
index, vob->spu_streams[index].id);
return 0;
}
@@ -479,7 +479,7 @@ vobsub_add_timestamp(vobsub_t *vob, off_t filepos, unsigned int ms)
packet_queue_t *queue;
packet_t *pkt;
if (vob->spu_streams == 0) {
- fprintf(stderr, "[vobsub] warning, binning some index entries. Check your index file\n");
+ mp_msg(MSGT_VOBSUB,MSGL_WARN,"[vobsub] warning, binning some index entries. Check your index file\n");
return -1;
}
queue = vob->spu_streams + vob->spu_streams_current;
@@ -676,13 +676,13 @@ vobsub_parse_cuspal(vobsub_t *vob, const char *line)
/* don't know how to use tridx */
static int
-vobsub_parse_tridx(vobsub_t *vob, const char *line)
+vobsub_parse_tridx(const char *line)
{
//tridx: XXXX
- int i;
int tridx;
tridx = strtoul((line + 26), NULL, 16);
tridx = ((tridx&0x1000)>>12) | ((tridx&0x100)>>7) | ((tridx&0x10)>>2) | ((tridx&1)<<3);
+ return tridx;
}
static int
@@ -698,21 +698,21 @@ vobsub_parse_delay(vobsub_t *vob, const char *line)
forward = -1;
line++;
}
- fprintf(stderr, "forward=%d", forward);
+ mp_msg(MSGT_SPUDEC,MSGL_V, "forward=%d", forward);
h = atoi(line + 7);
- fprintf(stderr, "h=%d," ,h);
+ mp_msg(MSGT_VOBSUB,MSGL_V, "h=%d," ,h);
m = atoi(line + 10);
- fprintf(stderr, "m=%d,", m);
+ mp_msg(MSGT_VOBSUB,MSGL_V, "m=%d,", m);
s = atoi(line + 13);
- fprintf(stderr, "s=%d,", s);
+ mp_msg(MSGT_VOBSUB,MSGL_V, "s=%d,", s);
ms = atoi(line + 16);
- fprintf(stderr, "ms=%d", ms);
+ mp_msg(MSGT_VOBSUB,MSGL_V, "ms=%d", ms);
vob->delay = ms + 1000 * (s + 60 * (m + 60 * h)) * forward;
return 0;
}
static int
-vobsub_set_lang(vobsub_t *vob, const char *line)
+vobsub_set_lang(const char *line)
{
if (vobsub_id == -1)
vobsub_id = atoi(line + 8);
@@ -736,7 +736,7 @@ vobsub_parse_one_line(vobsub_t *vob, FILE *fd)
if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#')
continue;
else if (strncmp("langidx:", line, 8) == 0)
- res = vobsub_set_lang(vob, line);
+ res = vobsub_set_lang(line);
else if (strncmp("delay:", line, 6) == 0)
res = vobsub_parse_delay(vob, line);
else if (strncmp("id:", line, 3) == 0)
@@ -751,36 +751,37 @@ vobsub_parse_one_line(vobsub_t *vob, FILE *fd)
res = vobsub_parse_timestamp(vob, line + 10);
else if (strncmp("custom colors:", line, 14) == 0)
//custom colors: ON/OFF, tridx: XXXX, colors: XXXXXX, XXXXXX, XXXXXX,XXXXXX
- res = vobsub_parse_cuspal(vob, line) + vobsub_parse_tridx(vob, line) + vobsub_parse_custom(vob, line);
+ res = vobsub_parse_cuspal(vob, line) + vobsub_parse_tridx(line) + vobsub_parse_custom(vob, line);
else {
if (verbose)
- fprintf(stderr, "vobsub: ignoring %s", line);
+ mp_msg(MSGT_VOBSUB,MSGL_V, "vobsub: ignoring %s", line);
continue;
}
if (res < 0)
- fprintf(stderr, "ERROR in %s", line);
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "ERROR in %s", line);
break;
} while (1);
return res;
}
int
-vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force)
+vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force)
{
+ vobsub_t *vob = (vobsub_t*)this;
int res = -1;
FILE *fd = fopen(name, "rb");
if (fd == NULL) {
if (force)
- perror("Can't open IFO file");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't open IFO file");
} else {
// parse IFO header
unsigned char block[0x800];
const char *const ifo_magic = "DVDVIDEO-VTS";
if (fread(block, sizeof(block), 1, fd) != 1) {
if (force)
- perror("Can't read IFO header");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO header");
} else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1))
- fprintf(stderr, "Bad magic in IFO header\n");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bad magic in IFO header\n");
else {
unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16
| block[0xce] << 8 | block[0xcf];
@@ -803,11 +804,11 @@ vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *wi
*height /= 2;
break;
default:
- fprintf(stderr, "Unknown resolution %d \n", resolution);
+ mp_msg(MSGT_VOBSUB,MSGL_WARN,"Vobsub: Unknown resolution %d \n", resolution);
}
if (fseek(fd, pgci_sector * sizeof(block), SEEK_SET)
|| fread(block, sizeof(block), 1, fd) != 1)
- perror("Can't read IFO PGCI");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO PGCI");
else {
unsigned long idx;
unsigned long pgc_offset = block[0xc] << 24 | block[0xd] << 16
@@ -816,7 +817,8 @@ vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *wi
unsigned char *p = block + pgc_offset + 0xa4 + 4 * idx;
palette[idx] = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
}
- //vob->have_palette = 1;
+ if(vob)
+ vob->have_palette = 1;
res = 0;
}
}
@@ -826,12 +828,13 @@ vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *wi
}
void *
-vobsub_open(const char *const name, const int force)
+vobsub_open(const char *const name,const char *const ifo,const int force,void** spu)
{
vobsub_t *vob = malloc(sizeof(vobsub_t));
+ if(spu)
+ *spu = NULL;
if (vob) {
char *buf;
- vob->spudec = NULL;
vob->orig_frame_width = 0;
vob->orig_frame_height = 0;
vob->spu_streams = NULL;
@@ -843,18 +846,24 @@ vobsub_open(const char *const name, const int force)
FILE *fd;
mpeg_t *mpg;
/* read in the info file */
- strcpy(buf, name);
- strcat(buf, ".ifo");
- vobsub_parse_ifo(buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
+ if(!ifo) {
+ strcpy(buf, name);
+ strcat(buf, ".ifo");
+ vobsub_parse_ifo(vob,buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
+ } else
+ vobsub_parse_ifo(vob,ifo, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force);
/* read in the index */
strcpy(buf, name);
strcat(buf, ".idx");
fd = fopen(buf, "rb");
if (fd == NULL) {
if(force)
- perror("VobSub: Can't open IDX file");
- else
- return NULL;
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open IDX file");
+ else {
+ free(buf);
+ free(vob);
+ return NULL;
+ }
} else {
while (vobsub_parse_one_line(vob, fd) >= 0)
/* NOOP */ ;
@@ -863,23 +872,29 @@ vobsub_open(const char *const name, const int force)
/* if no palette in .idx then use custom colors */
if ((vob->custom == 0)&&(vob->have_palette!=1))
vob->custom = 1;
- if (vob->orig_frame_width && vob->orig_frame_height)
- vob->spudec = spudec_new_scaled_vobsub(vob->palette, vob->cuspal, vob->custom, vob->orig_frame_width, vob->orig_frame_height);
+ if (spu && vob->orig_frame_width && vob->orig_frame_height)
+ *spu = spudec_new_scaled_vobsub(vob->palette, vob->cuspal, vob->custom, vob->orig_frame_width, vob->orig_frame_height);
/* read the indexed mpeg_stream */
strcpy(buf, name);
strcat(buf, ".sub");
mpg = mpeg_open(buf);
if (mpg == NULL) {
- if(force)
- perror("VobSub: Can't open SUB file");
+ if(force)
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open SUB file");
+ else {
+
+ free(buf);
+ free(vob);
+ return NULL;
+ }
} else {
long last_pts_diff = 0;
while (!mpeg_eof(mpg)) {
off_t pos = mpeg_tell(mpg);
if (mpeg_run(mpg) < 0) {
if (!mpeg_eof(mpg))
- perror("mpeg_run error");
+ mp_msg(MSGT_VOBSUB,MSGL_ERR,"mpeg_run error");
break;
}
if (mpg->packet_size) {
@@ -912,7 +927,7 @@ vobsub_open(const char *const name, const int force)
}
}
else
- fprintf(stderr, "don't know what to do with subtitle #%u\n", sid);
+ mp_msg(MSGT_VOBSUB,MSGL_WARN, "don't know what to do with subtitle #%u\n", sid);
}
}
}
@@ -931,8 +946,6 @@ void
vobsub_close(void *this)
{
vobsub_t *vob = (vobsub_t *)this;
- if (vob->spudec)
- spudec_free(vob->spudec);
if (vob->spu_streams) {
while (vob->spu_streams_size--)
packet_queue_destroy(vob->spu_streams + vob->spu_streams_size);
@@ -941,34 +954,23 @@ vobsub_close(void *this)
free(vob);
}
-void vobsub_draw(void *this, int dxs, int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
-{
- vobsub_t *vob = (vobsub_t *)this;
- if (vob->spudec) {
- spudec_draw_scaled(vob->spudec, dxs, dys, draw_alpha);
- }
-}
-
-void
-vobsub_process(void *vobhandle, float pts)
-{
- vobsub_t *vob = (vobsub_t *)vobhandle;
- unsigned int pts100 = 90000 * pts;
- if (vob->spudec) {
- spudec_heartbeat(vob->spudec, pts100);
- if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
- packet_queue_t *queue = vob->spu_streams + vobsub_id;
- while (queue->current_index < queue->packets_size) {
- packet_t *pkt = queue->packets + queue->current_index;
- if (pkt->pts100 <= pts100) {
- spudec_assemble(vob->spudec, pkt->data, pkt->size, pkt->pts100);
- ++queue->current_index;
- }
- else
- break;
- }
- }
+int
+vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) {
+ vobsub_t *vob = (vobsub_t *)vobhandle;
+ unsigned int pts100 = 90000 * pts;
+ if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) {
+ packet_queue_t *queue = vob->spu_streams + vobsub_id;
+ while (queue->current_index < queue->packets_size) {
+ packet_t *pkt = queue->packets + queue->current_index;
+ if (pkt->pts100 <= pts100) {
+ ++queue->current_index;
+ *data = pkt->data;
+ *timestamp = pkt->pts100;
+ return pkt->size;
+ } else break;
}
+ }
+ return -1;
}
void
@@ -980,6 +982,4 @@ vobsub_reset(void *vobhandle)
while (n-- > 0)
vob->spu_streams[n].current_index = 0;
}
- if (vob->spudec)
- spudec_reset(vob->spudec);
}
diff --git a/vobsub.h b/vobsub.h
index a5700c06b3..a1b713d8e5 100644
--- a/vobsub.h
+++ b/vobsub.h
@@ -1,10 +1,10 @@
#ifndef MPLAYER_VOBSUB_H
#define MPLAYER_VOBSUB_H
-extern void *vobsub_open(const char *subname, const int force);
-extern void vobsub_process(void *vob, float pts);
+extern void *vobsub_open(const char *subname, const char *const ifo, const int force, void** spu);
extern void vobsub_reset(void *vob);
-extern void vobsub_draw(void *vob, int dxs, int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-extern int vobsub_parse_ifo(const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force);
+extern int vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force);
+extern int vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp);
+extern void vobsub_close(void *this);
#endif /* MPLAYER_VOBSUB_H */