int OutOpenAvio(vlc_object_t *object) { sout_access_out_t *access = (sout_access_out_t*)object; config_ChainParse( access, "sout-avio-", ppsz_sout_options, access->p_cfg ); sout_access_out_sys_t *sys = vlc_obj_malloc(object, sizeof(*sys)); if (!sys) return VLC_ENOMEM; sys->context = NULL; /* */ vlc_init_avformat(object); if (!access->psz_path) return VLC_EGENERIC; int ret; AVDictionary *options = NULL; char *psz_opts = var_InheritString(access, "sout-avio-options"); if (psz_opts) { vlc_av_get_options(psz_opts, &options); free(psz_opts); } ret = avio_open2(&sys->context, access->psz_path, AVIO_FLAG_WRITE, NULL, &options); AVDictionaryEntry *t = NULL; while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) msg_Err( access, "unknown option \"%s\"", t->key ); av_dict_free(&options); if (ret < 0) { errno = AVUNERROR(ret); msg_Err(access, "Failed to open %s", access->psz_path); return VLC_EGENERIC; } access->pf_write = Write; access->pf_control = OutControl; access->pf_seek = OutSeek; access->p_sys = sys; 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; /* Identify cdg file by extension, as there is no simple way to * detect it */ if( !demux_IsPathExtension( p_demux, ".cdg" ) && !demux_IsForced( p_demux, "cdg" ) ) return VLC_EGENERIC; /* CDG file size has to be multiple of CDG_FRAME_SIZE (it works even * if size is unknown ie 0) */ // if( (stream_Size( p_demux->s ) % CDG_FRAME_SIZE) != 0 ) // { // msg_Err( p_demux, "Reject CDG file based on its size" ); // return VLC_EGENERIC; // } demux_sys_t *p_sys = vlc_obj_malloc( p_this, sizeof (*p_sys) ); if( unlikely(p_sys == NULL) ) return VLC_ENOMEM; es_format_Init( &p_sys->fmt, VIDEO_ES, VLC_CODEC_CDG ); p_sys->fmt.video.i_width = 300-2*6; p_sys->fmt.video.i_height = 216-2*12 ; p_sys->fmt.video.i_visible_width = p_sys->fmt.video.i_width; p_sys->fmt.video.i_visible_height = p_sys->fmt.video.i_height; p_sys->p_es = es_out_Add( p_demux->out, &p_sys->fmt ); if( unlikely(p_sys->p_es == NULL) ) return VLC_ENOMEM; /* There is CDG_FRAME_RATE frames per second */ date_Init( &p_sys->pts, CDG_FRAME_RATE, 1 ); date_Set( &p_sys->pts, VLC_TICK_0 ); p_demux->pf_demux = Demux; p_demux->pf_control = Control; p_demux->p_sys = p_sys; return VLC_SUCCESS; }
static int Open(vlc_object_t *object) { stream_t *access = (stream_t *)object; access_sys_t *sys = vlc_obj_malloc(object, sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; int (*open_cb)(void *, void **, uint64_t *); void *opaque; opaque = var_InheritAddress(access, "imem-data"); open_cb = var_InheritAddress(access, "imem-open"); sys->opaque = NULL; sys->read_cb = var_InheritAddress(access, "imem-read"); sys->seek_cb = var_InheritAddress(access, "imem-seek"); sys->close_cb = var_InheritAddress(access, "imem-close"); sys->size = UINT64_MAX; if (open_cb == NULL) open_cb = open_cb_default; if (sys->read_cb == NULL) return VLC_EGENERIC; if (open_cb(opaque, &sys->opaque, &sys->size)) { msg_Err(access, "open error"); return VLC_EGENERIC; } access->pf_read = Read; access->pf_block = NULL; access->pf_seek = (sys->seek_cb != NULL) ? Seek : NULL; access->pf_control = Control; access->p_sys = sys; return VLC_SUCCESS; }
int OpenAvio(vlc_object_t *object) { stream_t *access = (stream_t*)object; access_sys_t *sys = vlc_obj_malloc(object, sizeof(*sys)); if (!sys) return VLC_ENOMEM; sys->context = NULL; /* We accept: * - avio://full_url * - url (only a subset of available protocols). */ char *url; if (!strcmp(access->psz_name, "avio")) url = strdup(access->psz_location); else if (asprintf(&url, "%s://%s", access->psz_name, access->psz_location) < 0) url = NULL; if (!url) return VLC_ENOMEM; /* */ vlc_init_avformat(object); int ret; AVIOInterruptCB cb = { .callback = UrlInterruptCallback, .opaque = access, }; AVDictionary *options = NULL; char *psz_opts = var_InheritString(access, "avio-options"); if (psz_opts) { vlc_av_get_options(psz_opts, &options); free(psz_opts); } ret = avio_open2(&sys->context, url, AVIO_FLAG_READ, &cb, &options); AVDictionaryEntry *t = NULL; while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) msg_Err( access, "unknown option \"%s\"", t->key ); av_dict_free(&options); if (ret < 0) { msg_Err(access, "Failed to open %s: %s", url, vlc_strerror_c(AVUNERROR(ret))); free(url); return VLC_EGENERIC; } free(url); sys->size = avio_size(sys->context); bool seekable; seekable = sys->context->seekable; msg_Dbg(access, "%sseekable, size=%"PRIi64, seekable ? "" : "not ", sys->size); /* */ access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access->p_sys = sys; return VLC_SUCCESS; }
static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *sys = vlc_obj_malloc(obj, sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; /* Open the device */ const char *device = demux->psz_location; if (device == NULL || !device[0]) device = "default"; const int mode = SND_PCM_NONBLOCK /*| SND_PCM_NO_AUTO_RESAMPLE*/ | SND_PCM_NO_AUTO_CHANNELS /*| SND_PCM_NO_AUTO_FORMAT*/; snd_pcm_t *pcm; int val = snd_pcm_open (&pcm, device, SND_PCM_STREAM_CAPTURE, mode); if (val != 0) { msg_Err (demux, "cannot open ALSA device \"%s\": %s", device, snd_strerror (val)); return VLC_EGENERIC; } sys->pcm = pcm; msg_Dbg (demux, "using ALSA device: %s", device); DumpDevice (VLC_OBJECT(demux), pcm); /* Negotiate capture parameters */ snd_pcm_hw_params_t *hw; es_format_t fmt; unsigned param; int dir; snd_pcm_hw_params_alloca (&hw); snd_pcm_hw_params_any (pcm, hw); Dump (demux, "initial hardware setup:\n", snd_pcm_hw_params_dump, hw); val = snd_pcm_hw_params_set_rate_resample (pcm, hw, 0); if (val) { msg_Err (demux, "cannot disable resampling: %s", snd_strerror (val)); goto error; } val = snd_pcm_hw_params_set_access (pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED); if (val) { msg_Err (demux, "cannot set access mode: %s", snd_strerror (val)); goto error; } snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; for (size_t i = 0; i < sizeof (choices) / sizeof (choices[0]); i++) if (snd_pcm_hw_params_test_format (pcm, hw, choices[i]) == 0) { val = snd_pcm_hw_params_set_format (pcm, hw, choices[i]); if (val) { msg_Err (demux, "cannot set sample format: %s", snd_strerror (val)); goto error; } format = choices[i]; break; } if (format == SND_PCM_FORMAT_UNKNOWN) { msg_Err (demux, "no supported sample format"); goto error; } assert ((size_t)format < (sizeof (formats) / sizeof (formats[0]))); es_format_Init (&fmt, AUDIO_ES, formats[format]); fmt.audio.i_format = fmt.i_codec; param = 1 + var_InheritBool (demux, "alsa-stereo"); val = snd_pcm_hw_params_set_channels_max (pcm, hw, ¶m); if (val) { msg_Err (demux, "cannot restrict channels count: %s", snd_strerror (val)); goto error; } val = snd_pcm_hw_params_set_channels_last (pcm, hw, ¶m); if (val) { msg_Err (demux, "cannot set channels count: %s", snd_strerror (val)); goto error; } assert (param > 0); assert (param < (sizeof (channel_maps) / sizeof (channel_maps[0]))); fmt.audio.i_channels = param; fmt.audio.i_physical_channels = channel_maps[param - 1]; param = var_InheritInteger (demux, "alsa-samplerate"); val = snd_pcm_hw_params_set_rate_max (pcm, hw, ¶m, NULL); if (val) { msg_Err (demux, "cannot restrict rate to %u Hz or less: %s", 192000, snd_strerror (val)); goto error; } val = snd_pcm_hw_params_set_rate_last (pcm, hw, ¶m, &dir); if (val) { msg_Err (demux, "cannot set sample rate: %s", snd_strerror (val)); goto error; } if (dir) msg_Warn (demux, "sample rate is not integral"); fmt.audio.i_rate = param; sys->rate = param; sys->start = mdate (); sys->caching = INT64_C(1000) * var_InheritInteger (demux, "live-caching"); param = sys->caching; val = snd_pcm_hw_params_set_buffer_time_near (pcm, hw, ¶m, NULL); if (val) { msg_Err (demux, "cannot set buffer duration: %s", snd_strerror (val)); goto error; } param /= 4; val = snd_pcm_hw_params_set_period_time_near (pcm, hw, ¶m, NULL); if (val) { msg_Err (demux, "cannot set period: %s", snd_strerror (val)); goto error; } val = snd_pcm_hw_params_get_period_size (hw, &sys->period_size, &dir); if (val) { msg_Err (demux, "cannot get period size: %s", snd_strerror (val)); goto error; } if (dir > 0) sys->period_size++; /* Commit hardware parameters */ val = snd_pcm_hw_params (pcm, hw); if (val) { msg_Err (demux, "cannot commit hardware parameters: %s", snd_strerror (val)); goto error; } Dump (demux, "final HW setup:\n", snd_pcm_hw_params_dump, hw); /* Kick recording */ aout_FormatPrepare (&fmt.audio); sys->es = es_out_Add (demux->out, &fmt); demux->p_sys = sys; if (vlc_clone (&sys->thread, Thread, demux, VLC_THREAD_PRIORITY_INPUT)) { es_out_Del (demux->out, sys->es); goto error; } demux->pf_demux = NULL; demux->pf_control = Control; return VLC_SUCCESS; error: snd_pcm_close (pcm); return VLC_EGENERIC; }
/** * Probe the X server. */ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg, video_format_t *fmtp, vlc_video_context *ctx) { vlc_object_t *obj = VLC_OBJECT(vd); vout_display_sys_t *sys = vlc_obj_malloc(obj, sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; vd->sys = sys; /* Connect to X */ xcb_connection_t *conn; const xcb_screen_t *screen; if (vlc_xcb_parent_Create(vd, cfg, &conn, &screen) == NULL) return VLC_EGENERIC; sys->conn = conn; sys->root = screen->root; sys->format.argb = 0; sys->format.alpha = 0; if (!CheckRender(vd, conn)) goto error; xcb_render_query_pict_formats_cookie_t pic_fmt_ck = xcb_render_query_pict_formats(conn); xcb_render_query_pict_formats_reply_t *pic_fmt_r = xcb_render_query_pict_formats_reply(conn, pic_fmt_ck, NULL); if (pic_fmt_r == NULL) goto error; const xcb_setup_t *setup = xcb_get_setup(conn); const xcb_render_pictforminfo_t *const pic_fmts = xcb_render_query_pict_formats_formats(pic_fmt_r); xcb_visualid_t visual = 0; for (unsigned i = 0; i < pic_fmt_r->num_formats; i++) { const xcb_render_pictforminfo_t *const pic_fmt = pic_fmts + i; const xcb_render_directformat_t *const d = &pic_fmt->direct; if (pic_fmt->depth == 8 && pic_fmt->direct.alpha_mask == 0xff) { /* Alpha mask format */ sys->format.alpha = pic_fmt->id; continue; } xcb_visualid_t vid = FindVisual(setup, screen, pic_fmt_r, pic_fmt->id); if (vid == 0) continue; /* Use only ARGB for now. 32-bits is guaranteed to work. */ if (pic_fmt->depth != 32) continue; vlc_fourcc_t chroma = ParseFormat(setup, pic_fmt); if (chroma == 0) continue; fmtp->i_chroma = chroma; fmtp->i_rmask = ((uint32_t)d->red_mask) << d->red_shift; fmtp->i_gmask = ((uint32_t)d->green_mask) << d->green_shift; fmtp->i_bmask = ((uint32_t)d->blue_mask) << d->blue_shift; sys->format.argb = pic_fmt->id; visual = vid; } free(pic_fmt_r); if (unlikely(sys->format.argb == 0 || sys->format.alpha == 0)) goto error; /* Buggy server */ msg_Dbg(obj, "using RENDER picture format %u", sys->format.argb); msg_Dbg(obj, "using X11 visual 0x%"PRIx32, visual); char *filter = var_InheritString(obj, "x11-render-filter"); if (filter != NULL) { msg_Dbg(obj, "using filter \"%s\"", filter); sys->filter = ToCharset("ISO 8859-1", filter, &(size_t){ 0 }); free(filter); } else sys->filter = NULL; sys->drawable.source = xcb_generate_id(conn); sys->drawable.crop = xcb_generate_id(conn); sys->drawable.scale = xcb_generate_id(conn); sys->drawable.subpic = xcb_generate_id(conn); sys->drawable.alpha = xcb_generate_id(conn); sys->drawable.dest = xcb_generate_id(conn); sys->picture.source = xcb_generate_id(conn); sys->picture.crop = xcb_generate_id(conn); sys->picture.scale = xcb_generate_id(conn); sys->picture.subpic = xcb_generate_id(conn); sys->picture.alpha = xcb_generate_id(conn); sys->picture.dest = xcb_generate_id(conn); sys->gc = xcb_generate_id(conn); if (XCB_shm_Check(obj, conn)) sys->segment = xcb_generate_id(conn); else sys->segment = 0; xcb_colormap_t cmap = xcb_generate_id(conn); uint32_t cw_mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; const uint32_t cw_list[] = { /* XCB_CW_BACK_PIXEL */ screen->black_pixel, /* XCB_CW_BORDER_PIXEL */ screen->black_pixel, /* XCB_CW_EVENT_MASK */ 0, /* XCB_CW_COLORMAP */ cmap, }; xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, cmap, screen->root, visual); xcb_create_pixmap(conn, 32, sys->drawable.source, screen->root, vd->source.i_width, vd->source.i_height); xcb_create_gc(conn, sys->gc, sys->drawable.source, 0, NULL); xcb_create_window(conn, 32, sys->drawable.dest, cfg->window->handle.xid, 0, 0, cfg->display.width, cfg->display.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, cw_mask, cw_list); xcb_render_create_picture(conn, sys->picture.source, sys->drawable.source, sys->format.argb, 0, NULL); xcb_render_create_picture(conn, sys->picture.dest, sys->drawable.dest, sys->format.argb, 0, NULL); CreateBuffers(vd, cfg); xcb_map_window(conn, sys->drawable.dest); sys->spu_chromas[0] = fmtp->i_chroma; sys->spu_chromas[1] = 0; vd->info.subpicture_chromas = sys->spu_chromas; vd->prepare = Prepare; vd->display = Display; vd->control = Control; (void) ctx; return VLC_SUCCESS; error: xcb_disconnect(conn); return VLC_EGENERIC; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { stream_t *p_access = (stream_t*)p_this; const char *psz_url = p_access->psz_url; char *psz; int ret = VLC_EGENERIC; vlc_credential credential; access_sys_t *p_sys = vlc_obj_malloc( p_this, sizeof(*p_sys) ); if( unlikely(p_sys == NULL) ) return VLC_ENOMEM; p_sys->stream = NULL; p_sys->b_proxy = false; p_sys->psz_proxy_passbuf = NULL; p_sys->psz_mime = NULL; p_sys->b_icecast = false; p_sys->psz_location = NULL; p_sys->psz_user_agent = NULL; p_sys->psz_referrer = NULL; p_sys->psz_username = NULL; p_sys->psz_password = NULL; p_sys->i_icy_meta = 0; p_sys->i_icy_offset = 0; p_sys->psz_icy_name = NULL; p_sys->psz_icy_genre = NULL; p_sys->psz_icy_title = NULL; p_sys->b_has_size = false; p_sys->offset = 0; p_sys->size = 0; p_access->p_sys = p_sys; if( vlc_UrlParse( &p_sys->url, psz_url ) || p_sys->url.psz_host == NULL ) { msg_Err( p_access, "invalid URL" ); vlc_UrlClean( &p_sys->url ); return VLC_EGENERIC; } if( p_sys->url.i_port <= 0 ) p_sys->url.i_port = 80; vlc_credential_init( &credential, &p_sys->url ); /* Determine the HTTP user agent */ /* See RFC2616 §2.2 token and comment definition, and §3.8 and * §14.43 user-agent header */ p_sys->psz_user_agent = var_InheritString( p_access, "http-user-agent" ); if (p_sys->psz_user_agent) { unsigned comment_level = 0; for( char *p = p_sys->psz_user_agent; *p; p++ ) { uint8_t c = *p; if (comment_level == 0) { if( c < 32 || strchr( ")<>@,;:\\\"[]?={}", c ) ) *p = '_'; /* remove potentially harmful characters */ } else { if (c == ')') comment_level--; else if( c < 32 && strchr( "\t\r\n", c ) == NULL) *p = '_'; /* remove potentially harmful characters */ } if (c == '(') { if (comment_level == UINT_MAX) break; comment_level++; } } /* truncate evil unclosed comments */ if (comment_level > 0) { char *p = strchr(p_sys->psz_user_agent, '('); *p = '\0'; } } /* HTTP referrer */ p_sys->psz_referrer = var_InheritString( p_access, "http-referrer" ); /* Check proxy */ psz = var_InheritString( p_access, "http-proxy" ); if( psz == NULL ) { msg_Dbg(p_access, "querying proxy for %s", psz_url); psz = vlc_getProxyUrl(psz_url); if (psz != NULL) msg_Dbg(p_access, "proxy: %s", psz); else msg_Dbg(p_access, "no proxy"); } if( psz != NULL ) { p_sys->b_proxy = true; vlc_UrlParse( &p_sys->proxy, psz ); free( psz ); psz = var_InheritString( p_access, "http-proxy-pwd" ); if( psz ) p_sys->proxy.psz_password = p_sys->psz_proxy_passbuf = psz; if( p_sys->proxy.psz_host == NULL || *p_sys->proxy.psz_host == '\0' ) { msg_Warn( p_access, "invalid proxy host" ); goto error; } if( p_sys->proxy.i_port <= 0 ) { p_sys->proxy.i_port = 80; } } msg_Dbg( p_access, "http: server='%s' port=%d file='%s'", p_sys->url.psz_host, p_sys->url.i_port, p_sys->url.psz_path != NULL ? p_sys->url.psz_path : "" ); if( p_sys->b_proxy ) { msg_Dbg( p_access, " proxy %s:%d", p_sys->proxy.psz_host, p_sys->proxy.i_port ); } if( p_sys->url.psz_username && *p_sys->url.psz_username ) { msg_Dbg( p_access, " user='******'", p_sys->url.psz_username ); } p_sys->b_reconnect = var_InheritBool( p_access, "http-reconnect" ); if( vlc_credential_get( &credential, p_access, NULL, NULL, NULL, NULL ) ) { p_sys->url.psz_username = (char *) credential.psz_username; p_sys->url.psz_password = (char *) credential.psz_password; } connect: /* Connect */ if( Connect( p_access ) ) goto disconnect; if( p_sys->i_code == 401 ) { if( p_sys->auth.psz_realm == NULL ) { msg_Err( p_access, "authentication failed without realm" ); goto disconnect; } /* FIXME ? */ if( p_sys->url.psz_username && p_sys->url.psz_password && p_sys->auth.psz_nonce && p_sys->auth.i_nonce == 0 ) { Disconnect( p_access ); goto connect; } free( p_sys->psz_username ); free( p_sys->psz_password ); p_sys->psz_username = p_sys->psz_password = NULL; msg_Dbg( p_access, "authentication failed for realm %s", p_sys->auth.psz_realm ); credential.psz_realm = p_sys->auth.psz_realm; credential.psz_authtype = p_sys->auth.psz_nonce ? "Digest" : "Basic"; if( vlc_credential_get( &credential, p_access, NULL, NULL, _("HTTP authentication"), _("Please enter a valid login name and a " "password for realm %s."), p_sys->auth.psz_realm ) ) { p_sys->psz_username = strdup(credential.psz_username); p_sys->psz_password = strdup(credential.psz_password); if (!p_sys->psz_username || !p_sys->psz_password) goto disconnect; msg_Err( p_access, "retrying with user=%s", p_sys->psz_username ); p_sys->url.psz_username = p_sys->psz_username; p_sys->url.psz_password = p_sys->psz_password; Disconnect( p_access ); goto connect; } else goto disconnect; } else vlc_credential_store( &credential, p_access ); if( ( p_sys->i_code == 301 || p_sys->i_code == 302 || p_sys->i_code == 303 || p_sys->i_code == 307 ) && p_sys->psz_location != NULL ) { p_access->psz_url = p_sys->psz_location; p_sys->psz_location = NULL; ret = VLC_ACCESS_REDIRECT; goto disconnect; } if( p_sys->b_reconnect ) msg_Dbg( p_access, "auto re-connect enabled" ); /* Set up p_access */ p_access->pf_read = Read; p_access->pf_control = Control; p_access->pf_seek = Seek; vlc_credential_clean( &credential ); return VLC_SUCCESS; disconnect: Disconnect( p_access ); error: vlc_credential_clean( &credential ); vlc_UrlClean( &p_sys->url ); if( p_sys->b_proxy ) vlc_UrlClean( &p_sys->proxy ); free( p_sys->psz_proxy_passbuf ); free( p_sys->psz_mime ); free( p_sys->psz_location ); free( p_sys->psz_user_agent ); free( p_sys->psz_referrer ); free( p_sys->psz_username ); free( p_sys->psz_password ); return ret; }
/***************************************************************************** * Open *****************************************************************************/ static int Open( vlc_object_t *p_this ) { demux_t *p_demux = (demux_t*)p_this; demux_sys_t *p_sys; ModPlug_Settings settings; /* We accept file based on extension match */ if( !p_demux->obj.force ) { const char *psz_ext = p_demux->psz_filepath ? strrchr( p_demux->psz_filepath, '.' ) : NULL; if( psz_ext ) psz_ext++; if( Validate( p_demux, psz_ext ) ) { msg_Dbg( p_demux, "MOD validation failed (ext=%s)", psz_ext ? psz_ext : ""); return VLC_EGENERIC; } } const int64_t i_size = stream_Size( p_demux->s ); if( i_size <= 0 || i_size >= MOD_MAX_FILE_SIZE ) return VLC_EGENERIC; p_sys = vlc_obj_malloc( p_this, sizeof (*p_sys) ); if( !p_sys ) return VLC_ENOMEM; msg_Dbg( p_demux, "loading complete file (could be long)" ); p_sys->i_data = i_size; p_sys->p_data = vlc_obj_malloc( p_this, p_sys->i_data ); if( unlikely(p_sys->p_data == NULL) ) return VLC_ENOMEM; p_sys->i_data = vlc_stream_Read( p_demux->s, p_sys->p_data, p_sys->i_data ); if( p_sys->i_data <= 0 ) { msg_Err( p_demux, "failed to read the complete file" ); return VLC_EGENERIC; } /* Configure modplug before loading the file */ vlc_mutex_lock( &libmodplug_lock ); ModPlug_GetSettings( &settings ); settings.mFlags = MODPLUG_ENABLE_OVERSAMPLING; settings.mChannels = 2; settings.mBits = 16; settings.mFrequency = 44100; settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; if( var_InheritBool( p_demux, "mod-noisereduction" ) ) settings.mFlags |= MODPLUG_ENABLE_NOISE_REDUCTION; if( var_InheritBool( p_demux, "mod-reverb" ) ) settings.mFlags |= MODPLUG_ENABLE_REVERB; settings.mReverbDepth = var_InheritInteger( p_demux, "mod-reverb-level" ); settings.mReverbDelay = var_InheritInteger( p_demux, "mod-reverb-delay" ); if( var_InheritBool( p_demux, "mod-megabass" ) ) settings.mFlags |= MODPLUG_ENABLE_MEGABASS; settings.mBassAmount = var_InheritInteger( p_demux, "mod-megabass-level" ); settings.mBassRange = var_InheritInteger( p_demux, "mod-megabass-range" ); if( var_InheritBool( p_demux, "mod-surround" ) ) settings.mFlags |= MODPLUG_ENABLE_SURROUND; settings.mSurroundDepth = var_InheritInteger( p_demux, "mod-surround-level" ); settings.mSurroundDelay = var_InheritInteger( p_demux, "mod-surround-delay" ); ModPlug_SetSettings( &settings ); p_sys->f = ModPlug_Load( p_sys->p_data, p_sys->i_data ); vlc_mutex_unlock( &libmodplug_lock ); if( !p_sys->f ) { msg_Err( p_demux, "failed to understand the file" ); return VLC_EGENERIC; } /* init time */ date_Init( &p_sys->pts, settings.mFrequency, 1 ); date_Set( &p_sys->pts, VLC_TICK_0 ); p_sys->i_length = VLC_TICK_FROM_MS( ModPlug_GetLength( p_sys->f ) ); msg_Dbg( p_demux, "MOD loaded name=%s length=%"PRId64"ms", ModPlug_GetName( p_sys->f ), MS_FROM_VLC_TICK( p_sys->i_length ) ); #ifdef WORDS_BIGENDIAN es_format_Init( &p_sys->fmt, AUDIO_ES, VLC_FOURCC( 't', 'w', 'o', 's' ) ); #else es_format_Init( &p_sys->fmt, AUDIO_ES, VLC_FOURCC( 'a', 'r', 'a', 'w' ) ); #endif p_sys->fmt.audio.i_rate = settings.mFrequency; p_sys->fmt.audio.i_channels = settings.mChannels; p_sys->fmt.audio.i_bitspersample = settings.mBits; p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt ); if( unlikely(p_sys->es == NULL) ) return VLC_ENOMEM; /* Fill p_demux field */ p_demux->pf_demux = Demux; p_demux->pf_control = Control; p_demux->p_sys = p_sys; 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; const uint8_t *peek; /* XA file heuristic */ if( vlc_stream_Peek( p_demux->s, &peek, 10 ) < 10 ) return VLC_EGENERIC; if( memcmp( peek, "XAI", 4 ) && memcmp( peek, "XAJ", 4 ) && memcmp( peek, "XA\0", 4 ) ) return VLC_EGENERIC; if( GetWLE( peek + 8 ) != 1 ) /* format tag */ return VLC_EGENERIC; demux_sys_t *p_sys = vlc_obj_malloc( p_this, sizeof (*p_sys) ); if( unlikely( p_sys == NULL ) ) return VLC_ENOMEM; /* read XA header*/ xa_header_t xa; if( vlc_stream_Read( p_demux->s, &xa, HEADER_LENGTH ) < HEADER_LENGTH ) return VLC_EGENERIC; es_format_t fmt; es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_ADPCM_XA_EA ); msg_Dbg( p_demux, "assuming EA ADPCM audio codec" ); fmt.audio.i_rate = GetDWLE( &xa.nSamplesPerSec ); fmt.audio.i_bytes_per_frame = 15 * GetWLE( &xa.nChannels ); fmt.audio.i_frame_length = FRAME_LENGTH; fmt.audio.i_channels = GetWLE ( &xa.nChannels ); fmt.audio.i_blockalign = fmt.audio.i_bytes_per_frame; fmt.audio.i_bitspersample = GetWLE( &xa.wBitsPerSample ); fmt.i_bitrate = (fmt.audio.i_rate * fmt.audio.i_bytes_per_frame * 8) / fmt.audio.i_frame_length; /* FIXME: better computation */ p_sys->i_data_size = xa.iSize * 15 / 56; /* How many frames per block (1:1 is too CPU intensive) */ p_sys->i_block_frames = fmt.audio.i_rate / (FRAME_LENGTH * 20) + 1; p_sys->i_frame_size = fmt.audio.i_bytes_per_frame; p_sys->i_bitrate = fmt.i_bitrate; msg_Dbg( p_demux, "fourcc: %4.4s, channels: %d, " "freq: %d Hz, bitrate: %dKo/s, blockalign: %d", (char *)&fmt.i_codec, fmt.audio.i_channels, fmt.audio.i_rate, fmt.i_bitrate / 8192, fmt.audio.i_blockalign ); if( fmt.audio.i_rate == 0 || fmt.audio.i_channels == 0 || fmt.audio.i_bitspersample != 16 ) return VLC_EGENERIC; p_sys->p_es = es_out_Add( p_demux->out, &fmt ); if( unlikely(p_sys->p_es == NULL) ) return VLC_ENOMEM; date_Init( &p_sys->pts, fmt.audio.i_rate, 1 ); date_Set( &p_sys->pts, VLC_TICK_0 ); p_demux->pf_demux = Demux; p_demux->pf_control = Control; p_demux->p_sys = p_sys; return VLC_SUCCESS; }