Mercurial > mplayer.hg
annotate libmenu/menu_chapsel.c @ 36447:740a60d26cc0
Only detect a file as MPEG-PS if we can find at least 2 packets.
author | reimar |
---|---|
date | Wed, 11 Dec 2013 20:03:03 +0000 |
parents | 38a5d56c389c |
children | b28f3ff37ae7 |
rev | line source |
---|---|
25364 | 1 /* |
2 * Support chapter list and selection. | |
3 * | |
4 * Copyright (C) 2006-2007 Benjamin Zores <ben A geexbox P org> | |
5 * Copyright (C) 2007 Ulion <ulion A gmail P com> | |
6 * | |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
26743
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
25499
diff
changeset
|
19 * You should have received a copy of the GNU General Public License along |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
25499
diff
changeset
|
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
0f42fb42843c
Use standard license headers with standard formatting.
diego
parents:
25499
diff
changeset
|
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
25364 | 22 */ |
23 | |
24 #include <stdlib.h> | |
25 #include <stdio.h> | |
26 #include <string.h> | |
27 | |
28 #include "config.h" | |
29 | |
30 #include "m_struct.h" | |
31 #include "m_option.h" | |
32 #include "input/input.h" | |
33 | |
34 #include "stream/stream.h" | |
35 #include "libmpdemux/demuxer.h" | |
36 #include "access_mpcontext.h" | |
37 | |
38 #include "libmpcodecs/mp_image.h" | |
39 | |
40 #include "menu.h" | |
41 #include "menu_list.h" | |
42 | |
43 struct list_entry_s { | |
44 struct list_entry p; | |
45 int cid; | |
46 }; | |
47 | |
48 struct menu_priv_s { | |
49 menu_list_priv_t p; | |
50 char* title; | |
51 int auto_close; | |
52 char* fmt_with_time; | |
53 }; | |
54 | |
55 static struct menu_priv_s cfg_dflt = { | |
56 MENU_LIST_PRIV_DFLT, | |
57 "Select chapter", | |
58 0, | |
59 "${chapter_name} [${start}]" | |
60 }; | |
61 | |
62 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m) | |
63 | |
30957 | 64 static const m_option_t cfg_fields[] = { |
25364 | 65 MENU_LIST_PRIV_FIELDS, |
66 { "title", ST_OFF (title), CONF_TYPE_STRING, 0, 0, 0, NULL }, | |
67 { "auto-close", ST_OFF (auto_close), CONF_TYPE_FLAG, 0, 0, 1, NULL }, | |
25499 | 68 { "fmt-with-time", ST_OFF (fmt_with_time), CONF_TYPE_STRING, 0, 0, 0, NULL }, |
25364 | 69 { NULL, NULL, NULL, 0, 0, 0, NULL } |
70 }; | |
71 | |
72 static char *fmt_replace(const char *fmt, const char *chapter_name, | |
73 const char *start) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26743
diff
changeset
|
74 static const char ctag[] = "${chapter_name}"; |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26743
diff
changeset
|
75 static const char stag[] = "${start}"; |
25364 | 76 int l = strlen(fmt); |
77 int cl = strlen(chapter_name); | |
78 int sl = strlen(start); | |
35282
38a5d56c389c
Fix allocation that could in theory be too small for the terminating NULL.
reimar
parents:
30957
diff
changeset
|
79 char *str = malloc(l + cl + sl + 1); |
25364 | 80 char *p; |
81 strcpy(str, fmt); | |
82 p = strstr(str, ctag); | |
83 if (p) { | |
84 memmove(p+cl, p+sizeof(ctag)-1, str+l+1 - (p+sizeof(ctag)-1)); | |
85 memcpy(p, chapter_name, cl); | |
86 l -= sizeof(ctag) + 1; | |
87 l += cl; | |
88 } | |
89 p = strstr(str, stag); | |
90 if (p) { | |
91 memmove(p+sl, p+sizeof(stag)-1, str+l+1 - (p+sizeof(stag)-1)); | |
92 memcpy(p, start, sl); | |
93 l -= sizeof(stag) + 1; | |
94 l += sl; | |
95 } | |
96 return str; | |
97 } | |
98 | |
99 static int fill_menu (menu_t* menu) | |
100 { | |
101 list_entry_t* e; | |
102 int cid, chapter_num = 0; | |
103 int start_time; | |
104 demuxer_t* demuxer = mpctx_get_demuxer(menu->ctx); | |
105 | |
106 if (demuxer) | |
107 chapter_num = demuxer_chapter_count(demuxer); | |
108 if (chapter_num > 0) { | |
109 menu_list_init (menu); | |
110 for (cid = 0; cid < chapter_num; ++cid) | |
111 if ((e = calloc (1, sizeof (list_entry_t))) != NULL) { | |
112 e->cid = cid + 1; | |
113 e->p.next = NULL; | |
114 e->p.txt = demuxer_chapter_display_name(demuxer, cid); | |
115 start_time = demuxer_chapter_time(demuxer, cid, NULL); | |
116 if (start_time >= 0) { | |
117 char timestr[13]; | |
118 char *tmp; | |
119 int hour = start_time / 3600; | |
120 int minute = (start_time / 60) % 60; | |
121 int seconds = start_time % 60; | |
122 sprintf(timestr,"%02d:%02d:%02d", hour, minute, seconds); | |
123 | |
124 tmp = fmt_replace(menu->priv->fmt_with_time, e->p.txt, timestr); | |
125 free(e->p.txt); | |
126 e->p.txt = tmp; | |
127 } | |
128 menu_list_add_entry(menu, e); | |
129 } | |
130 } | |
131 else | |
132 menu_list_read_cmd(menu, MENU_CMD_CANCEL); | |
133 | |
134 return 1; | |
135 } | |
136 | |
137 static void read_cmd (menu_t* menu, int cmd) | |
138 { | |
139 switch (cmd) { | |
140 case MENU_CMD_RIGHT: | |
141 case MENU_CMD_OK: { | |
142 char cmdbuf[26]; | |
143 sprintf(cmdbuf, "seek_chapter %d 1", menu->priv->p.current->cid); | |
144 mp_input_queue_cmd(mp_input_parse_cmd(cmdbuf)); | |
145 if (menu->priv->auto_close) | |
146 mp_input_queue_cmd(mp_input_parse_cmd("menu hide")); | |
147 break; | |
148 } | |
149 default: | |
150 menu_list_read_cmd (menu, cmd); | |
151 } | |
152 } | |
153 | |
154 static void close_cs (menu_t* menu) | |
155 { | |
156 menu_list_uninit (menu, NULL); | |
157 } | |
158 | |
159 static int open_cs (menu_t* menu, char* args) | |
160 { | |
161 args = NULL; | |
162 | |
163 menu->draw = menu_list_draw; | |
164 menu->read_cmd = read_cmd; | |
165 menu->close = close_cs; | |
166 menu->priv->p.title = menu->priv->title; | |
167 | |
168 return fill_menu (menu); | |
169 } | |
170 | |
171 const menu_info_t menu_info_chapsel = { | |
172 "Chapter selector menu", | |
173 "chapsel", | |
174 "Benjamin Zores & Ulion", | |
175 "", | |
176 { | |
177 "chapsel_cfg", | |
178 sizeof(struct menu_priv_s), | |
179 &cfg_dflt, | |
180 cfg_fields | |
181 }, | |
182 open_cs | |
183 }; |