示例#1
0
static MPLS_PL*
_process_file(char *name, MPLS_PL *pl_list[], int pl_count)
{
    MPLS_PL *pl;

    pl = bd_read_mpls(name);
    if (pl == NULL) {
        fprintf(stderr, "Parse failed: %s\n", name);
        return NULL;
    }
    if (seconds) {
        if (!_filter_short(pl, seconds)) {
            bd_free_mpls(pl);
            return NULL;
        }
    }
    if (repeats) {
        if (!_filter_repeats(pl, repeats)) {
            bd_free_mpls(pl);
            return NULL;
        }
    }
    if (dups) {
        if (!_filter_dup(pl_list, pl_count, pl)) {
            bd_free_mpls(pl);
            return NULL;
        }
    }
    if (verbose) {
        indent_printf(0, 
                    "%s -- Num Clips: %3d , Duration: minutes %4u:%02u",
                    basename(name),
                    pl->list_count,
                    _pl_duration(pl) / (45000 * 60),
                    (_pl_duration(pl) / 45000) % 60);
        _show_ai(pl, 1);
    } else {
        indent_printf(0, "%s -- Duration: minutes %4u:%02u",
                    basename(name),
                    _pl_duration(pl) / (45000 * 60),
                    (_pl_duration(pl) / 45000) % 60);
    }
    if (playlist_info) {
        _show_details(pl, 1);
    }
    if (chapter_marks) {
        _show_marks(pl, 1);
    }
    if (pip_metadata) {
        _show_pip_metadata(pl, 1);
    }
    if (clip_list) {
        _show_clip_list(pl, 1);
    }
    if (sub_paths) {
        _show_sub_paths(pl, 1);
        _show_sub_paths_ss(pl, 1);
    }
    return pl;
}
示例#2
0
static int
_filter_dup(MPLS_PL *pl_list[], int count, MPLS_PL *pl)
{
    int ii, jj;

    for (ii = 0; ii < count; ii++) {
        if (pl->list_count != pl_list[ii]->list_count ||
            _pl_duration(pl) != _pl_duration(pl_list[ii])) {
            continue;
        }
        for (jj = 0; jj < pl->list_count; jj++) {
            MPLS_PI *pi1, *pi2;

            pi1 = &pl->play_item[jj];
            pi2 = &pl_list[ii]->play_item[jj];

            if (memcmp(pi1->clip[0].clip_id, pi2->clip[0].clip_id, 5) != 0 ||
                pi1->in_time != pi2->in_time ||
                pi1->out_time != pi2->out_time) {
                break;
            }
        }
        if (jj != pl->list_count) {
            continue;
        }
        return 0;
    }
    return 1;
}
示例#3
0
static int
_filter_short(MPLS_PL *pl, unsigned int seconds)
{
    // Ignore short playlists
    if (_pl_duration(pl) / 45000 <= seconds) {
        return 0;
    }
    return 1;
}
示例#4
0
static int _pl_guess_main_title(MPLS_PL *p1, MPLS_PL *p2)
{
    uint32_t d1 = _pl_duration(p1);
    uint32_t d2 = _pl_duration(p2);

    /* if both longer than 30 min */
    if (d1 > 30*60*45000 && d2 > 30*60*45000) {

        /* prefer many chapters over no chapters */
        int chap1 = _pl_chapter_count(p1);
        int chap2 = _pl_chapter_count(p2);
        int chap_diff = chap2 - chap1;
        if ((chap1 < 2 || chap2 < 2) && (chap_diff < -5 || chap_diff > 5)) {
            /* chapter count differs by more than 5 */
            BD_DEBUG(DBG_MAIN_PL, "main title: chapter count difference %d\n", chap_diff);
            return chap_diff;
        }

        /* Check video: prefer HD over SD, H.264/VC1 over MPEG1/2 */
        int vid_diff = _cmp_video_props(p1, p2);
        if (vid_diff) {
            BD_DEBUG(DBG_MAIN_PL, "main title: video properties difference %d\n", vid_diff);
            return vid_diff;
        }

        /* compare audio: prefer HD audio */
        int aud_diff = _cmp_audio_props(p1, p2);
        if (aud_diff) {
            BD_DEBUG(DBG_MAIN_PL, "main title: audio properties difference %d\n", aud_diff);
            return aud_diff;
        }
    }

    /* compare playlist duration, select longer playlist */
    if (d1 < d2) {
        return 1;
    }
    if (d1 > d2) {
        return -1;
    }

    return 0;
}
示例#5
0
char* nav_find_main_title(const char *root)
{
    BD_DIR_H *dir;
    BD_DIRENT ent;
    char *path = NULL;
    MPLS_PL **pl_list = NULL;
    MPLS_PL **tmp = NULL;
    MPLS_PL *pl = NULL;
    unsigned count, ii, jj, pl_list_size = 0;
    int res;
    char longest[11];

    BD_DEBUG(DBG_NAV, "Root: %s:\n", root);
    path = str_printf("%s" DIR_SEP "BDMV" DIR_SEP "PLAYLIST", root);

    dir = dir_open(path);
    if (dir == NULL) {
        fprintf(stderr, "Failed to open dir: %s\n", path);
        X_FREE(path);
        return NULL;
    }
    X_FREE(path);

    ii = jj = 0;
    for (res = dir_read(dir, &ent); !res; res = dir_read(dir, &ent)) {

        if (ent.d_name[0] == '.') {
            continue;
        }
        path = str_printf("%s" DIR_SEP "BDMV" DIR_SEP "PLAYLIST" DIR_SEP "%s",
                          root, ent.d_name);

        if (ii >= pl_list_size) {
            pl_list_size += 100;
            tmp = realloc(pl_list, pl_list_size * sizeof(MPLS_PL*));
            if (tmp == NULL) {
                X_FREE(path);
                break;
            }
            pl_list = tmp;
        }
        pl = mpls_parse(path, 0);
        X_FREE(path);
        if (pl != NULL) {
            if (_filter_dup(pl_list, ii, pl) &&
                _filter_repeats(pl, 2)) {
                pl_list[ii] = pl;
                if (_pl_duration(pl_list[ii]) >= _pl_duration(pl_list[jj])) {
                    strncpy(longest, ent.d_name, 11);
                    longest[10] = '\0';
                    jj = ii;
                }
                ii++;
            } else {
                mpls_free(pl);
            }
        }
    }
    dir_close(dir);

    count = ii;
    for (ii = 0; ii < count; ii++) {
        mpls_free(pl_list[ii]);
    }
    if (count > 0) {
        char *str = (char*)malloc(strlen(longest) + 1);
        strcpy(str, longest);
        return str;
    } else {
        return NULL;
    }
}
示例#6
0
NAV_TITLE_LIST* nav_get_title_list(const char *root, uint32_t flags)
{
    BD_DIR_H *dir;
    BD_DIRENT ent;
    char *path = NULL;
    MPLS_PL **pl_list = NULL;
    MPLS_PL *pl = NULL;
    unsigned int ii, pl_list_size = 0;
    int res;
    NAV_TITLE_LIST *title_list;
    unsigned int title_info_alloc = 100;

    title_list = calloc(1, sizeof(NAV_TITLE_LIST));
    title_list->title_info = calloc(title_info_alloc, sizeof(NAV_TITLE_INFO));

    BD_DEBUG(DBG_NAV, "Root: %s:\n", root);
    path = str_printf("%s" DIR_SEP "BDMV" DIR_SEP "PLAYLIST", root);

    dir = dir_open(path);
    if (dir == NULL) {
        BD_DEBUG(DBG_NAV, "Failed to open dir: %s\n", path);
        X_FREE(path);
        X_FREE(title_list);
        return NULL;
    }
    X_FREE(path);

    ii = 0;
    for (res = dir_read(dir, &ent); !res; res = dir_read(dir, &ent)) {

        if (ent.d_name[0] == '.') {
            continue;
        }
        path = str_printf("%s" DIR_SEP "BDMV" DIR_SEP "PLAYLIST" DIR_SEP "%s",
                          root, ent.d_name);

        if (ii >= pl_list_size) {
            MPLS_PL **tmp = NULL;

            pl_list_size += 100;
            tmp = realloc(pl_list, pl_list_size * sizeof(MPLS_PL*));
            if (tmp == NULL) {
                X_FREE(path);
                break;
            }
            pl_list = tmp;
        }
        pl = mpls_parse(path, 0);
        X_FREE(path);
        if (pl != NULL) {
            if ((flags & TITLES_FILTER_DUP_TITLE) &&
                !_filter_dup(pl_list, ii, pl)) {
                mpls_free(pl);
                continue;
            }
            if ((flags & TITLES_FILTER_DUP_CLIP) && !_filter_repeats(pl, 2)) {
                mpls_free(pl);
                continue;
            }
            if (ii >= title_info_alloc) {
                NAV_TITLE_INFO *tmp = NULL;
                title_info_alloc += 100;

                tmp = realloc(title_list->title_info,
                              title_info_alloc * sizeof(NAV_TITLE_INFO));
                if (tmp == NULL) {
                    break;
                }
                title_list->title_info = tmp;
            }
            pl_list[ii] = pl;
            strncpy(title_list->title_info[ii].name, ent.d_name, 11);
            title_list->title_info[ii].name[10] = '\0';
            title_list->title_info[ii].ref = ii;
            title_list->title_info[ii].mpls_id  = atoi(ent.d_name);
            title_list->title_info[ii].duration = _pl_duration(pl_list[ii]);
            ii++;
        }
    }
    dir_close(dir);

    title_list->count = ii;
    for (ii = 0; ii < title_list->count; ii++) {
        mpls_free(pl_list[ii]);
    }
    return title_list;
}
示例#7
0
NAV_TITLE_LIST* nav_get_title_list(BD_DISC *disc, uint32_t flags, uint32_t min_title_length)
{
    BD_DIR_H *dir;
    BD_DIRENT ent;
    MPLS_PL **pl_list = NULL;
    MPLS_PL *pl = NULL;
    unsigned int ii, pl_list_size = 0;
    int res;
    NAV_TITLE_LIST *title_list;
    unsigned int title_info_alloc = 100;

    dir = disc_open_dir(disc, "BDMV" DIR_SEP "PLAYLIST");
    if (dir == NULL) {
        return NULL;
    }

    title_list = calloc(1, sizeof(NAV_TITLE_LIST));
    title_list->title_info = calloc(title_info_alloc, sizeof(NAV_TITLE_INFO));

    ii = 0;
    for (res = dir_read(dir, &ent); !res; res = dir_read(dir, &ent)) {

        if (ent.d_name[0] == '.') {
            continue;
        }
        if (ii >= pl_list_size) {
            MPLS_PL **tmp = NULL;

            pl_list_size += 100;
            tmp = realloc(pl_list, pl_list_size * sizeof(MPLS_PL*));
            if (tmp == NULL) {
                break;
            }
            pl_list = tmp;
        }
        pl = mpls_get(disc, ent.d_name);
        if (pl != NULL) {
            if ((flags & TITLES_FILTER_DUP_TITLE) &&
                !_filter_dup(pl_list, ii, pl)) {
                mpls_free(pl);
                continue;
            }
            if ((flags & TITLES_FILTER_DUP_CLIP) && !_filter_repeats(pl, 2)) {
                mpls_free(pl);
                continue;
            }
            if (min_title_length > 0 &&
                _pl_duration(pl) < min_title_length*45000) {
                mpls_free(pl);
                continue;
            }
            if (ii >= title_info_alloc) {
                NAV_TITLE_INFO *tmp = NULL;
                title_info_alloc += 100;

                tmp = realloc(title_list->title_info,
                              title_info_alloc * sizeof(NAV_TITLE_INFO));
                if (tmp == NULL) {
                    break;
                }
                title_list->title_info = tmp;
            }
            pl_list[ii] = pl;

            /* main title guessing */
            if (_filter_dup(pl_list, ii, pl) &&
                _filter_repeats(pl, 2)) {

                if (_pl_guess_main_title(pl_list[ii], pl_list[title_list->main_title_idx]) <= 0) {
                    title_list->main_title_idx = ii;
                }
            }

            strncpy(title_list->title_info[ii].name, ent.d_name, 11);
            title_list->title_info[ii].name[10] = '\0';
            title_list->title_info[ii].ref = ii;
            title_list->title_info[ii].mpls_id  = atoi(ent.d_name);
            title_list->title_info[ii].duration = _pl_duration(pl_list[ii]);
            ii++;
        }
    }
    dir_close(dir);

    title_list->count = ii;
    for (ii = 0; ii < title_list->count; ii++) {
        mpls_free(pl_list[ii]);
    }
    X_FREE(pl_list);
    return title_list;
}
int BD_Parser(FILE *fp, FileInfo *finfo, int is_dir)
{
	int nRet = 0;
	int ii;
	int title_guess, title_count;
	uint64_t max_duration = 0;
	uint64_t max_duration2 = 0;
	MPLS_PL * pl = NULL, * pl2 = NULL, * def_pl;
	BLURAY  *bd = NULL;
	parse_priv * par_priv = NULL;
	BLURAY_TITLE_MAX_DUR *title_max = NULL;
	int title_id[2] = {-1};
	int mpls_id[2] = {-1};

	mp_msg("BD_Parser\n");
	if (finfo->priv != NULL)
	{
		par_priv = (parse_priv *)finfo->priv;
		bd = par_priv->bd;
		title_count = par_priv->title_num;
		free(par_priv);
		finfo->priv = NULL;
	} else {
		bd = bd_open(finfo->filepath, NULL);
		if (bd)
			title_count = bd_get_titles(bd, TITLES_RELEVANT);
	}
	//goto error_end;

	if (bd)
	{
		title_max = bd_get_title_max2_dur(bd);
		if (title_max != NULL)
		{
			pl = bd_title_filter(bd, title_max->dur_first_count, title_max->dur_first, is_dir, finfo->filepath, &title_id[0], &mpls_id[0]);
			if (title_max->dur_second_count > 0)
			{
				pl2 = bd_title_filter(bd, title_max->dur_second_count, title_max->dur_second, is_dir, finfo->filepath, &title_id[1], &mpls_id[1]);
			}
			mp_msg("title_id: %d %d, mpls_id: %d %d\n", title_id[0], title_id[1],
					mpls_id[0], mpls_id[1]);
			title_guess = title_id[0];

			bd_free_title_max2_dur(title_max);
		}

		def_pl = pl;
		//if (pl2 != NULL)
		if (pl2 != NULL && pl != NULL)
		{
			MPLS_PI *pi, *pi2;
			pi = &pl->play_item[0];
			pi2 = &pl2->play_item[0];
			mp_msg("playlist 1: c: %d, v: %d, a: %d, s: %d, d: %d\n", bd_get_chapters(pl),
					pi->stn.num_video, pi->stn.num_audio, pi->stn.num_pg, _pl_duration(pl)/45000);
			mp_msg("playlist 2: c: %d, v: %d, a: %d, s: %d, d: %d\n", bd_get_chapters(pl2),
					pi2->stn.num_video, pi2->stn.num_audio, pi2->stn.num_pg, _pl_duration(pl2)/45000);
			if ((bd_get_chapters(pl) < bd_get_chapters(pl2)) &&
					(pi->stn.num_audio <= pi2->stn.num_audio) )
			{
				// playlist 2 have more chapters and audio use it.
				def_pl = pl2;
				title_guess = title_id[1];
			} else {
				if ((pl->list_count > 0) && (pl2->list_count > 0))
				{
					if ( (pi2->stn.num_audio >= pi->stn.num_audio) &&
							(pi2->stn.num_pg > pi->stn.num_pg) &&
							(bd_get_chapters(pl2) >= bd_get_chapters(pl)) )	//Barry 2011-07-29 fix mantis: 5605
					{
						def_pl = pl2;
						title_guess = title_id[1];
					}
#if 1	//Barry 2011-07-13 fix mantis: 5192
					if ((_pl_duration(pl)/45000) > 60000)
					{
						def_pl = pl2;
						title_guess = title_id[1];
					}
#endif
				}
			}
		}
		else if (pl2 != NULL && pl == NULL)
		{
			// playlist 2 have more chapters and audio use it.
			def_pl = pl2;
			title_guess = title_id[1];
			//printf("***********  Switch to playlist 2 **********\n");
		}

		nRet = set_mpls_info(def_pl, finfo);
		if (nRet == 1)
		{
			MPLS_PI *pi;
			int chapters = bd_get_chapters(def_pl);
			((bd_priv_t *)finfo->priv)->chapter_num = chapters;
			((bd_priv_t *)finfo->priv)->title = title_guess;
			pi = &def_pl->play_item[0];
			if (pi != NULL)
				((bd_priv_t *)finfo->priv)->file_id = atoi(pi->clip[0].clip_id);
		}

error_end:
		if (pl != NULL) mpls_free(pl);
		if (pl2 != NULL) mpls_free(pl2);
		if (bd != NULL) bd_close(bd);
	}

	return nRet;
}
static MPLS_PL * bd_title_filter(BLURAY *bd, uint32_t count, BLURAY_TITLE_MPLS_ID *title, int is_dir, char *filepath, int *title_id, int *mpls_id)
{
	MPLS_PL *pl = NULL, *pl_tmp = NULL;
	MPLS_PI *pi = NULL, *pi_tmp = NULL;
	int chapter_count, chapter_count_tmp;
	char *path = NULL;
	int ii;

	for (ii = 0; ii < count; ii++)
	{
		if (is_dir == 1) {
			path = str_printf("%s/BDMV/PLAYLIST/%05d.mpls", filepath, title[ii].mpls_id);
		} else {
			path = str_printf("/BDMV/PLAYLIST/%05d.mpls", title[ii].mpls_id);
		}
		if (pl == NULL)
		{
			pl = mpls_parse(path, 0, bd_get_udfdata(bd));
			if (pl != NULL)
			{
				pi = &pl->play_item[0];
				*title_id = (int)title[ii].title_id;
				*mpls_id = (int)title[ii].mpls_id;
				chapter_count = bd_get_chapters(pl);
			}
		} else {
			pl_tmp = mpls_parse(path, 0, bd_get_udfdata(bd));
			if (pl_tmp != NULL)
			{
				pi_tmp = &pl_tmp->play_item[0];
				chapter_count_tmp = bd_get_chapters(pl_tmp); 
				mp_msg("filter playlist 1: c: %d, v: %d, a: %d, s: %d, d: %d\n", chapter_count,
						pi->stn.num_video, pi->stn.num_audio, pi->stn.num_pg, _pl_duration(pl)/45000);
				mp_msg("filter playlist 2: c: %d, v: %d, a: %d, s: %d, d: %d\n", chapter_count_tmp,
						pi_tmp->stn.num_video, pi_tmp->stn.num_audio, pi_tmp->stn.num_pg, _pl_duration(pl_tmp)/45000);
				if ( ((pi_tmp->stn.num_pg > 0) && (pi->stn.num_pg > pi_tmp->stn.num_pg)) && \
						((pi_tmp->stn.num_audio > 0) && (pi_tmp->stn.num_audio >= pi->stn.num_audio - 1)) && \
						(chapter_count_tmp >= chapter_count)
						)
				{
					mpls_free(pl);
					pl = pl_tmp;
					pi = &pl->play_item[0];
					chapter_count = chapter_count_tmp;
					*title_id = (int)title[ii].title_id;
					*mpls_id = (int)title[ii].mpls_id;
				} else {
#if 1	//Barry 2011-07-13 fix mantis: 5192
					if ((_pl_duration(pl)/45000) > 60000)
					{
						mpls_free(pl);
						pl = pl_tmp;
						pi = &pl->play_item[0];
						chapter_count = chapter_count_tmp;
						*title_id = (int)title[ii].title_id;
						*mpls_id = (int)title[ii].mpls_id;
					}
					else
#endif
						mpls_free(pl_tmp);
				}
			}
		}
		if (path != NULL) free(path);
	}

	return pl;
}
static int set_mpls_info(MPLS_PL *pl, FileInfo *finfo)
{
		int nRet = 0;	
		int ii, jj;
		MPLS_PI *pi = NULL;
		MPLS_STREAM *ss;
		bd_priv_t *bd_priv; 

		finfo->priv = calloc(1, sizeof(bd_priv_t));
		if (finfo->priv == NULL)
		{
			mp_msg("malloc priv data error!!!");
			return nRet;
		}
		bd_priv = (bd_priv_t *)finfo->priv;

#if 1
		//for (ii = 0; ii < pl->list_count; ii++) {
		for (ii = 0; ii < 1; ii++) {
			pi = &pl->play_item[ii];
			// video 
			bd_priv->video_num = pi->stn.num_video;
			bd_priv->video_list =
				(list_priv_t *)calloc(1, sizeof(list_priv_t) * bd_priv->video_num);
			for (jj = 0; jj < pi->stn.num_video; jj++) {
				mp_msg("Video Stream %d:\n", jj);
				//_show_stream(&pi->stn.video[jj]);
				bd_priv->video_list[jj].sid = pi->stn.video[jj].pid;
				bd_priv->video_list[jj].type = pi->stn.video[jj].coding_type;
			}
			// audio
			bd_priv->audio_num = pi->stn.num_audio;
			bd_priv->audio_list =
				(list_priv_t *)calloc(1, sizeof(list_priv_t) * bd_priv->audio_num);
			for (jj = 0; jj < pi->stn.num_audio; jj++) {
				mp_msg("Audio Stream %d:\n", jj);
				//_show_stream(&pi->stn.audio[jj]);
				bd_priv->audio_list[jj].sid = pi->stn.audio[jj].pid;
				bd_priv->audio_list[jj].type = pi->stn.audio[jj].coding_type;
				bd_priv->audio_list[jj].format = pi->stn.audio[jj].format;
				memcpy(bd_priv->audio_list[jj].lang ,pi->stn.audio[jj].lang, 4);
			}
			// subtitle
			//bd_priv->sub_num = pi->stn.num_pg + pi->stn.num_pip_pg;
			bd_priv->sub_num = pi->stn.num_pg;
			bd_priv->sub_list =
				(list_priv_t *)calloc(1, sizeof(list_priv_t) * bd_priv->sub_num);
			for (jj = 0; jj < bd_priv->sub_num; jj++) {
				if (jj < pi->stn.num_pg) {
					mp_msg("Presentation Graphics Stream %d:\n", jj);
				} else {
					mp_msg("PIP Presentation Graphics Stream %d:\n", jj);
				}
				//_show_stream(&pi->stn.pg[jj]);
				bd_priv->sub_list[jj].sid = pi->stn.pg[jj].pid;
				bd_priv->sub_list[jj].type = pi->stn.pg[jj].coding_type;
				memcpy(bd_priv->sub_list[jj].lang ,pi->stn.pg[jj].lang, 4);
			}
		}
#endif 

		if (pl->list_count > 0)
			pi = &pl->play_item[0];
		if (pi != NULL)
		{
			if (pi->stn.num_video > 0)
			{
				ss = &pi->stn.video[0];
				//_show_stream(ss);
				if (_set_video_stream(finfo, ss))
				{
					finfo->bVideo = 1;
				}
			}
			for (ii = 0; ii < pi->stn.num_audio; ii++)
			{
				ss = &pi->stn.audio[ii];
				//_show_stream(ss);
				if (_set_audio_stream(finfo, ss))
				{
					if (check_audio_type(finfo->AudioType, finfo->wf.nChannels, finfo->hw_a_flag) != 0) {
						finfo->bAudio = 1;
						break;
					}
				}
			}
			if (finfo->bVideo || finfo->bAudio)
				nRet = 1;
		}

		if (nRet == 0)
		{
			if (finfo->priv != NULL)
				free(finfo->priv);
		}
		
		finfo->FileDuration = _pl_duration(pl) / 45000;
		return nRet;
}