-
Notifications
You must be signed in to change notification settings - Fork 5
/
dvd_subtitles.c
156 lines (109 loc) · 3.88 KB
/
dvd_subtitles.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "dvd_subtitles.h"
/** Subtitles **/
/**
* Get the number of subtitle streams for a track
*
*/
uint8_t dvd_track_subtitles(ifo_handle_t *vts_ifo) {
if(vts_ifo->vtsi_mat == NULL)
return 0;
uint8_t subtitles = vts_ifo->vtsi_mat->nr_of_vts_subp_streams;
return subtitles;
}
/**
* Get the number of subtitle streams marked as active.
*
*/
uint8_t dvd_track_active_subtitles(ifo_handle_t *vmg_ifo, ifo_handle_t *vts_ifo, uint16_t title_track) {
if(vts_ifo->vts_pgcit == NULL || vts_ifo->vts_ptt_srpt == NULL || vts_ifo->vts_ptt_srpt->title == NULL)
return 0;
uint8_t ttn = dvd_track_ttn(vmg_ifo, title_track);
pgcit_t *vts_pgcit = vts_ifo->vts_pgcit;
pgc_t *pgc = vts_pgcit->pgci_srp[vts_ifo->vts_ptt_srpt->title[ttn - 1].ptt[0].pgcn - 1].pgc;
uint8_t idx = 0;
uint8_t active_subtitles = 0;
if(!pgc)
return 0;
for(idx = 0; idx < DVD_SUBTITLE_STREAM_LIMIT; idx++) {
if(pgc->subp_control[idx] & 0x80000000)
active_subtitles++;
}
return active_subtitles;
}
/**
* Check if a subtitle stream is flagged as active or not.
*/
bool dvd_subtitle_active(ifo_handle_t *vmg_ifo, ifo_handle_t *vts_ifo, uint16_t title_track, uint8_t subtitle_track) {
if(vts_ifo->vts_pgcit == NULL || vts_ifo->vts_ptt_srpt == NULL || vts_ifo->vts_ptt_srpt->title == NULL)
return false;
uint8_t subtitles = dvd_track_subtitles(vts_ifo);
if(subtitle_track > DVD_SUBTITLE_STREAM_LIMIT || subtitle_track > subtitles)
return false;
uint8_t ttn = dvd_track_ttn(vmg_ifo, title_track);
pgcit_t *vts_pgcit = vts_ifo->vts_pgcit;
uint16_t pgcn = vts_ifo->vts_ptt_srpt->title[ttn - 1].ptt[0].pgcn;
pgc_t *pgc = vts_pgcit->pgci_srp[pgcn - 1].pgc;
if(!pgc)
return false;
if(pgc->subp_control[subtitle_track - 1] & 0x80000000)
return true;
return false;
}
/**
* Get the number of subtitle streams for a specific language
*/
uint8_t dvd_track_num_subtitle_lang_code_streams(ifo_handle_t *vts_ifo, char *lang_code) {
uint8_t streams = dvd_track_subtitles(vts_ifo);
if(streams == 0)
return 0;
uint8_t matches = 0;
uint8_t i = 0;
char str[DVD_SUBTITLE_LANG_CODE + 1] = {'\0'};
for(i = 0; i < streams; i++) {
dvd_subtitle_lang_code(str, vts_ifo, i);
if(strncmp(str, lang_code, DVD_SUBTITLE_LANG_CODE) == 0)
matches++;
}
return matches;
}
/**
* Check if a DVD track has a specific subtitle language
*/
bool dvd_track_has_subtitle_lang_code(ifo_handle_t *vts_ifo, char *lang_code) {
if(dvd_track_num_subtitle_lang_code_streams(vts_ifo, lang_code) > 0)
return true;
else
return false;
}
// Have dvd_debug check for issues here.
// FIXME I want to have some kind of distinguishment in here, and for audio tracks
// if it's an invalid language. If it's missing one, set it to unknown (for example)
// but if it's invalid, maybe guess that it's in English, or something? Dunno.
// Having a best-guess approach might not be bad, maybe even look at region codes
/**
* Get the lang code of a subtitle track for a title track
*
*/
void dvd_subtitle_lang_code(char *dest_str, ifo_handle_t *vts_ifo, uint8_t subtitle_track) {
char lang_code[3] = {'\0'};
subp_attr_t *subp_attr = NULL;
subp_attr = &vts_ifo->vtsi_mat->vts_subp_attr[subtitle_track];
if(subp_attr->type == 0 && subp_attr->lang_code == 0 && subp_attr->zero1 == 0 && subp_attr->zero2 == 0 && subp_attr->lang_extension == 0) {
return;
}
snprintf(lang_code, DVD_SUBTITLE_LANG_CODE + 1, "%c%c", subp_attr->lang_code >> 8, subp_attr->lang_code & 0xff);
if(!isalpha(lang_code[0]) || !isalpha(lang_code[1]))
return;
strncpy(dest_str, lang_code, DVD_SUBTITLE_LANG_CODE);
}
/**
* Get the stream ID for a subtitle, an index that starts at 0x20
*
* This is only here for lsdvd output compatability. The function just adds
* the index to 0x20.
*
* Possible ranges: 0x20 to 0x3f
*/
void dvd_subtitle_stream_id(char *dest_str, uint8_t subtitle_track) {
snprintf(dest_str, DVD_SUBTITLE_STREAM_ID + 1, "0x%x", 0x20 + subtitle_track);
}