⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vobsub.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (pkt->data)	free(pkt->data);}static voidpacket_queue_construct(packet_queue_t *queue){    queue->id = NULL;    queue->packets = NULL;    queue->packets_reserve = 0;    queue->packets_size = 0;    queue->current_index = 0;}static voidpacket_queue_destroy(packet_queue_t *queue){    if (queue->packets) {	while (queue->packets_size--)	    packet_destroy(queue->packets + queue->packets_size);	free(queue->packets);    }    return;}/* Make sure there is enough room for needed_size packets in the   packet queue. */static intpacket_queue_ensure(packet_queue_t *queue, unsigned int needed_size){    if (queue->packets_reserve < needed_size) {	if (queue->packets) {	    packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t));	    if (tmp == NULL) {		mp_msg(MSGT_VOBSUB,MSGL_FATAL,"realloc failure");		return -1;	    }	    queue->packets = tmp;	    queue->packets_reserve *= 2;	}	else {	    queue->packets = malloc(sizeof(packet_t));	    if (queue->packets == NULL) {		mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure");		return -1;	    }	    queue->packets_reserve = 1;	}    }    return 0;}/* add one more packet */static intpacket_queue_grow(packet_queue_t *queue){    if (packet_queue_ensure(queue, queue->packets_size + 1) < 0) 	return -1;    packet_construct(queue->packets + queue->packets_size);    ++queue->packets_size;    return 0;}/* insert a new packet, duplicating pts from the current one */static intpacket_queue_insert(packet_queue_t *queue){    packet_t *pkts;    if (packet_queue_ensure(queue, queue->packets_size + 1) < 0)	return -1;    /* XXX packet_size does not reflect the real thing here, it will be updated a bit later */    memmove(queue->packets + queue->current_index + 2,	    queue->packets + queue->current_index + 1,	    sizeof(packet_t) * (queue->packets_size - queue->current_index - 1));    pkts = queue->packets + queue->current_index;    ++queue->packets_size;    ++queue->current_index;    packet_construct(pkts + 1);    pkts[1].pts100 = pkts[0].pts100;    pkts[1].filepos = pkts[0].filepos;    return 0;}/********************************************************************** * Vobsub **********************************************************************/typedef struct {    unsigned int palette[16];    unsigned int cuspal[4];    int delay;    unsigned int custom;    unsigned int have_palette;    unsigned int orig_frame_width, orig_frame_height;    unsigned int origin_x, origin_y;    unsigned int forced_subs;    /* index */    packet_queue_t *spu_streams;    unsigned int spu_streams_size;    unsigned int spu_streams_current;} vobsub_t;/* Make sure that the spu stream idx exists. */static intvobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index){    if (index >= vob->spu_streams_size) {	/* This is a new stream */	if (vob->spu_streams) {	    packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t));	    if (tmp == NULL) {		mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: realloc failure");		return -1;	    }	    vob->spu_streams = tmp;	}	else {	    vob->spu_streams = malloc((index + 1) * sizeof(packet_queue_t));	    if (vob->spu_streams == NULL) {		mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: malloc failure");		return -1;	    }	}	while (vob->spu_streams_size <= index) {	    packet_queue_construct(vob->spu_streams + vob->spu_streams_size);	    ++vob->spu_streams_size;	}    }    return 0;}static intvobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int index){    if (vobsub_ensure_spu_stream(vob, index) < 0)	return -1;    if (id && idlen) {	if (vob->spu_streams[index].id)	    free(vob->spu_streams[index].id);	vob->spu_streams[index].id = malloc(idlen + 1);	if (vob->spu_streams[index].id == NULL) {	    mp_msg(MSGT_VOBSUB,MSGL_FATAL,"vobsub_add_id: malloc failure");	    return -1;	}	vob->spu_streams[index].id[idlen] = 0;	memcpy(vob->spu_streams[index].id, id, idlen);    }    vob->spu_streams_current = index;    if (identify)    {	mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VOBSUB_ID=%d\n", index);	if (id && idlen)	    mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VSID_%d_LANG=%s\n", index, vob->spu_streams[index].id);    }    mp_msg(MSGT_VOBSUB,MSGL_V,"[vobsub] subtitle (vobsubid): %d language %s\n",		index, vob->spu_streams[index].id);    return 0;}static intvobsub_add_timestamp(vobsub_t *vob, off_t filepos, int ms){    packet_queue_t *queue;    packet_t *pkt;    if (vob->spu_streams == 0) {	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;    if (packet_queue_grow(queue) >= 0) {	pkt = queue->packets + (queue->packets_size - 1);	pkt->filepos = filepos;	pkt->pts100 = ms < 0 ? UINT_MAX : (unsigned int)ms * 90;	return 0;    }    return -1;}static intvobsub_parse_id(vobsub_t *vob, 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 -1;    ++q;    while (isspace(*q))	++q;    if (strncmp("index:", q, 6))	return -1;    q += 6;    while (isspace(*q))	++q;    if (!isdigit(*q))	return -1;    return vobsub_add_id(vob, p, idlen, atoi(q));}static intvobsub_parse_timestamp(vobsub_t *vob, const char *line){    // timestamp: HH:MM:SS.mmm, filepos: 0nnnnnnnnn    const char *p;    int h, m, s, ms;    off_t filepos;    while (isspace(*line))	++line;    p = line;    while (isdigit(*p))	++p;    if (p - line != 2)	return -1;    h = atoi(line);    if (*p != ':')	return -1;    line = ++p;    while (isdigit(*p))	++p;    if (p - line != 2)	return -1;    m = atoi(line);    if (*p != ':')	return -1;    line = ++p;    while (isdigit(*p))	++p;    if (p - line != 2)	return -1;    s = atoi(line);    if (*p != ':')	return -1;    line = ++p;    while (isdigit(*p))	++p;    if (p - line != 3)	return -1;    ms = atoi(line);    if (*p != ',')	return -1;    line = p + 1;    while (isspace(*line))	++line;    if (strncmp("filepos:", line, 8))	return -1;    line += 8;    while (isspace(*line))	++line;    if (! isxdigit(*line))	return -1;    filepos = strtol(line, NULL, 16);    return vobsub_add_timestamp(vob, filepos, vob->delay + ms + 1000 * (s + 60 * (m + 60 * h)));}static intvobsub_parse_size(vobsub_t *vob, const char *line){    // size: WWWxHHH    char *p;    while (isspace(*line))	++line;    if (!isdigit(*line))	return -1;    vob->orig_frame_width = strtoul(line, &p, 10);    if (*p != 'x')	return -1;    ++p;    vob->orig_frame_height = strtoul(p, NULL, 10);    return 0;}static intvobsub_parse_origin(vobsub_t *vob, const char *line){    // org: X,Y    char *p;    while (isspace(*line))	++line;    if (!isdigit(*line))	return -1;    vob->origin_x = strtoul(line, &p, 10);    if (*p != ',')	return -1;    ++p;    vob->origin_y = strtoul(p, NULL, 10);    return 0;}static intvobsub_parse_palette(vobsub_t *vob, const char *line){    // palette: XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX    unsigned int n;    n = 0;    while (1) {	const char *p;	int r, g, b, y, u, v, tmp;	while (isspace(*line))	    ++line;	p = line;	while (isxdigit(*p))	    ++p;	if (p - line != 6)	    return -1;	tmp = strtoul(line, NULL, 16);	r = tmp >> 16 & 0xff;	g = tmp >> 8 & 0xff;	b = tmp & 0xff;	y = MIN(MAX((int)(0.1494 * r + 0.6061 * g + 0.2445 * b), 0), 0xff);	u = MIN(MAX((int)(0.6066 * r - 0.4322 * g - 0.1744 * b) + 128, 0), 0xff);	v = MIN(MAX((int)(-0.08435 * r - 0.3422 * g + 0.4266 * b) + 128, 0), 0xff);	vob->palette[n++] = y << 16 | u << 8 | v;	if (n == 16)	    break;	if (*p == ',')	    ++p;	line = p;    }    vob->have_palette = 1;    return 0;}static intvobsub_parse_custom(vobsub_t *vob, const char *line){    //custom colors: OFF/ON(0/1)    if ((strncmp("ON", line + 15, 2) == 0)||strncmp("1", line + 15, 1) == 0)        vob->custom=1;    else if ((strncmp("OFF", line + 15, 3) == 0)||strncmp("0", line + 15, 1) == 0)        vob->custom=0;    else        return -1;    return 0;}static intvobsub_parse_cuspal(vobsub_t *vob, const char *line){    //colors: XXXXXX, XXXXXX, XXXXXX, XXXXXX    unsigned int n;    n = 0;    line += 40;    while(1){    	const char *p;	while (isspace(*line))	    ++line;	p=line;	while (isxdigit(*p))	    ++p;	if (p - line !=6)	    return -1;	vob->cuspal[n++] = strtoul(line, NULL,16);	if (n==4)	    break;	if(*p == ',')	    ++p;	line = p;    }    return 0;}/* don't know how to use tridx */static intvobsub_parse_tridx(const char *line){    //tridx: XXXX    int tridx;    tridx = strtoul((line + 26), NULL, 16);    tridx = ((tridx&0x1000)>>12) | ((tridx&0x100)>>7) | ((tridx&0x10)>>2) | ((tridx&1)<<3);    return tridx;}static intvobsub_parse_delay(vobsub_t *vob, const char *line){    int h, m, s, ms;    int forward = 1;    if (*(line + 7) == '+'){    	forward = 1;	line++;    }    else if (*(line + 7) == '-'){    	forward = -1;	line++;    }    mp_msg(MSGT_SPUDEC,MSGL_V, "forward=%d", forward);    h = atoi(line + 7);    mp_msg(MSGT_VOBSUB,MSGL_V, "h=%d," ,h);    m = atoi(line + 10);    mp_msg(MSGT_VOBSUB,MSGL_V, "m=%d,", m);    s = atoi(line + 13);    mp_msg(MSGT_VOBSUB,MSGL_V, "s=%d,", s);    ms = atoi(line + 16);    mp_msg(MSGT_VOBSUB,MSGL_V, "ms=%d", ms);    vob->delay = (ms + 1000 * (s + 60 * (m + 60 * h))) * forward;    return 0;}static intvobsub_set_lang(const char *line){    if (vobsub_id == -1)        vobsub_id = atoi(line + 8);    return 0;}static intvobsub_parse_forced_subs(vobsub_t *vob, const char *line){    const char *p;    p  = line;    while (isspace(*p))	++p;    if (strncasecmp("on",p,2) == 0){	    vob->forced_subs=~0;	    return 0;    } else if (strncasecmp("off",p,3) == 0){	    vob->forced_subs=0;	    return 0;    }	    return -1;}static intvobsub_parse_one_line(vobsub_t *vob, rar_stream_t *fd){    ssize_t line_size;    int res = -1;	size_t line_reserve = 0;	char *line = NULL;    do {	line_size = getline(&line, &line_reserve, fd);	if (line_size < 0) {	    break;	}	if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#')	    continue;	else if (strncmp("langidx:", line, 8) == 0)	    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)	    res = vobsub_parse_id(vob, line + 3);	else if (strncmp("palette:", line, 8) == 0)	    res = vobsub_parse_palette(vob, line + 8);	else if (strncmp("size:", line, 5) == 0)	    res = vobsub_parse_size(vob, line + 5);	else if (strncmp("org:", line, 4) == 0)	    res = vobsub_parse_origin(vob, line + 4);	else if (strncmp("timestamp:", line, 10) == 0)	    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(line) + vobsub_parse_custom(vob, line);	else if (strncmp("forced subs:", line, 12) == 0)		res = vobsub_parse_forced_subs(vob, line + 12);	else {	    mp_msg(MSGT_VOBSUB,MSGL_V, "vobsub: ignoring %s", line);	    continue;	}	if (res < 0)	    mp_msg(MSGT_VOBSUB,MSGL_ERR,  "ERROR in %s", line);	break;    } while (1);    if (line)      free(line);    return res;}intvobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force,		 int sid, char *langid){    vobsub_t *vob = (vobsub_t*)this;    int res = -1;    rar_stream_t *fd = rar_open(name, "rb");    if (fd == NULL) {        if (force)	    mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Can't open IFO file\n");    } else {	// parse IFO header	unsigned char block[0x800];	const char *const ifo_magic = "DVDVIDEO-VTS";	if (rar_read(block, sizeof(block), 1, fd) != 1) {	    if (force)		mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Can't read IFO header\n");	} else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1))	    mp_msg(MSGT_VOBSUB,MSGL_ERR, "VobSub: Bad magic in IFO header\n");	else {	    unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16		| block[0xce] << 8 | block[0xcf];	    int standard = (block[0x200] & 0x30) >> 4;	    int resolution = (block[0x201] & 0x0c) >> 2;	    *height = standard ? 576 : 480;	    *width = 0;	    switch (resolution) {	    case 0x0:		*width = 720;		break;	    case 0x1:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -