int Import_WPL( vlc_object_t* p_this ) { demux_t* p_demux = (demux_t*)p_this; CHECK_FILE(); if( !demux_IsPathExtension( p_demux, ".wpl" ) && !demux_IsPathExtension( p_demux, ".zpl" ) ) return VLC_EGENERIC; DEMUX_INIT_COMMON(); demux_sys_t* p_sys = p_demux->p_sys; uint8_t *p_peek; ssize_t i_peek = stream_Peek( p_demux->s, (const uint8_t **) &p_peek, 2048 ); if( unlikely( i_peek <= 0 ) ) { Close_WPL( p_this ); return VLC_EGENERIC; } stream_t *p_probestream = stream_MemoryNew( p_demux->s, p_peek, i_peek, true ); if( unlikely( !p_probestream ) ) { Close_WPL( p_this ); return VLC_EGENERIC; } p_sys->p_reader = xml_ReaderCreate( p_this, p_probestream ); if ( !p_sys->p_reader ) { msg_Err( p_demux, "Failed to create an XML reader" ); Close_WPL( p_this ); stream_Delete( p_probestream ); return VLC_EGENERIC; } const int i_flags = p_sys->p_reader->i_flags; p_sys->p_reader->i_flags |= OBJECT_FLAGS_QUIET; const char* psz_name; int type = xml_ReaderNextNode( p_sys->p_reader, &psz_name ); p_sys->p_reader->i_flags = i_flags; if ( type != XML_READER_STARTELEM || strcasecmp( psz_name, "smil" ) ) { msg_Err( p_demux, "Invalid WPL playlist. Root element should have been <smil>" ); Close_WPL( p_this ); stream_Delete( p_probestream ); return VLC_EGENERIC; } p_sys->p_reader = xml_ReaderReset( p_sys->p_reader, p_demux->s ); stream_Delete( p_probestream ); msg_Dbg( p_demux, "Found valid WPL playlist" ); return VLC_SUCCESS; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; char *psz_file; ifo_handle_t *p_vmg_file; if( !p_demux->psz_path || !*p_demux->psz_path ) { /* Only when selected */ if( !p_demux->psz_access || !*p_demux->psz_access ) return VLC_EGENERIC; psz_file = var_InheritString( p_this, "dvd" ); } else psz_file = strdup( p_demux->psz_path ); #ifdef WIN32 if( psz_file != NULL ) { size_t flen = strlen( psz_file ); if( flen > 0 && psz_file[flen - 1] == '\\' ) psz_file[flen - 1] = '\0'; } else psz_file = strdup(""); #endif if( unlikely(psz_file == NULL) ) return VLC_EGENERIC; /* Open dvdread */ const char *psz_path = ToLocale( psz_file ); dvd_reader_t *p_dvdread = DVDOpen( psz_path ); LocaleFree( psz_path ); if( p_dvdread == NULL ) { msg_Err( p_demux, "DVDRead cannot open source: %s", psz_file ); dialog_Fatal( p_demux, _("Playback failure"), _("DVDRead could not open the disc \"%s\"."), psz_file ); free( psz_file ); return VLC_EGENERIC; } free( psz_file ); /* Ifo allocation & initialisation */ if( !( p_vmg_file = ifoOpen( p_dvdread, 0 ) ) ) { msg_Warn( p_demux, "cannot open VMG info" ); return VLC_EGENERIC; } msg_Dbg( p_demux, "VMG opened" ); /* Fill p_demux field */ DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys; ps_track_init( p_sys->tk ); p_sys->i_sar_num = 0; p_sys->i_sar_den = 0; p_sys->i_title_cur_time = (mtime_t) 0; p_sys->i_cell_cur_time = (mtime_t) 0; p_sys->i_cell_duration = (mtime_t) 0; p_sys->p_dvdread = p_dvdread; p_sys->p_vmg_file = p_vmg_file; p_sys->p_title = NULL; p_sys->p_vts_file = NULL; p_sys->i_title = p_sys->i_chapter = -1; p_sys->i_mux_rate = 0; p_sys->i_angle = var_CreateGetInteger( p_demux, "dvdread-angle" ); if( p_sys->i_angle <= 0 ) p_sys->i_angle = 1; DemuxTitles( p_demux, &p_sys->i_angle ); if( DvdReadSetArea( p_demux, 0, 0, p_sys->i_angle ) != VLC_SUCCESS ) { Close( p_this ); msg_Err( p_demux, "DvdReadSetArea(0,0,%i) failed (can't decrypt DVD?)", p_sys->i_angle ); return VLC_EGENERIC; } /* Update default_pts to a suitable value for dvdread access */ var_Create( p_demux, "dvdread-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); return VLC_SUCCESS; }
/***************************************************************************** * Open: check file and initializes structures *****************************************************************************/ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; uint8_t hdr[20]; const uint8_t *p_peek; int i_cat; int i_samples, i_modulo; if( stream_Peek( p_demux->s , &p_peek, 4 ) < 4 ) return VLC_EGENERIC; if( memcmp( p_peek, ".snd", 4 ) ) return VLC_EGENERIC; /* skip signature */ stream_Read( p_demux->s, NULL, 4 ); /* cannot fail */ /* read header */ if( stream_Read( p_demux->s, hdr, 20 ) < 20 ) { msg_Err( p_demux, "cannot read" ); return VLC_EGENERIC; } if( GetDWBE( &hdr[0] ) < 24 ) { msg_Err( p_demux, "invalid file" ); return VLC_EGENERIC; } DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys; p_sys->i_time = 0; p_sys->i_header_size = GetDWBE( &hdr[0] ); /* skip extra header data */ if( p_sys->i_header_size > 24 ) { stream_Read( p_demux->s, NULL, p_sys->i_header_size - 24 ); } /* init fmt */ es_format_Init( &p_sys->fmt, AUDIO_ES, 0 ); p_sys->fmt.audio.i_rate = GetDWBE( &hdr[12] ); p_sys->fmt.audio.i_channels = GetDWBE( &hdr[16] ); #if 0 p_sys->au.i_header_size = GetDWBE( &p_sys->au.i_header_size ); p_sys->au.i_data_size = GetDWBE( &p_sys->au.i_data_size ); p_sys->au.i_encoding = GetDWBE( &p_sys->au.i_encoding ); p_sys->au.i_sample_rate = GetDWBE( &p_sys->au.i_sample_rate ); p_sys->au.i_channels = GetDWBE( &p_sys->au.i_channels ); #endif switch( GetDWBE( &hdr[8] ) ) { case AU_ALAW_8: /* 8-bit ISDN A-law */ p_sys->fmt.i_codec = VLC_CODEC_ALAW; p_sys->fmt.audio.i_bitspersample = 8; p_sys->fmt.audio.i_blockalign = 1 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_MULAW_8: /* 8-bit ISDN u-law */ p_sys->fmt.i_codec = VLC_CODEC_MULAW; p_sys->fmt.audio.i_bitspersample = 8; p_sys->fmt.audio.i_blockalign = 1 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_LINEAR_8: /* 8-bit linear PCM */ p_sys->fmt.i_codec = VLC_FOURCC( 't','w','o','s' ); p_sys->fmt.audio.i_bitspersample = 8; p_sys->fmt.audio.i_blockalign = 1 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_LINEAR_16: /* 16-bit linear PCM */ p_sys->fmt.i_codec = VLC_FOURCC( 't','w','o','s' ); p_sys->fmt.audio.i_bitspersample = 16; p_sys->fmt.audio.i_blockalign = 2 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_LINEAR_24: /* 24-bit linear PCM */ p_sys->fmt.i_codec = VLC_FOURCC( 't','w','o','s' ); p_sys->fmt.audio.i_bitspersample = 24; p_sys->fmt.audio.i_blockalign = 3 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_LINEAR_32: /* 32-bit linear PCM */ p_sys->fmt.i_codec = VLC_FOURCC( 't','w','o','s' ); p_sys->fmt.audio.i_bitspersample = 32; p_sys->fmt.audio.i_blockalign = 4 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_FLOAT: /* 32-bit IEEE floating point */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_FLOAT ); p_sys->fmt.audio.i_bitspersample = 32; p_sys->fmt.audio.i_blockalign = 4 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_DOUBLE: /* 64-bit IEEE floating point */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_DOUBLE ); p_sys->fmt.audio.i_bitspersample = 64; p_sys->fmt.audio.i_blockalign = 8 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_PCM; break; case AU_ADPCM_G721: /* 4-bit CCITT g.721 ADPCM */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_ADPCM_G721 ); p_sys->fmt.audio.i_bitspersample = 0; p_sys->fmt.audio.i_blockalign = 0 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_ADPCM; break; case AU_ADPCM_G722: /* CCITT g.722 ADPCM */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_ADPCM_G722 ); p_sys->fmt.audio.i_bitspersample = 0; p_sys->fmt.audio.i_blockalign = 0 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_ADPCM; break; case AU_ADPCM_G723_3: /* CCITT g.723 3-bit ADPCM */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_ADPCM_G723_3 ); p_sys->fmt.audio.i_bitspersample = 0; p_sys->fmt.audio.i_blockalign = 0 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_ADPCM; break; case AU_ADPCM_G723_5: /* CCITT g.723 5-bit ADPCM */ p_sys->fmt.i_codec = VLC_FOURCC( 'a', 'u', 0, AU_ADPCM_G723_5 ); p_sys->fmt.audio.i_bitspersample = 0; p_sys->fmt.audio.i_blockalign = 0 * p_sys->fmt.audio.i_channels; i_cat = AU_CAT_ADPCM; break; default: msg_Warn( p_demux, "unknow encoding=0x%x", GetDWBE( &hdr[8] ) ); p_sys->fmt.audio.i_bitspersample = 0; p_sys->fmt.audio.i_blockalign = 0; i_cat = AU_CAT_UNKNOWN; break; } p_sys->fmt.i_bitrate = p_sys->fmt.audio.i_rate * p_sys->fmt.audio.i_channels * p_sys->fmt.audio.i_bitspersample; if( i_cat == AU_CAT_UNKNOWN || i_cat == AU_CAT_ADPCM ) { p_sys->i_frame_size = 0; p_sys->i_frame_length = 0; msg_Err( p_demux, "unsupported codec/type (Please report it)" ); free( p_sys ); return VLC_EGENERIC; } if( p_sys->fmt.audio.i_rate == 0 ) { msg_Err( p_demux, "invalid samplerate: 0" ); free( p_sys ); return VLC_EGENERIC; } /* add the es */ p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt ); /* calculate 50ms frame size/time */ i_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 ); p_sys->i_frame_size = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 ); if( p_sys->fmt.audio.i_blockalign > 0 ) { if( ( i_modulo = p_sys->i_frame_size % p_sys->fmt.audio.i_blockalign ) != 0 ) { p_sys->i_frame_size += p_sys->fmt.audio.i_blockalign - i_modulo; } } p_sys->i_frame_length = (mtime_t)1000000 * (mtime_t)i_samples / (mtime_t)p_sys->fmt.audio.i_rate; return VLC_SUCCESS; }