📄 vobsub.cpp
字号:
if (vobsub_ensure_spu_stream( index) < 0)
return PARSE_ERROR;
if (id && idlen) {
if (spu_streams[index].id)
free(spu_streams[index].id);
spu_streams[index].id = (char_t*)calloc(idlen + 1,sizeof(char_t));
if (spu_streams[index].id == NULL) {
DPRINTF(_l("vobsub_add_id: malloc failure"));
return PARSE_ERROR;
}
//memcpy(spu_streams[index].id, id, idlen)
//spu_streams[index].id[idlen] = 0;
text<char_t>(id, idlen, spu_streams[index].id, idlen + 1);//strncpy(spu_streams[index].id,id,idlen);// ;
}
spu_streams_current = index;
DPRINTF(_l("[vobsub] subtitle (vobsubid): %d language %s"),index, spu_streams[index].id);
return PARSE_OK;
}
Tvobsub::PARSE_RES Tvobsub::vobsub_add_altid( const char *id, size_t idlen)
{
if (spu_streams == 0) {
DPRINTF(_l("[vobsub] warning, binning some index entries. Check your index file"));
return PARSE_ERROR;
}
packet_queue_t *queue = spu_streams + spu_streams_current;
if (queue->altid) free(queue->altid);
queue->altid=(char_t*)calloc(idlen+1,sizeof(char_t));
//memcpy(queue->altid,id,idlen);
//queue->altid[idlen]='\0';
text<char_t>(id, idlen, queue->altid, idlen + 1);
return PARSE_OK;
}
Tvobsub::PARSE_RES Tvobsub::vobsub_add_timestamp( long filepos, int ms)
{
packet_queue_t *queue;
packet_t *pkt;
if (spu_streams == 0) {
DPRINTF(_l("[vobsub] warning, binning some index entries. Check your index file"));
return PARSE_ERROR;
}
queue = spu_streams + spu_streams_current;
if (queue->packet_queue_grow() >= 0) {
pkt = queue->packets + (queue->packets_size - 1);
pkt->filepos = filepos;
pkt->pts100 = ms < 0 ? UINT_MAX : (unsigned int)ms * 90;
return PARSE_OK;
}
return PARSE_ERROR;
}
Tvobsub::PARSE_RES Tvobsub::vobsub_parse_id(const char *line)
{
// id: xx, index: n
size_t idlen;
const char *p, *q;
p = line;
while (isspace(*p))
++p;
q = p;
while (isalpha(*q))
++q;
idlen = q - p;
if (idlen == 0)
return PARSE_ERROR;
++q;
while (isspace(*q))
++q;
if (strncmp("index:", q, 6))
return PARSE_ERROR;
q += 6;
while (isspace(*q))
++q;
if (!isdigit(*q))
return PARSE_ERROR;
return vobsub_add_id(p, idlen, atoi(q));
}
Tvobsub::PARSE_RES Tvobsub::vobsub_parse_altid(const char *line)
{
// id: xx, index: n
size_t idlen;
const char *p, *q;
p = line;
while (isspace(*p))
++p;
q = p;
while (*q && *q!='\n')
++q;
idlen = q - p;
if (idlen == 0)
return PARSE_ERROR;
return vobsub_add_altid(p, idlen);
}
Tvobsub::PARSE_RES Tvobsub::vobsub_parse_timestamp(const char *line)
{
// timestamp: HH:MM:SS.mmm, filepos: 0nnnnnnnnn
int ms;
const char *p=parseTimestamp(line,ms);
if (!p)
return PARSE_ERROR;
if (*p != ',')
return PARSE_ERROR;
line = p + 1;
while (isspace(*line))
++line;
if (strncmp("filepos:", line, 8))
return PARSE_ERROR;
line += 8;
while (isspace(*line))
++line;
if (! isxdigit(*line))
return PARSE_ERROR;
long filepos = strtol(line, NULL, 16);
return vobsub_add_timestamp(filepos, delay + ms/* + 1000 * (s + 60 * (m + 60 * h))*/);
}
/* don't know how to use tridx */
Tvobsub::PARSE_RES Tvobsub::vobsub_set_lang(const char *line)
{
if (vobsub_id == -1)
vobsub_id = atoi(line + 8);
return PARSE_OK;
}
Tvobsub::PARSE_RES Tvobsub::idx_parse_one_line(const char *line)
{
if (strncmp("langidx:", line, 8) == 0)
return vobsub_set_lang(line);
else if (strncmp("id:", line, 3) == 0)
return vobsub_parse_id( line + 3);
else if (strncmp("alt:", line, 4) == 0)
return vobsub_parse_altid( line + 4);
else if (strncmp("timestamp:", line, 10) == 0)
return vobsub_parse_timestamp( line + 10);
else
return TsubtitleDVDparent::idx_parse_one_line(line);
}
Tvobsub::Tvobsub(Tstream &fd,const char_t *const name,const char_t *const ifo,const int force,Tspudec* *spu,IffdshowBase *deci)
{
deci->getConfig(&config);
ok=false;
if(spu)
*spu = NULL;
char_t *buf;
spu_streams = NULL;
spu_streams_size = 0;
spu_streams_current = 0;
vobsub_id=-1;
delay = 0;
forced_subs=0;
buf = (char_t*)malloc((strlen(name) + 5) * sizeof(char_t));
if (buf)
{
idx_parse(fd);
/* if no palette in .idx then use custom colors */
if ((custom_colors == 0)&&(fsppal!=1))
custom_colors = 1;
if (spu && rectOrig.dx && rectOrig.dy)
*spu = new Tspudec(deci,sppal, cuspal, custom_colors, rectOrig.dx, rectOrig.dy);
/* read the indexed mpeg_stream */
strcpy(buf, name);
strcat(buf, _l(".sub"));
mpeg_t *mpg = mpeg_open(buf);
if (mpg == NULL)
{
if(force)
DPRINTF(_l("VobSub: Can't open SUB file"));
else
{
free(buf);
//free(vob);
return /*NULL*/;
}
}
else
{
long last_pts_diff = 0;
while (!mpeg_eof(mpg))
{
long pos = mpeg_tell(mpg);
if (mpeg_run(mpg) < 0)
{
if (!mpeg_eof(mpg))
DPRINTF(_l("VobSub: mpeg_run error"));
break;
}
if (mpg->packet_size)
{
if ((mpg->aid & 0xe0) == 0x20)
{
unsigned int sid = mpg->aid & 0x1f;
if (vobsub_ensure_spu_stream(sid) >= 0)
{
packet_queue_t *queue = spu_streams + sid;
//get the packet to fill
if (queue->packets_size == 0 && queue->packet_queue_grow() < 0)
return;
while (queue->current_index + 1 < queue->packets_size && queue->packets[queue->current_index + 1].filepos <= pos)
++queue->current_index;
if (queue->current_index < queue->packets_size)
{
packet_t *pkt;
if (queue->packets[queue->current_index].data)
{
// insert a new packet and fix the PTS !
queue->packet_queue_insert();
queue->packets[queue->current_index].pts100 = mpg->pts + last_pts_diff;
}
pkt = queue->packets + queue->current_index;
if (pkt->pts100 != UINT_MAX)
{
if (queue->packets_size > 1)
last_pts_diff = pkt->pts100 - mpg->pts;
else
pkt->pts100 = mpg->pts;
// FIXME: should not use mpg_sub internal informations, make a copy
pkt->data = mpg->packet;
pkt->size = mpg->packet_size;
mpg->packet = NULL;
mpg->packet_reserve = 0;
mpg->packet_size = 0;
}
}
}
}
}
}
spu_streams_current = spu_streams_size;
while (spu_streams_current-- > 0)
spu_streams[spu_streams_current].current_index = 0;
mpeg_free(mpg);
}
free(buf);
}
ok=true;
}
Tvobsub::~Tvobsub()
{
if (spu_streams) {
while (spu_streams_size--)
(spu_streams + spu_streams_size)->packet_queue_destroy();
free(spu_streams);
}
}
unsigned int Tvobsub::vobsub_get_indexes_count(void)
{
return spu_streams_size;
}
char_t* Tvobsub::vobsub_get_id( unsigned int index)
{
return (index < spu_streams_size) ? spu_streams[index].id : NULL;
}
unsigned int Tvobsub::vobsub_get_forced_subs_flag(void)
{
return forced_subs;
}
/*
int Tvobsub::vobsub_set_from_lang(const char * lang)
{
unsigned int i;
while(lang && strlen(lang) >= 2){
for(i=0; i < spu_streams_size; i++)
if (spu_streams[i].id)
if ((strncmp(spu_streams[i].id, lang, 2)==0)){
vobsub_id=i;
DPRINTF( _l("Selected VOBSUB language: %d language: %s"), i, text<char_t>(spu_streams[i].id));
return 0;
}
lang+=2;while (lang[0]==',' || lang[0]==' ') ++lang;
}
DPRINTF(_l("No matching VOBSUB language found!"));
return -1;
}
*/
int Tvobsub::vobsub_get_packet(unsigned int pts,void** data, int* timestamp) {
unsigned int pts100 = (unsigned int)pts;//(90000 * pts);
if (spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < spu_streams_size) {
packet_queue_t *queue = spu_streams + vobsub_id;
while (queue->current_index < queue->packets_size) {
packet_t *pkt = queue->packets + queue->current_index;
if (pkt->pts100 != UINT_MAX)
if (pkt->pts100 <= pts100) {
++queue->current_index;
*data = pkt->data;
*timestamp = pkt->pts100;
return pkt->size;
} else break;
else
++queue->current_index;
}
}
return -1;
}
int Tvobsub::vobsub_get_next_packet( void** data, int* timestamp)
{
if (spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < spu_streams_size) {
packet_queue_t *queue = spu_streams + vobsub_id;
if (queue->current_index < queue->packets_size) {
packet_t *pkt = queue->packets + queue->current_index;
++queue->current_index;
*data = pkt->data;
*timestamp = pkt->pts100;
return pkt->size;
}
}
return -1;
}
void Tvobsub::vobsub_seek(int pts)
{
packet_queue_t * queue;
unsigned int seek_pts100 = (int)pts;// * 90000;
if (spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < spu_streams_size) {
/* do not seek if we don't know the id */
if (vobsub_get_id(vobsub_id) == NULL)
return;
queue = spu_streams + vobsub_id;
queue->current_index = 0;
while ((queue->packets + queue->current_index)->pts100 < seek_pts100)
++queue->current_index;
if (queue->current_index > 0)
--queue->current_index;
}
}
void Tvobsub::vobsub_reset(void)
{
if (spu_streams) {
unsigned int n = spu_streams_size;
while (n-- > 0)
spu_streams[n].current_index = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -