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

📄 subreader.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (sub_format==SUB_INVALID) {mp_msg(MSGT_SUBREADER,MSGL_WARN,"SUB: Could not determine file format\n");return NULL;}    srp=sr+sub_format;    mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Detected subtitle file format: %s\n", srp->name);        rewind (fd);#ifdef USE_ICONV    sub_utf8_prev=sub_utf8;    {	    int l,k;	    k = -1;	    if ((l=strlen(filename))>4){		    char *exts[] = {".utf", ".utf8", ".utf-8" };		    for (k=3;--k>=0;)			if (!strcasecmp(filename+(l - strlen(exts[k])), exts[k])){			    sub_utf8 = 1;			    break;			}	    }	    if (k<0) subcp_open(fd);    }#endif    sub_num=0;n_max=32;    first=(subtitle *)malloc(n_max*sizeof(subtitle));    if(!first){#ifdef USE_ICONV	  subcp_close();          sub_utf8=sub_utf8_prev;#endif	    return NULL;    }    #ifdef USE_SORTSUB    sub = (subtitle *)malloc(sizeof(subtitle));    //This is to deal with those formats (AQT & Subrip) which define the end of a subtitle    //as the beginning of the following    previous_sub_end = 0;#endif        while(1){        if(sub_num>=n_max){            n_max+=16;            first=realloc(first,n_max*sizeof(subtitle));        }#ifndef USE_SORTSUB	sub = &first[sub_num];#endif		memset(sub, '\0', sizeof(subtitle));        sub=srp->read(fd,sub);        if(!sub) break;   // EOF#ifdef USE_ICONV	if ((sub!=ERR) && (sub_utf8 & 2)) sub=subcp_recode(sub);#endif#ifdef USE_FRIBIDI	if (sub!=ERR) sub=sub_fribidi(sub,sub_utf8);#endif	if ( sub == ERR )	 {#ifdef USE_ICONV          subcp_close();#endif    	  if ( first ) free(first);	  return NULL; 	 }        // Apply any post processing that needs recoding first        if ((sub!=ERR) && !sub_no_text_pp && srp->post) srp->post(sub);#ifdef USE_SORTSUB	if(!sub_num || (first[sub_num - 1].start <= sub->start)){	    first[sub_num].start = sub->start;  	    first[sub_num].end   = sub->end;	    first[sub_num].lines = sub->lines;	    first[sub_num].alignment = sub->alignment;  	    for(i = 0; i < sub->lines; ++i){		first[sub_num].text[i] = sub->text[i];  	    }	    if (previous_sub_end){  		first[sub_num - 1].end = previous_sub_end;    		previous_sub_end = 0;	    }	} else {	    for(j = sub_num - 1; j >= 0; --j){    		first[j + 1].start = first[j].start;    		first[j + 1].end   = first[j].end;		first[j + 1].lines = first[j].lines;		first[j + 1].alignment = first[j].alignment;    		for(i = 0; i < first[j].lines; ++i){      		    first[j + 1].text[i] = first[j].text[i];		}		if(!j || (first[j - 1].start <= sub->start)){	    	    first[j].start = sub->start;	    	    first[j].end   = sub->end;	    	    first[j].lines = sub->lines;	    	    first[j].alignment = sub->alignment;	    	    for(i = 0; i < SUB_MAX_TEXT; ++i){			first[j].text[i] = sub->text[i];		    }		    if (previous_sub_end){			first[j].end = first[j - 1].end;			first[j - 1].end = previous_sub_end;			previous_sub_end = 0;		    }		    break;    		}	    }	}#endif	        if(sub==ERR) ++sub_errs; else ++sub_num; // Error vs. Valid    }        fclose(fd);#ifdef USE_ICONV    subcp_close();#endif//    printf ("SUB: Subtitle format %s time.\n", uses_time?"uses":"doesn't use");    mp_msg(MSGT_SUBREADER,MSGL_INFO,"SUB: Read %i subtitles", sub_num);    if (sub_errs) mp_msg(MSGT_SUBREADER,MSGL_INFO,", %i bad line(s).\n", sub_errs);    else 	  mp_msg(MSGT_SUBREADER,MSGL_INFO,".\n");    if(sub_num<=0){	free(first);	return NULL;    }    // we do overlap if the user forced it (suboverlap_enable == 2) or    // the user didn't forced no-overlapsub and the format is Jacosub or Ssa.    // this is because usually overlapping subtitles are found in these formats,    // while in others they are probably result of bad timingif ((suboverlap_enabled == 2) ||    ((suboverlap_enabled) && ((sub_format == SUB_JACOSUB) || (sub_format == SUB_SSA)))) {    adjust_subs_time(first, 6.0, fps, 0, sub_num, uses_time);/*~6 secs AST*/// here we manage overlapping subtitles    sub_orig = sub_num;    n_first = sub_num;    sub_num = 0;    second = NULL;    // for each subtitle in first[] we deal with its 'block' of    // bonded subtitles    for (sub_first = 0; sub_first < n_first; ++sub_first) {	unsigned long global_start = first[sub_first].start,		global_end = first[sub_first].end, local_start, local_end;	int lines_to_add = first[sub_first].lines, sub_to_add = 0,		**placeholder = NULL, higher_line = 0, counter, start_block_sub = sub_num;	char real_block = 1;	// here we find the number of subtitles inside the 'block'	// and its span interval. this works well only with sorted	// subtitles	while ((sub_first + sub_to_add + 1 < n_first) && (first[sub_first + sub_to_add + 1].start < global_end)) {	    ++sub_to_add;	    lines_to_add += first[sub_first + sub_to_add].lines;	    if (first[sub_first + sub_to_add].start < global_start) {		global_start = first[sub_first + sub_to_add].start;	    }	    if (first[sub_first + sub_to_add].end > global_end) {		global_end = first[sub_first + sub_to_add].end;	    }	}	// we need a structure to keep trace of the screen lines	// used by the subs, a 'placeholder'	counter = 2 * sub_to_add + 1;  // the maximum number of subs derived	                               // from a block of sub_to_add+1 subs	placeholder = (int **) malloc(sizeof(int *) * counter);	for (i = 0; i < counter; ++i) {	    placeholder[i] = (int *) malloc(sizeof(int) * lines_to_add);	    for (j = 0; j < lines_to_add; ++j) {		placeholder[i][j] = -1;	    }	}	counter = 0;	local_end = global_start - 1;	do {	    int ls;	    // here we find the beginning and the end of a new	    // subtitle in the block	    local_start = local_end + 1;	    local_end   = global_end;	    for (j = 0; j <= sub_to_add; ++j) {		if ((first[sub_first + j].start - 1 > local_start) && (first[sub_first + j].start - 1 < local_end)) {		    local_end = first[sub_first + j].start - 1;		} else if ((first[sub_first + j].end > local_start) && (first[sub_first + j].end < local_end)) {		    local_end = first[sub_first + j].end;		}	    }            // here we allocate the screen lines to subs we must	    // display in current local_start-local_end interval.	    // if the subs were yet presents in the previous interval	    // they keep the same lines, otherside they get unused lines	    for (j = 0; j <= sub_to_add; ++j) {		if ((first[sub_first + j].start <= local_end) && (first[sub_first + j].end > local_start)) {		    unsigned long sub_lines = first[sub_first + j].lines, fragment_length = lines_to_add + 1,			tmp = 0;		    char boolean = 0;		    int fragment_position = -1;		    // if this is not the first new sub of the block		    // we find if this sub was present in the previous		    // new sub		    if (counter)			for (i = 0; i < lines_to_add; ++i) {			    if (placeholder[counter - 1][i] == sub_first + j) {				placeholder[counter][i] = sub_first + j;				boolean = 1;			    }			}		    if (boolean)			continue;		    // we are looking for the shortest among all groups of		    // sequential blank lines whose length is greater than or		    // equal to sub_lines. we store in fragment_position the		    // position of the shortest group, in fragment_length its		    // length, and in tmp the length of the group currently		    // examinated		    for (i = 0; i < lines_to_add; ++i) {			if (placeholder[counter][i] == -1) {			    // placeholder[counter][i] is part of the current group			    // of blank lines			    ++tmp;			} else {			    if (tmp == sub_lines) {				// current group's size fits exactly the one we				// need, so we stop looking				fragment_position = i - tmp;				tmp = 0;				break;			    }			    if ((tmp) && (tmp > sub_lines) && (tmp < fragment_length)) {				// current group is the best we found till here,				// but is still bigger than the one we are looking				// for, so we keep on looking				fragment_length = tmp;				fragment_position = i - tmp;				tmp = 0;			    } else {				// current group doesn't fit at all, so we forget it				tmp = 0;			    }			}		    }		    if (tmp) {			// last screen line is blank, a group ends with it			if ((tmp >= sub_lines) && (tmp < fragment_length)) {			    fragment_position = i - tmp;			}		    }		    if (fragment_position == -1) {			// it was not possible to find free screen line(s) for a subtitle,			// usually this means a bug in the code; however we do not overlap			mp_msg(MSGT_SUBREADER, MSGL_WARN, "SUB: we could not find a suitable position for an overlapping subtitle\n");			higher_line = SUB_MAX_TEXT + 1;			break;		    } else {			for (tmp = 0; tmp < sub_lines; ++tmp) {			    placeholder[counter][fragment_position + tmp] = sub_first + j;			}		    }		}	    }	    for (j = higher_line + 1; j < lines_to_add; ++j) {		if (placeholder[counter][j] != -1)		    higher_line = j;		else		    break;	    }	    if (higher_line >= SUB_MAX_TEXT) {		// the 'block' has too much lines, so we don't overlap the		// subtitles		second = (subtitle *) realloc(second, (sub_num + sub_to_add + 1) * sizeof(subtitle));		for (j = 0; j <= sub_to_add; ++j) {		    int ls;		    memset(&second[sub_num + j], '\0', sizeof(subtitle));		    second[sub_num + j].start = first[sub_first + j].start;		    second[sub_num + j].end   = first[sub_first + j].end;		    second[sub_num + j].lines = first[sub_first + j].lines;		    second[sub_num + j].alignment = first[sub_first + j].alignment;		    for (ls = 0; ls < second[sub_num + j].lines; ls++) {			second[sub_num + j].text[ls] = strdup(first[sub_first + j].text[ls]);		    }		}		sub_num += sub_to_add + 1;		sub_first += sub_to_add;		real_block = 0;		break;	    }	    // we read the placeholder structure and create the new	    // subs.	    second = (subtitle *) realloc(second, (sub_num + 1) * sizeof(subtitle));	    memset(&second[sub_num], '\0', sizeof(subtitle));	    second[sub_num].start = local_start;	    second[sub_num].end   = local_end;	    second[sub_num].alignment = first[sub_first].alignment;	    n_max = (lines_to_add < SUB_MAX_TEXT) ? lines_to_add : SUB_MAX_TEXT;	    for (i = 0, j = 0; j < n_max; ++j) {		if (placeholder[counter][j] != -1) {		    int lines = first[placeholder[counter][j]].lines;		    for (ls = 0; ls < lines; ++ls) {			second[sub_num].text[i++] = strdup(first[placeholder[counter][j]].text[ls]);		    }		    j += lines - 1;		} else {		    second[sub_num].text[i++] = strdup(" ");		}	    }	    ++sub_num;	    ++counter;	} while (local_end < global_end);	if (real_block)	    for (i = 0; i < counter; ++i)		second[start_block_sub + i].lines = higher_line + 1;	counter = 2 * sub_to_add + 1;	for (i = 0; i < counter; ++i) {	    free(placeholder[i]);	}	free(placeholder);	sub_first += sub_to_add;    }    for (j = sub_orig - 1; j >= 0; --j) {	for (i = first[j].lines - 1; i >= 0; --i) {	    free(first[j].text[i]);	}    }    free(first);    return_sub = second;} else { //if(suboverlap_enabled)    adjust_subs_time(first, 6.0, fps, 1, sub_num, uses_time);/*~6 secs AST*/    return_sub = first;}    if (return_sub == NULL) return NULL;    subt_data = (sub_data *)malloc(sizeof(sub_data));    subt_data->filename = filename;    subt_data->sub_uses_time = uses_time;    subt_data->sub_num = sub_num;    subt_data->sub_errs = sub_errs;    subt_data->subtitles = return_sub;    return subt_data;}#if 0char * strreplace( char * in,char * what,char * whereof ){ int i; char * tmp;  if ( ( in == NULL )||( what == NULL )||( whereof == NULL )||( ( tmp=strstr( in,what ) ) == NULL ) ) return NULL; for( i=0;i<strlen( whereof );i++ ) tmp[i]=whereof[i]; if ( strlen( what ) > strlen( whereof ) ) tmp[i]=0; return in;}#endifstatic void strcpy_trim(char *d, char *s){    // skip leading whitespace    while (*s && !isalnum(*s)) {	s++;    }    for (;;) {	// copy word	while (*s && isalnum(*s)) {	    *d = tolower(*s);	    s++; d++;	}	if (*s == 0) break;	// trim excess whitespace	while (*s && !isalnum(*s)) {	    s++;	}	if (*s == 0) break;	*d++ = ' ';    }    *d = 0;} static void strcpy_strip_ext(char *d, char *s){    char *tmp = strrchr(s,'.');    if (!tmp) {	strcpy(d, s);	return;    } else {	strncpy(d, s, tmp-s);	d[tmp-s] = 0;    }    while (*d) {	*d = tolower(*d);	d++;    }} static void strcpy_get_ext(char *d, char *s){    char *tmp = strrchr(s,'.');    if (!tmp) {	strcpy(d, "");	return;    } else {	strcpy(d, tmp+1);   }}static int whiteonly(char *s){    while (*s) {	if (isalnum(*s)) return 0;	s++;  }    return 1;}typedef struct _subfn {    int priority;    char *fname;} subfn;static int compare_sub_priority(const void *a, const void *b){    if (((subfn*)a)->priority > ((subfn*)b)->priority) {	return -1;    } else if (((subfn*)a)->priority < ((subfn*)b)->priority) {	return 1;    } else {	return strcoll(((subfn*)a)->fname, ((subfn*)b)->fname);    }}char** sub_filenames(char* path, char *fname){    char *f_dir, *f_fname, *f_fname_noext, *f_fname_trim, *tmp, *tmp_sub_id;    char *tmp_fname_noext, *tmp_fname_trim, *tmp_fname_ext, *tmpresult;     int len, pos, found, i, j;    char * sub_exts[] = {  "utf", "utf8", "utf-8", "sub", "srt", "smi", "rt", "txt", "ssa", "aqt", "jss", "js", "ass", NULL};    subfn *result;    char **result2;        int subcnt;     FILE *f;    DIR *d;    struct dirent *de;    len = (strlen(fname) > 256 ? strlen(fname) : 256)	+(strlen(path) > 256 ? strlen(path) : 256)+2;    f_dir = (char*)malloc(len);    f_fname = (char*)malloc(len);

⌨️ 快捷键说明

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