X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fgme.c;h=5d6d214a1bac343cf5ee444c58535fcc8777e72c;hb=45f98242300f76b6531d8c344214f78f8212221e;hp=77ce03a773a2b9928a22cd75d701f5751fac72dc;hpb=fac9bec69abe4f731e9e27a420e5cacaff804918;p=vlc diff --git a/modules/demux/gme.c b/modules/demux/gme.c index 77ce03a773..5d6d214a1b 100644 --- a/modules/demux/gme.c +++ b/modules/demux/gme.c @@ -5,20 +5,20 @@ /***************************************************************************** * Copyright © 2010 Rémi Denis-Courmont * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - ****************************************************************************/ + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ #ifdef HAVE_CONFIG_H # include @@ -29,8 +29,8 @@ #include #include +#include #include -#include #include #include @@ -52,8 +52,13 @@ vlc_module_end () struct demux_sys_t { Music_Emu *emu; + unsigned track_id; + es_out_id_t *es; date_t pts; + + input_title_t **titlev; + unsigned titlec; }; @@ -70,6 +75,7 @@ static int Open (vlc_object_t *obj) || size > LONG_MAX /* too big for GME */) return VLC_EGENERIC; + /* Auto detection */ const uint8_t *peek; if (stream_Peek (demux->s, &peek, 4) < 4) return VLC_EGENERIC; @@ -79,6 +85,7 @@ static int Open (vlc_object_t *obj) return VLC_EGENERIC; msg_Dbg (obj, "detected file type %s", type); + /* Initialization */ demux_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; @@ -90,7 +97,7 @@ static int Open (vlc_object_t *obj) return VLC_ENOMEM; } gme_load_custom (sys->emu, Reader, size, demux->s); - gme_start_track (sys->emu, 0); + gme_start_track (sys->emu, sys->track_id = 0); es_format_t fmt; es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_S16N); @@ -106,6 +113,31 @@ static int Open (vlc_object_t *obj) date_Init (&sys->pts, RATE, 1); date_Set (&sys->pts, 0); + /* Titles */ + unsigned n = gme_track_count (sys->emu); + sys->titlev = malloc (n * sizeof (*sys->titlev)); + if (unlikely(sys->titlev == NULL)) + n = 0; + sys->titlec = n; + for (unsigned i = 0; i < n; i++) + { + input_title_t *title = vlc_input_title_New (); + sys->titlev[i] = title; + if (unlikely(title == NULL)) + continue; + + gme_info_t *infos; + if (gme_track_info (sys->emu, &infos, i)) + continue; + msg_Dbg (obj, "track %u: %s %d ms", i, infos->song, infos->length); + if (infos->length != -1) + title->i_length = infos->length * INT64_C(1000); + if (infos->song[0]) + title->psz_name = strdup (infos->song); + gme_free_info (infos); + } + + /* Callbacks */ demux->pf_demux = Demux; demux->pf_control = Control; demux->p_sys = sys; @@ -118,6 +150,9 @@ static void Close (vlc_object_t *obj) demux_t *demux = (demux_t *)obj; demux_sys_t *sys = demux->p_sys; + for (unsigned i = 0, n = sys->titlec; i < n; i++) + vlc_input_title_Delete (sys->titlev[i]); + free (sys->titlev); gme_delete (sys->emu); free (sys); } @@ -139,12 +174,19 @@ static int Demux (demux_t *demux) { demux_sys_t *sys = demux->p_sys; + /* Next track */ if (gme_track_ended (sys->emu)) { - msg_Dbg (demux, "track ended"); - return 0; + msg_Dbg (demux, "track %u ended", sys->track_id); + if (++sys->track_id >= (unsigned)gme_track_count (sys->emu)) + return 0; + + demux->info.i_update |= INPUT_UPDATE_TITLE; + demux->info.i_title = sys->track_id; + gme_start_track (sys->emu, sys->track_id); } + block_t *block = block_Alloc (2 * 2 * SAMPLES); if (unlikely(block == NULL)) return 0; @@ -171,27 +213,85 @@ static int Control (demux_t *demux, int query, va_list args) switch (query) { - case DEMUX_GET_POSITION: // TODO + case DEMUX_GET_POSITION: { double *pos = va_arg (args, double *); - *pos = 0.; + + if (unlikely(sys->track_id >= sys->titlec) + || (sys->titlev[sys->track_id]->i_length == 0)) + *pos = 0.; + else + *pos = (double)(gme_tell (sys->emu)) + / (double)(sys->titlev[sys->track_id]->i_length / 1000); + return VLC_SUCCESS; + } + + case DEMUX_SET_POSITION: + { + double pos = va_arg (args, double); + + if (unlikely(sys->track_id >= sys->titlec) + || (sys->titlev[sys->track_id]->i_length == 0)) + break; + + int seek = (sys->titlev[sys->track_id]->i_length / 1000) * pos; + if (seek > INT_MAX || gme_seek (sys->emu, seek)) + break; + return VLC_SUCCESS; + } + + case DEMUX_GET_LENGTH: + { + int64_t *v = va_arg (args, int64_t *); + + if (unlikely(sys->track_id >= sys->titlec) + || (sys->titlev[sys->track_id]->i_length == 0)) + break; + *v = sys->titlev[sys->track_id]->i_length; return VLC_SUCCESS; } - //case DEMUX_SET_POSITION: TODO - //case DEMUX_GET_LENGTH: TODO case DEMUX_GET_TIME: { int64_t *v = va_arg (args, int64_t *); - *v = gme_tell (sys->emu) * 1000; + *v = gme_tell (sys->emu) * INT64_C(1000); return VLC_SUCCESS; } case DEMUX_SET_TIME: { - int64_t v = va_arg (args, int64_t); - if (v > INT_MAX || gme_seek (sys->emu, v / 1000)) - return VLC_EGENERIC; + int64_t v = va_arg (args, int64_t) / 1000; + if (v > INT_MAX || gme_seek (sys->emu, v)) + break; + return VLC_SUCCESS; + } + + case DEMUX_GET_TITLE_INFO: + { + input_title_t ***titlev = va_arg (args, input_title_t ***); + int *titlec = va_arg (args, int *); + *(va_arg (args, int *)) = 0; /* Title offset */ + *(va_arg (args, int *)) = 0; /* Chapter offset */ + + unsigned n = sys->titlec; + *titlev = malloc (sizeof (**titlev) * n); + if (unlikely(titlev == NULL)) + n = 0; + *titlec = n; + for (unsigned i = 0; i < n; i++) + (*titlev)[i] = vlc_input_title_Duplicate (sys->titlev[i]); + return VLC_SUCCESS; + } + + case DEMUX_SET_TITLE: + { + int track_id = va_arg (args, int); + if (track_id >= gme_track_count (sys->emu)) + break; + gme_start_track (sys->emu, track_id); + demux->info.i_update |= INPUT_UPDATE_TITLE; + demux->info.i_title = track_id; + sys->track_id = track_id; return VLC_SUCCESS; } }