+ msg_Warn( p_demux, "DEMUX_GET_FPS unimplemented !!" );
+ return VLC_EGENERIC;
+
+ case DEMUX_GET_META:
+ {
+ vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
+ MP4_Box_t *p_0xa9xxx;
+
+ MP4_Box_t *p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta/meta/ilst" );
+ if( p_udta == NULL )
+ {
+ p_udta = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
+ if( p_udta == NULL )
+ {
+ return VLC_EGENERIC;
+ }
+ }
+
+ for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;
+ p_0xa9xxx = p_0xa9xxx->p_next )
+ {
+
+ if( !p_0xa9xxx || !p_0xa9xxx->data.p_0xa9xxx )
+ continue;
+
+ /* FIXME FIXME: should convert from whatever the character
+ * encoding of MP4 meta data is to UTF-8. */
+#define SET(fct) do { char *psz_utf = strdup( p_0xa9xxx->data.p_0xa9xxx->psz_text ? p_0xa9xxx->data.p_0xa9xxx->psz_text : "" ); \
+ if( psz_utf ) { EnsureUTF8( psz_utf ); \
+ fct( p_meta, psz_utf ); free( psz_utf ); } } while(0)
+
+ /* XXX Becarefull p_udta can have box that are not 0xa9xx */
+ switch( p_0xa9xxx->i_type )
+ {
+ case FOURCC_0xa9nam: /* Full name */
+ SET( vlc_meta_SetTitle );
+ break;
+ case FOURCC_0xa9aut:
+ SET( vlc_meta_SetArtist );
+ break;
+ case FOURCC_0xa9ART:
+ SET( vlc_meta_SetArtist );
+ break;
+ case FOURCC_0xa9cpy:
+ SET( vlc_meta_SetCopyright );
+ break;
+ case FOURCC_0xa9day: /* Creation Date */
+ SET( vlc_meta_SetDate );
+ break;
+ case FOURCC_0xa9des: /* Description */
+ SET( vlc_meta_SetDescription );
+ break;
+ case FOURCC_0xa9gen: /* Genre */
+ SET( vlc_meta_SetGenre );
+ break;
+
+ case FOURCC_0xa9alb: /* Album */
+ SET( vlc_meta_SetAlbum );
+ break;
+
+ case FOURCC_0xa9swr:
+ case FOURCC_0xa9inf: /* Information */
+ case FOURCC_0xa9dir: /* Director */
+ case FOURCC_0xa9dis: /* Disclaimer */
+ case FOURCC_0xa9enc: /* Encoded By */
+ case FOURCC_0xa9trk: /* Track */
+ case FOURCC_0xa9cmt: /* Commment */
+ case FOURCC_0xa9url: /* URL */
+ case FOURCC_0xa9req: /* Requirements */
+ case FOURCC_0xa9fmt: /* Original Format */
+ case FOURCC_0xa9dsa: /* Display Source As */
+ case FOURCC_0xa9hst: /* Host Computer */
+ case FOURCC_0xa9prd: /* Producer */
+ case FOURCC_0xa9prf: /* Performers */
+ case FOURCC_0xa9ope: /* Original Performer */
+ case FOURCC_0xa9src: /* Providers Source Content */
+ case FOURCC_0xa9wrt: /* Writer */
+ case FOURCC_0xa9com: /* Composer */
+ case FOURCC_WLOC: /* Window Location */
+ /* TODO one day, but they aren't really meaningfull */
+ break;
+#undef SET
+
+ default:
+ break;
+ }
+ }
+ return VLC_SUCCESS;
+ }
+
+ case DEMUX_GET_TITLE_INFO:
+ {
+ input_title_t ***ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
+ int *pi_int = (int*)va_arg( args, int* );
+ int *pi_title_offset = (int*)va_arg( args, int* );
+ int *pi_seekpoint_offset = (int*)va_arg( args, int* );
+
+ if( !p_sys->p_title )
+ return VLC_EGENERIC;
+
+ *pi_int = 1;
+ *ppp_title = malloc( sizeof( input_title_t**) );
+ (*ppp_title)[0] = vlc_input_title_Duplicate( p_sys->p_title );
+ *pi_title_offset = 0;
+ *pi_seekpoint_offset = 0;
+ return VLC_SUCCESS;
+ }
+ case DEMUX_SET_TITLE:
+ {
+ const int i_title = (int)va_arg( args, int );
+ if( !p_sys->p_title || i_title != 0 )
+ return VLC_EGENERIC;
+ return VLC_SUCCESS;
+ }
+ case DEMUX_SET_SEEKPOINT:
+ {
+ const int i_seekpoint = (int)va_arg( args, int );
+ if( !p_sys->p_title )
+ return VLC_EGENERIC;
+ return Seek( p_demux, p_sys->p_title->seekpoint[i_seekpoint]->i_time_offset );
+ }
+
+ case DEMUX_SET_NEXT_DEMUX_TIME:
+ case DEMUX_SET_GROUP: