/***************************************************************************** * OpenDecoder: Create the decoder instance *****************************************************************************/ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init) { decoder_t *p_dec = (decoder_t *)p_this; decoder_sys_t *p_sys; mc_api *api; const char *mime = NULL; /* Video or Audio if "mediacodec-audio" bool is true */ if (p_dec->fmt_in.i_cat != VIDEO_ES && (p_dec->fmt_in.i_cat != AUDIO_ES || !var_InheritBool(p_dec, CFG_PREFIX "audio"))) return VLC_EGENERIC; if (p_dec->fmt_in.i_cat == VIDEO_ES) { if (!p_dec->fmt_in.video.i_width || !p_dec->fmt_in.video.i_height) { /* We can handle h264 without a valid video size */ if (p_dec->fmt_in.i_codec != VLC_CODEC_H264) { msg_Dbg(p_dec, "resolution (%dx%d) not supported", p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height); return VLC_EGENERIC; } } switch (p_dec->fmt_in.i_codec) { case VLC_CODEC_HEVC: mime = "video/hevc"; break; case VLC_CODEC_H264: mime = "video/avc"; break; case VLC_CODEC_H263: mime = "video/3gpp"; break; case VLC_CODEC_MP4V: mime = "video/mp4v-es"; break; case VLC_CODEC_WMV3: mime = "video/x-ms-wmv"; break; case VLC_CODEC_VC1: mime = "video/wvc1"; break; case VLC_CODEC_VP8: mime = "video/x-vnd.on2.vp8"; break; case VLC_CODEC_VP9: mime = "video/x-vnd.on2.vp9"; break; /* case VLC_CODEC_MPGV: mime = "video/mpeg2"; break; */ } } else { switch (p_dec->fmt_in.i_codec) { case VLC_CODEC_AMR_NB: mime = "audio/3gpp"; break; case VLC_CODEC_AMR_WB: mime = "audio/amr-wb"; break; case VLC_CODEC_MPGA: case VLC_CODEC_MP3: mime = "audio/mpeg"; break; case VLC_CODEC_MP2: mime = "audio/mpeg-L2"; break; case VLC_CODEC_MP4A: mime = "audio/mp4a-latm"; break; case VLC_CODEC_QCELP: mime = "audio/qcelp"; break; case VLC_CODEC_VORBIS: mime = "audio/vorbis"; break; case VLC_CODEC_OPUS: mime = "audio/opus"; break; case VLC_CODEC_ALAW: mime = "audio/g711-alaw"; break; case VLC_CODEC_MULAW: mime = "audio/g711-mlaw"; break; case VLC_CODEC_FLAC: mime = "audio/flac"; break; case VLC_CODEC_GSM: mime = "audio/gsm"; break; case VLC_CODEC_A52: mime = "audio/ac3"; break; case VLC_CODEC_EAC3: mime = "audio/eac3"; break; case VLC_CODEC_ALAC: mime = "audio/alac"; break; case VLC_CODEC_DTS: mime = "audio/vnd.dts"; break; /* case VLC_CODEC_: mime = "audio/mpeg-L1"; break; */ /* case VLC_CODEC_: mime = "audio/aac-adts"; break; */ } } if (!mime) { msg_Dbg(p_dec, "codec %4.4s not supported", (char *)&p_dec->fmt_in.i_codec); return VLC_EGENERIC; } api = calloc(1, sizeof(mc_api)); if (!api) return VLC_ENOMEM; api->p_obj = p_this; api->b_video = p_dec->fmt_in.i_cat == VIDEO_ES; if (pf_init(api) != VLC_SUCCESS) { free(api); return VLC_EGENERIC; } /* Allocate the memory needed to store the decoder's structure */ if ((p_sys = calloc(1, sizeof(*p_sys))) == NULL) { api->clean(api); free(api); return VLC_ENOMEM; } p_sys->api = api; p_dec->p_sys = p_sys; p_dec->pf_decode_video = DecodeVideo; p_dec->pf_decode_audio = DecodeAudio; p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat; p_dec->fmt_out.video = p_dec->fmt_in.video; p_dec->fmt_out.audio = p_dec->fmt_in.audio; p_dec->b_need_packetized = true; p_sys->mime = mime; p_sys->b_new_block = true; if (p_dec->fmt_in.i_cat == VIDEO_ES) { p_sys->u.video.i_width = p_dec->fmt_in.video.i_width; p_sys->u.video.i_height = p_dec->fmt_in.video.i_height; p_sys->u.video.timestamp_fifo = timestamp_FifoNew(32); if (!p_sys->u.video.timestamp_fifo) { CloseDecoder(p_this); return VLC_ENOMEM; } if (p_dec->fmt_in.i_codec == VLC_CODEC_H264) h264_get_profile_level(&p_dec->fmt_in, &p_sys->u.video.i_h264_profile, NULL, NULL); p_sys->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec), p_sys->mime, p_sys->u.video.i_h264_profile); if (!p_sys->psz_name) { CloseDecoder(p_this); return VLC_EGENERIC; } /* Check if we need late opening */ switch (p_dec->fmt_in.i_codec) { case VLC_CODEC_H264: if (!p_sys->u.video.i_width || !p_sys->u.video.i_height) { msg_Warn(p_dec, "waiting for sps/pps for codec %4.4s", (const char *)&p_dec->fmt_in.i_codec); return VLC_SUCCESS; } case VLC_CODEC_VC1: if (!p_dec->fmt_in.i_extra) { msg_Warn(p_dec, "waiting for extra data for codec %4.4s", (const char *)&p_dec->fmt_in.i_codec); return VLC_SUCCESS; } break; } } else { p_sys->u.audio.i_channels = p_dec->fmt_in.audio.i_channels; p_sys->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec), p_sys->mime, 0); if (!p_sys->psz_name) { CloseDecoder(p_this); return VLC_EGENERIC; } /* Marvel ACodec assert if channel count is 0 */ if (!strncmp(p_sys->psz_name, "OMX.Marvell", __MIN(strlen(p_sys->psz_name), strlen("OMX.Marvell")))) p_sys->u.audio.b_need_channels = true; /* Check if we need late opening */ switch (p_dec->fmt_in.i_codec) { case VLC_CODEC_VORBIS: case VLC_CODEC_MP4A: if (!p_dec->fmt_in.i_extra) { msg_Warn(p_dec, "waiting for extra data for codec %4.4s", (const char *)&p_dec->fmt_in.i_codec); return VLC_SUCCESS; } break; } if (!p_sys->u.audio.i_channels && p_sys->u.audio.b_need_channels) { msg_Warn(p_dec, "waiting for valid channel count"); return VLC_SUCCESS; } } return StartMediaCodec(p_dec); }
void RendererDialog::setVisible(bool visible) { QVLCDialog::setVisible(visible); if (visible) { /* SD subnodes */ char **ppsz_longnames; char **ppsz_names; if( vlc_rd_get_names( THEPL, &ppsz_names, &ppsz_longnames ) != VLC_SUCCESS ) return; char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames; for( ; *ppsz_name; ppsz_name++, ppsz_longname++ ) { /* TODO launch all discovery services for renderers */ msg_Dbg( p_intf, "starting renderer discovery service %s", *ppsz_longname ); if ( p_rd == NULL ) { p_rd = vlc_rd_new( VLC_OBJECT(p_intf), *ppsz_name ); if( !p_rd ) msg_Err( p_intf, "Could not start renderer discovery services" ); } break; } free( ppsz_names ); free( ppsz_longnames ); if ( p_rd != NULL ) { int row = -1; char *psz_renderer = var_InheritString( THEPL, "sout" ); if ( psz_renderer != NULL ) { for ( row = 0 ; row < ui.receiversListWidget->count(); row++ ) { RendererItem *rowItem = reinterpret_cast<RendererItem*>( ui.receiversListWidget->item( row ) ); if ( rowItem->isItemSout( psz_renderer, false ) ) break; } if ( row == ui.receiversListWidget->count() ) row = -1; free( psz_renderer ); } ui.receiversListWidget->setCurrentRow( row ); if ( !b_rd_started ) { vlc_event_manager_t *em = vlc_rd_event_manager( p_rd ); vlc_event_attach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this ); vlc_event_attach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this ); b_rd_started = vlc_rd_start( p_rd ) == VLC_SUCCESS; if ( !b_rd_started ) { vlc_event_detach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this); vlc_event_detach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this); } } } } else { if ( p_rd != NULL ) { if ( b_rd_started ) { vlc_event_manager_t *em = vlc_rd_event_manager( p_rd ); vlc_event_detach( em, vlc_RendererDiscoveryItemAdded, renderer_event_received, this); vlc_event_detach( em, vlc_RendererDiscoveryItemRemoved, renderer_event_received, this); vlc_rd_stop( p_rd ); b_rd_started = false; } } ui.receiversListWidget->clear(); } }
static int WriteCatalog( addons_storage_t *p_storage, addon_entry_t **pp_entries, int i_entries ) { addon_entry_t *p_entry; char *psz_file; char *psz_tempstring = NULL; char *psz_userdir = config_GetUserDir( VLC_DATA_DIR ); if ( !psz_userdir ) return VLC_ENOMEM; if ( asprintf( &psz_file, "%s%s", psz_userdir, ADDONS_CATALOG ) < 1 ) { free( psz_userdir ); return VLC_ENOMEM; } free( psz_userdir ); char *psz_path = strdup( psz_file ); if ( !psz_path ) { free( psz_file ); return VLC_ENOMEM; } char *psz_buf = strrchr( psz_path, DIR_SEP_CHAR ); if( psz_buf ) { *++psz_buf = '\0'; /* ensure directory exists */ if( !EMPTY_STR( psz_path ) ) recursive_mkdir( VLC_OBJECT(p_storage), psz_path ); free( psz_path ); } FILE *p_catalog = vlc_fopen( psz_file, "wt" ); free( psz_file ); if ( !p_catalog ) return VLC_EGENERIC; /* write XML header */ fprintf( p_catalog, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); fprintf( p_catalog, "<videolan xmlns=\"http://videolan.org/ns/vlc/addons/1.0\">\n" ); fprintf( p_catalog, "\t<addons>\n" ); for ( int i=0; i<i_entries; i++ ) { p_entry = pp_entries[i]; vlc_mutex_lock( &p_entry->lock ); if ( ( p_entry->e_state != ADDON_INSTALLED ) || !( p_entry->e_flags & ADDON_MANAGEABLE ) ) { vlc_mutex_unlock( &p_entry->lock ); continue; } if ( p_entry->psz_source_module ) psz_tempstring = convert_xml_special_chars( p_entry->psz_source_module ); char *psz_uuid = addons_uuid_to_psz( ( const addon_uuid_t * ) & p_entry->uuid ); fprintf( p_catalog, "\t\t<addon source=\"%s\" type=\"%s\" id=\"%s\" " "downloads=\"%ld\" score=\"%ld\"", ( psz_tempstring ) ? psz_tempstring : "", getTypePsz( p_entry->e_type ), psz_uuid, p_entry->i_downloads, p_entry->i_score ); free( psz_uuid ); free( psz_tempstring ); WRITE_WITH_ENTITIES( " version=\"%s\">\n", p_entry->psz_version ) WRITE_WITH_ENTITIES( "\t\t\t<name>%s</name>\n", p_entry->psz_name ) WRITE_WITH_ENTITIES( "\t\t\t<summary>%s</summary>\n", p_entry->psz_summary ) if ( p_entry->psz_description ) { psz_tempstring = p_entry->psz_description; /* FIXME: do real escaping */ while( ( psz_tempstring = strstr( psz_tempstring, "]]>" ) ) ) *psz_tempstring = ' '; fprintf( p_catalog, "\t\t\t<description><![CDATA[%s]]></description>\n", p_entry->psz_description ); } WRITE_WITH_ENTITIES( "\t\t\t<image>%s</image>\n", p_entry->psz_image_data ) WRITE_WITH_ENTITIES( "\t\t\t<archive>%s</archive>\n", p_entry->psz_archive_uri ) fprintf( p_catalog, "\t\t\t<authorship>\n" ); WRITE_WITH_ENTITIES( "\t\t\t\t<creator>%s</creator>\n", p_entry->psz_author ) WRITE_WITH_ENTITIES( "\t\t\t\t<sourceurl>%s</sourceurl>\n", p_entry->psz_source_uri ) fprintf( p_catalog, "\t\t\t</authorship>\n" ); FOREACH_ARRAY( addon_file_t *p_file, p_entry->files ) psz_tempstring = convert_xml_special_chars( p_file->psz_filename ); fprintf( p_catalog, "\t\t\t<resource type=\"%s\">%s</resource>\n", getTypePsz( p_file->e_filetype ), psz_tempstring ); free( psz_tempstring ); FOREACH_END(); fprintf( p_catalog, "\t\t</addon>\n" ); vlc_mutex_unlock( &p_entry->lock ); } fprintf( p_catalog, "\t</addons>\n" ); fprintf( p_catalog, "</videolan>\n" ); fclose( p_catalog ); return VLC_SUCCESS; }
int OpenAvio(vlc_object_t *object) { access_t *access = (access_t*)object; access_sys_t *sys = malloc(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_access, "avio")) url = strdup(access->psz_location); else if (asprintf(&url, "%s://%s", access->psz_access, access->psz_location) < 0) url = NULL; if (!url) { free(sys); return VLC_ENOMEM; } /* */ vlc_init_avformat(object); int ret; #if LIBAVFORMAT_VERSION_MAJOR < 54 ret = avio_open(&sys->context, url, AVIO_FLAG_READ); #else AVIOInterruptCB cb = { .callback = UrlInterruptCallback, .opaque = access, }; AVDictionary *options = NULL; char *psz_opts = var_InheritString(access, "avio-options"); if (psz_opts && *psz_opts) { options = vlc_av_get_options(psz_opts); 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); #endif if (ret < 0) { msg_Err(access, "Failed to open %s: %s", url, vlc_strerror_c(AVUNERROR(ret))); free(url); goto error; } free(url); #if LIBAVFORMAT_VERSION_MAJOR < 54 /* We can accept only one active user at any time */ if (SetupAvioCb(VLC_OBJECT(access))) { msg_Err(access, "Module aready in use"); avio_close(sys->context); goto error; } #endif int64_t size = avio_size(sys->context); bool seekable; #if LIBAVFORMAT_VERSION_MAJOR < 54 seekable = !sys->context->is_streamed; #else seekable = sys->context->seekable; #endif msg_Dbg(access, "%sseekable, size=%"PRIi64, seekable ? "" : "not ", size); sys->size = size > 0 ? size : 0; /* */ access_InitFields(access); access->pf_read = Read; access->pf_block = NULL; access->pf_control = Control; access->pf_seek = Seek; access->p_sys = sys; return VLC_SUCCESS; error: free(sys); return VLC_EGENERIC; }
static int Open(vlc_object_t *object) { vout_display_t *vd = (vout_display_t *)object; vout_display_sys_t *sys; /* Allocate structure */ vd->sys = sys = malloc(sizeof(*sys)); if (!sys) return VLC_ENOMEM; sys->directfb = NULL; sys->primary = NULL; sys->width = 0; sys->height = 0; sys->pool = NULL; /* Init DirectFB */ if (DirectFBInit(NULL,NULL) != DFB_OK) { msg_Err(vd, "Cannot init DirectFB"); free(sys); return VLC_EGENERIC; } if (OpenDisplay(vd)) { msg_Err(vd, "Cannot create primary surface"); Close(VLC_OBJECT(vd)); return VLC_EGENERIC; } vout_display_DeleteWindow(vd, NULL); /* */ video_format_t fmt; video_format_ApplyRotation(&fmt, &vd->fmt); switch (sys->pixel_format) { case DSPF_RGB332: /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ fmt.i_chroma = VLC_CODEC_RGB8; fmt.i_rmask = 0x7 << 5; fmt.i_gmask = 0x7 << 2; fmt.i_bmask = 0x3 << 0; break; case DSPF_RGB16: /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ fmt.i_chroma = VLC_CODEC_RGB16; fmt.i_rmask = 0x1f << 11; fmt.i_gmask = 0x3f << 5; fmt.i_bmask = 0x1f << 0; break; case DSPF_RGB24: /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ fmt.i_chroma = VLC_CODEC_RGB24; fmt.i_rmask = 0xff << 16; fmt.i_gmask = 0xff << 8; fmt.i_bmask = 0xff << 0; break; case DSPF_RGB32: /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ fmt.i_chroma = VLC_CODEC_RGB32; fmt.i_rmask = 0xff << 16; fmt.i_gmask = 0xff << 8; fmt.i_bmask = 0xff << 0; break; default: msg_Err(vd, "unknown screen depth %i", sys->pixel_format); Close(VLC_OBJECT(vd)); return VLC_EGENERIC; } fmt.i_width = sys->width; fmt.i_height = sys->height; /* */ vout_display_info_t info = vd->info; info.has_hide_mouse = true; /* */ vd->fmt = fmt; vd->info = info; vd->pool = Pool; vd->prepare = NULL; vd->display = Display; vd->control = Control; vd->manage = Manage; /* */ vout_display_SendEventFullscreen(vd, true); vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true); return VLC_SUCCESS; }
/***************************************************************************** * WinVoutEventProc: This is the window event processing function. ***************************************************************************** * On Windows, when you create a window you have to attach an event processing * function to it. The aim of this function is to manage "Queued Messages" and * "Nonqueued Messages". * Queued Messages are those picked up and retransmitted by vout_Manage * (using the GetMessage and DispatchMessage functions). * Nonqueued Messages are those that Windows will send directly to this * procedure (like WM_DESTROY, WM_WINDOWPOSCHANGED...) *****************************************************************************/ static long FAR PASCAL WinVoutEventProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { event_thread_t *p_event; if( message == WM_CREATE ) { /* Store vd for future use */ p_event = (event_thread_t *)((CREATESTRUCT *)lParam)->lpCreateParams; SetWindowLongPtr( hwnd, GWLP_USERDATA, (LONG_PTR)p_event ); return TRUE; } else { LONG_PTR p_user_data = GetWindowLongPtr( hwnd, GWLP_USERDATA ); p_event = (event_thread_t *)p_user_data; if( !p_event ) { /* Hmmm mozilla does manage somehow to save the pointer to our * windowproc and still calls it after the vout has been closed. */ return DefWindowProc(hwnd, message, wParam, lParam); } } vout_display_t *vd = p_event->vd; #if 0 if( message == WM_SETCURSOR ) { msg_Err(vd, "WM_SETCURSOR: %d (t2)", p_event->is_cursor_hidden); SetCursor( p_event->is_cursor_hidden ? p_event->cursor_empty : p_event->cursor_arrow ); return 1; } #endif if( message == WM_CAPTURECHANGED ) { for( int button = 0; p_event->button_pressed; button++ ) { unsigned m = 1 << button; if( p_event->button_pressed & m ) vout_display_SendEventMouseReleased( p_event->vd, button ); p_event->button_pressed &= ~m; } p_event->button_pressed = 0; return 0; } if( hwnd == p_event->hvideownd ) { #ifdef MODULE_NAME_IS_directdraw vlc_mutex_lock( &p_event->lock ); const bool use_overlay = p_event->use_overlay; vlc_mutex_unlock( &p_event->lock ); #endif switch( message ) { #ifdef MODULE_NAME_IS_directdraw case WM_ERASEBKGND: /* For overlay, we need to erase background */ return !use_overlay ? 1 : DefWindowProc(hwnd, message, wParam, lParam); case WM_PAINT: /* ** For overlay, DefWindowProc() will erase dirty regions ** with colorkey. ** For non-overlay, vout will paint the whole window at ** regular interval, therefore dirty regions can be ignored ** to minimize repaint. */ if( !use_overlay ) { ValidateRect(hwnd, NULL); } // fall through to default #else /* ** For OpenGL and Direct3D, vout will update the whole ** window at regular interval, therefore dirty region ** can be ignored to minimize repaint. */ case WM_ERASEBKGND: /* nothing to erase */ return 1; case WM_PAINT: /* nothing to repaint */ ValidateRect(hwnd, NULL); // fall through #endif default: return DefWindowProc(hwnd, message, wParam, lParam); } } switch( message ) { case WM_WINDOWPOSCHANGED: vlc_mutex_lock( &p_event->lock ); p_event->has_moved = true; vlc_mutex_unlock( &p_event->lock ); return 0; /* the user wants to close the window */ case WM_CLOSE: vout_display_SendEventClose(vd); return 0; /* the window has been closed so shut down everything now */ case WM_DESTROY: msg_Dbg( vd, "WinProc WM_DESTROY" ); /* just destroy the window */ PostQuitMessage( 0 ); return 0; case WM_SYSCOMMAND: switch (wParam) { case IDM_TOGGLE_ON_TOP: /* toggle the "on top" status */ { msg_Dbg(vd, "WinProc WM_SYSCOMMAND: IDM_TOGGLE_ON_TOP"); HMENU hMenu = GetSystemMenu(vd->sys->hwnd, FALSE); vout_display_SendWindowState(vd, (GetMenuState(hMenu, IDM_TOGGLE_ON_TOP, MF_BYCOMMAND) & MF_CHECKED) ? VOUT_WINDOW_STATE_NORMAL : VOUT_WINDOW_STATE_ABOVE); return 0; } default: break; } break; case WM_PAINT: case WM_NCPAINT: case WM_ERASEBKGND: return DefWindowProc(hwnd, message, wParam, lParam); case WM_KILLFOCUS: return 0; case WM_SETFOCUS: return 0; case WM_GESTURE: return DecodeGesture( VLC_OBJECT(vd), p_event->p_gesture, hwnd, message, wParam, lParam ); default: //msg_Dbg( vd, "WinProc WM Default %i", message ); break; } /* Let windows handle the message */ return DefWindowProc(hwnd, message, wParam, lParam); }
/** * Get the update file and parse it * p_update has to be locked when calling this function * * \param p_update pointer to update struct * \return true if the update is valid and authenticated */ static bool GetUpdateFile( update_t *p_update ) { stream_t *p_stream = NULL; char *psz_version_line = NULL; char *psz_update_data = NULL; p_stream = stream_UrlNew( p_update->p_libvlc, UPDATE_VLC_STATUS_URL ); if( !p_stream ) { msg_Err( p_update->p_libvlc, "Failed to open %s for reading", UPDATE_VLC_STATUS_URL ); goto error; } const int64_t i_read = stream_Size( p_stream ); psz_update_data = malloc( i_read + 1 ); /* terminating '\0' */ if( !psz_update_data ) goto error; if( stream_Read( p_stream, psz_update_data, i_read ) != i_read ) { msg_Err( p_update->p_libvlc, "Couldn't download update file %s", UPDATE_VLC_STATUS_URL ); goto error; } psz_update_data[i_read] = '\0'; stream_Delete( p_stream ); p_stream = NULL; /* first line : version number */ char *psz_update_data_parser = psz_update_data; size_t i_len = strcspn( psz_update_data, "\r\n" ); psz_update_data_parser += i_len; while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' ) psz_update_data_parser++; if( !(psz_version_line = malloc( i_len + 1)) ) goto error; strncpy( psz_version_line, psz_update_data, i_len ); psz_version_line[i_len] = '\0'; p_update->release.i_extra = 0; int ret = sscanf( psz_version_line, "%i.%i.%i.%i", &p_update->release.i_major, &p_update->release.i_minor, &p_update->release.i_revision, &p_update->release.i_extra); if( ret != 3 && ret != 4 ) { msg_Err( p_update->p_libvlc, "Update version false formated" ); goto error; } /* second line : URL */ i_len = strcspn( psz_update_data_parser, "\r\n" ); if( i_len == 0 ) { msg_Err( p_update->p_libvlc, "Update file %s is corrupted: URL missing", UPDATE_VLC_STATUS_URL ); goto error; } if( !(p_update->release.psz_url = malloc( i_len + 1)) ) goto error; strncpy( p_update->release.psz_url, psz_update_data_parser, i_len ); p_update->release.psz_url[i_len] = '\0'; psz_update_data_parser += i_len; while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' ) psz_update_data_parser++; /* Remaining data : description */ i_len = strlen( psz_update_data_parser ); if( i_len == 0 ) { msg_Err( p_update->p_libvlc, "Update file %s is corrupted: description missing", UPDATE_VLC_STATUS_URL ); goto error; } if( !(p_update->release.psz_desc = malloc( i_len + 1)) ) goto error; strncpy( p_update->release.psz_desc, psz_update_data_parser, i_len ); p_update->release.psz_desc[i_len] = '\0'; /* Now that we know the status is valid, we must download its signature * to authenticate it */ signature_packet_t sign; if( download_signature( VLC_OBJECT( p_update->p_libvlc ), &sign, UPDATE_VLC_STATUS_URL ) != VLC_SUCCESS ) { msg_Err( p_update->p_libvlc, "Couldn't download signature of status file" ); goto error; } if( sign.type != BINARY_SIGNATURE && sign.type != TEXT_SIGNATURE ) { msg_Err( p_update->p_libvlc, "Invalid signature type" ); goto error; } p_update->p_pkey = (public_key_t*)malloc( sizeof( public_key_t ) ); if( !p_update->p_pkey ) goto error; if( parse_public_key( videolan_public_key, sizeof( videolan_public_key ), p_update->p_pkey, NULL ) != VLC_SUCCESS ) { msg_Err( p_update->p_libvlc, "Couldn't parse embedded public key, something went really wrong..." ); FREENULL( p_update->p_pkey ); goto error; } memcpy( p_update->p_pkey->longid, videolan_public_key_longid, 8 ); if( memcmp( sign.issuer_longid, p_update->p_pkey->longid , 8 ) != 0 ) { msg_Dbg( p_update->p_libvlc, "Need to download the GPG key" ); public_key_t *p_new_pkey = download_key( VLC_OBJECT(p_update->p_libvlc), sign.issuer_longid, videolan_public_key_longid ); if( !p_new_pkey ) { msg_Err( p_update->p_libvlc, "Couldn't download GPG key" ); FREENULL( p_update->p_pkey ); goto error; } uint8_t *p_hash = hash_sha1_from_public_key( p_new_pkey ); if( !p_hash ) { msg_Err( p_update->p_libvlc, "Failed to hash signature" ); free( p_new_pkey ); FREENULL( p_update->p_pkey ); goto error; } if( verify_signature( p_new_pkey->sig.r, p_new_pkey->sig.s, &p_update->p_pkey->key, p_hash ) == VLC_SUCCESS ) { free( p_hash ); msg_Info( p_update->p_libvlc, "Key authenticated" ); free( p_update->p_pkey ); p_update->p_pkey = p_new_pkey; } else { free( p_hash ); msg_Err( p_update->p_libvlc, "Key signature invalid !" ); goto error; } } uint8_t *p_hash = hash_sha1_from_text( psz_update_data, &sign ); if( !p_hash ) { msg_Warn( p_update->p_libvlc, "Can't compute SHA1 hash for status file" ); goto error; } else if( p_hash[0] != sign.hash_verification[0] || p_hash[1] != sign.hash_verification[1] ) { msg_Warn( p_update->p_libvlc, "Bad SHA1 hash for status file" ); free( p_hash ); goto error; } else if( verify_signature( sign.r, sign.s, &p_update->p_pkey->key, p_hash ) != VLC_SUCCESS ) { msg_Err( p_update->p_libvlc, "BAD SIGNATURE for status file" ); free( p_hash ); goto error; } else { msg_Info( p_update->p_libvlc, "Status file authenticated" ); return true; } error: if( p_stream ) stream_Delete( p_stream ); free( psz_version_line ); free( psz_update_data ); return false; }
/** * This function allocates and initializes a FB vout method. */ static int Open(vlc_object_t *object) { vout_display_t *vd = (vout_display_t *)object; vout_display_sys_t *sys; /* Allocate instance and initialize some members */ vd->sys = sys = calloc(1, sizeof(*sys)); if (!sys) return VLC_ENOMEM; /* Does the framebuffer uses hw acceleration? */ sys->is_hw_accel = var_CreateGetBool(vd, "fb-hw-accel"); /* Set tty and fb devices */ sys->tty = 0; /* 0 == /dev/tty0 == current console */ sys->is_tty = var_CreateGetBool(vd, "fb-tty"); #if !defined(WIN32) && defined(HAVE_ISATTY) /* Check that stdin is a TTY */ if (sys->is_tty && !isatty(0)) { msg_Warn(vd, "fd 0 is not a TTY"); free(sys); return VLC_EGENERIC; } msg_Warn(vd, "disabling tty handling, use with caution because " "there is no way to return to the tty."); #endif const int mode = var_CreateGetInteger(vd, "fb-mode"); bool force_resolution = true; switch (mode) { case 0: /* QCIF */ sys->width = 176; sys->height = 144; break; case 1: /* CIF */ sys->width = 352; sys->height = 288; break; case 2: /* NTSC */ sys->width = 640; sys->height = 480; break; case 3: /* PAL */ sys->width = 704; sys->height = 576; break; case 4: default: force_resolution = false; break; } /* tty handling */ if (sys->is_tty && TtyInit(vd)) { free(sys); return VLC_EGENERIC; } /* */ sys->video_ptr = MAP_FAILED; sys->picture = NULL; sys->pool = NULL; if (OpenDisplay(vd, force_resolution)) { Close(VLC_OBJECT(vd)); return VLC_EGENERIC; } /* */ video_format_t fmt = vd->fmt; msg_Err(vd, "var_info.bits_per_pixel = %d", sys->var_info.bits_per_pixel); switch (sys->var_info.bits_per_pixel) { case 8: /* FIXME: set the palette */ fmt.i_chroma = VLC_CODEC_RGB8; break; case 15: fmt.i_chroma = VLC_CODEC_RGB15; break; case 16: fmt.i_chroma = VLC_CODEC_RGB16; break; case 24: fmt.i_chroma = VLC_CODEC_RGB24; break; case 32: fmt.i_chroma = VLC_CODEC_RGB32; break; default: msg_Err(vd, "unknown screen depth %i", sys->var_info.bits_per_pixel); Close(VLC_OBJECT(vd)); return VLC_EGENERIC; } if (sys->var_info.bits_per_pixel != 8) { fmt.i_rmask = ((1 << sys->var_info.red.length) - 1) << sys->var_info.red.offset; fmt.i_gmask = ((1 << sys->var_info.green.length) - 1) << sys->var_info.green.offset; fmt.i_bmask = ((1 << sys->var_info.blue.length) - 1) << sys->var_info.blue.offset; } fmt.i_width = sys->width; fmt.i_height = sys->height; /* */ vout_display_info_t info = vd->info; info.has_hide_mouse = true; /* */ vd->fmt = fmt; vd->info = info; vd->get = Get; vd->prepare = NULL; vd->display = Display; vd->control = Control; vd->manage = Manage; /* */ vout_display_SendEventFullscreen(vd, true); vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true); return VLC_SUCCESS; }
/********************************************************************* * The Panels *********************************************************************/ SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent, int _number, bool small ) : QWidget( _parent ), p_intf( _p_intf ) { module_config_t *p_config; ConfigControl *control; number = _number; #define CONFIG_GENERIC( option, type, label, qcontrol ) \ p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \ if( p_config ) \ { \ control = new type ## ConfigControl( VLC_OBJECT(p_intf), \ p_config, label, ui.qcontrol, false ); \ controls.append( control ); \ } \ else { \ ui.qcontrol->setEnabled( false ); \ if( label ) label->setEnabled( false ); \ } #define CONFIG_BOOL( option, qcontrol ) \ p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \ if( p_config ) \ { \ control = new BoolConfigControl( VLC_OBJECT(p_intf), \ p_config, NULL, ui.qcontrol, false ); \ controls.append( control ); \ } \ else { ui.qcontrol->setEnabled( false ); } #define CONFIG_GENERIC_NO_UI( option, type, label, qcontrol ) \ p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \ if( p_config ) \ { \ control = new type ## ConfigControl( VLC_OBJECT(p_intf), \ p_config, label, qcontrol, false ); \ controls.append( control ); \ } \ else { \ QWidget *widget = label; \ qcontrol->setVisible( false ); \ if( widget ) widget->setEnabled( false ); \ } #define CONFIG_GENERIC_NO_BOOL( option, type, label, qcontrol ) \ p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \ if( p_config ) \ { \ control = new type ## ConfigControl( VLC_OBJECT(p_intf), \ p_config, label, ui.qcontrol ); \ controls.append( control ); \ } #define CONFIG_GENERIC_FILE( option, type, label, qcontrol, qbutton ) \ p_config = config_FindConfig( VLC_OBJECT(p_intf), option ); \ if( p_config ) \ { \ control = new type ## ConfigControl( VLC_OBJECT(p_intf), \ p_config, label, qcontrol, qbutton ); \ controls.append( control ); \ } #define START_SPREFS_CAT( name , label ) \ case SPrefs ## name: \ { \ Ui::SPrefs ## name ui; \ ui.setupUi( panel ); \ panel_label->setText( label ); #define END_SPREFS_CAT \ break; \ } QVBoxLayout *panel_layout = new QVBoxLayout(); QWidget *panel = new QWidget(); panel_layout->setMargin( 3 ); // Title Label QLabel *panel_label = new QLabel; QFont labelFont = QApplication::font( static_cast<QWidget*>(0) ); labelFont.setPointSize( labelFont.pointSize() + 6 ); labelFont.setFamily( "Verdana" ); panel_label->setFont( labelFont ); // Title <hr> QFrame *title_line = new QFrame; title_line->setFrameShape(QFrame::HLine); title_line->setFrameShadow(QFrame::Sunken); QFont italicFont = QApplication::font( static_cast<QWidget*>(0) ); italicFont.setItalic( true ); switch( number ) { /****************************** * VIDEO Panel Implementation * ******************************/ START_SPREFS_CAT( Video , qtr("Video Settings") ); CONFIG_BOOL( "video", enableVideo ); CONFIG_BOOL( "fullscreen", fullscreen ); CONFIG_BOOL( "overlay", overlay ); CONFIG_BOOL( "video-on-top", alwaysOnTop ); CONFIG_BOOL( "video-deco", windowDecorations ); CONFIG_BOOL( "skip-frames", skipFrames ); CONFIG_GENERIC( "vout", Module, ui.voutLabel, outputModule ); CONFIG_BOOL( "video-wallpaper", wallpaperMode ); #ifdef WIN32 CONFIG_GENERIC( "directx-device", StringList, ui.dxDeviceLabel, dXdisplayDevice ); CONFIG_BOOL( "directx-hw-yuv", hwYUVBox ); #else ui.directXBox->setVisible( false ); ui.hwYUVBox->setVisible( false ); #endif CONFIG_GENERIC( "deinterlace", IntegerList, ui.deinterLabel, deinterlaceBox ); CONFIG_GENERIC( "deinterlace-mode", StringList, ui.deinterModeLabel, deinterlaceModeBox ); CONFIG_GENERIC( "aspect-ratio", String, ui.arLabel, arLine ); CONFIG_GENERIC_FILE( "snapshot-path", Directory, ui.dirLabel, ui.snapshotsDirectory, ui.snapshotsDirectoryBrowse ); CONFIG_GENERIC( "snapshot-prefix", String, ui.prefixLabel, snapshotsPrefix ); CONFIG_BOOL( "snapshot-sequential", snapshotsSequentialNumbering ); CONFIG_GENERIC( "snapshot-format", StringList, ui.arLabel, snapshotsFormat ); END_SPREFS_CAT; /****************************** * AUDIO Panel Implementation * ******************************/ START_SPREFS_CAT( Audio, qtr("Audio Settings") ); CONFIG_BOOL( "audio", enableAudio ); ui.SPrefsAudio_zone->setEnabled( ui.enableAudio->isChecked() ); CONNECT( ui.enableAudio, toggled( bool ), ui.SPrefsAudio_zone, setEnabled( bool ) ); #define audioCommon( name ) \ QWidget * name ## Control = new QWidget( ui.outputAudioBox ); \ QHBoxLayout * name ## Layout = new QHBoxLayout( name ## Control); \ name ## Layout->setMargin( 0 ); \ name ## Layout->setSpacing( 0 ); \ QLabel * name ## Label = new QLabel( qtr( "Device:" ), name ## Control ); \ name ## Label->setMinimumSize(QSize(250, 0)); \ name ## Layout->addWidget( name ## Label ); \ #define audioControl( name) \ audioCommon( name ) \ QComboBox * name ## Device = new QComboBox( name ## Control ); \ name ## Layout->addWidget( name ## Device ); \ name ## Label->setBuddy( name ## Device ); \ outputAudioLayout->addWidget( name ## Control, outputAudioLayout->rowCount(), 0, 1, -1 ); #define audioControl2( name) \ audioCommon( name ) \ QLineEdit * name ## Device = new QLineEdit( name ## Control ); \ name ## Layout->addWidget( name ## Device ); \ name ## Label->setBuddy( name ## Device ); \ QPushButton * name ## Browse = new QPushButton( qtr( "Browse..." ), name ## Control); \ name ## Layout->addWidget( name ## Browse ); \ outputAudioLayout->addWidget( name ## Control, outputAudioLayout->rowCount(), 0, 1, -1 ); /* Build if necessary */ QGridLayout * outputAudioLayout = qobject_cast<QGridLayout *>(ui.outputAudioBox->layout()); #ifdef WIN32 audioControl( DirectX ); optionWidgets.append( DirectXControl ); CONFIG_GENERIC_NO_UI( "directx-audio-device-name", StringList, DirectXLabel, DirectXDevice ); #else if( module_exists( "alsa" ) ) { audioControl( alsa ); optionWidgets.append( alsaControl ); CONFIG_GENERIC_NO_UI( "alsa-audio-device" , StringList, alsaLabel, alsaDevice ); } else optionWidgets.append( NULL ); if( module_exists( "oss" ) ) { audioControl2( OSS ); optionWidgets.append( OSSControl ); CONFIG_GENERIC_FILE( "oss-audio-device" , File, NULL, OSSDevice, OSSBrowse ); } else optionWidgets.append( NULL ); #endif #undef audioControl2 #undef audioControl #undef audioCommon /* Audio Options */ CONFIG_GENERIC_NO_BOOL( "volume" , IntegerRangeSlider, NULL, defaultVolume ); CONNECT( ui.defaultVolume, valueChanged( int ), this, updateAudioVolume( int ) ); CONFIG_BOOL( "qt-autosave-volume", keepVolumeRadio ); ui.defaultVolume_zone->setEnabled( ui.resetVolumeRadio->isChecked() ); CONNECT( ui.resetVolumeRadio, toggled( bool ), ui.defaultVolume_zone, setEnabled( bool ) ); CONFIG_GENERIC( "audio-language" , String , ui.langLabel, preferredAudioLanguage ); CONFIG_BOOL( "spdif", spdifBox ); CONFIG_GENERIC( "force-dolby-surround", IntegerList, ui.dolbyLabel, detectionDolby ); CONFIG_GENERIC_NO_BOOL( "norm-max-level" , Float, NULL, volNormSpin ); CONFIG_GENERIC( "audio-replay-gain-mode", StringList, ui.replayLabel, replayCombo ); CONFIG_GENERIC( "audio-visual" , Module , ui.visuLabel, visualisation); CONFIG_BOOL( "audio-time-stretch", autoscaleBox ); /* Audio Output Specifics */ CONFIG_GENERIC( "aout", Module, ui.outputLabel, outputModule ); CONNECT( ui.outputModule, currentIndexChanged( int ), this, updateAudioOptions( int ) ); /* File output exists on all platforms */ CONFIG_GENERIC_FILE( "audiofile-file", File, ui.fileLabel, ui.fileName, ui.fileBrowseButton ); optionWidgets.append( ui.fileControl ); optionWidgets.append( ui.outputModule ); optionWidgets.append( ui.volNormBox ); /*Little mofification of ui.volumeValue to compile with Qt < 4.3 */ ui.volumeValue->setButtonSymbols(QAbstractSpinBox::NoButtons); optionWidgets.append( ui.volumeValue ); optionWidgets.append( ui.headphoneEffect ); optionWidgets.append( ui.spdifBox ); updateAudioOptions( ui.outputModule->currentIndex() ); /* LastFM */ if( module_exists( "audioscrobbler" ) ) { CONFIG_GENERIC( "lastfm-username", String, ui.lastfm_user_label, lastfm_user_edit ); CONFIG_GENERIC( "lastfm-password", String, ui.lastfm_pass_label, lastfm_pass_edit ); if( config_ExistIntf( VLC_OBJECT( p_intf ), "audioscrobbler" ) ) ui.lastfm->setChecked( true ); else ui.lastfm->setChecked( false ); ui.lastfm_zone->setVisible( ui.lastfm->isChecked() ); CONNECT( ui.lastfm, toggled( bool ), ui.lastfm_zone, setVisible( bool ) ); CONNECT( ui.lastfm, stateChanged( int ), this, lastfm_Changed( int ) ); } else {
/***************************************************************************** * Called through lua_scripts_batch_execute to call 'probe' on * the script pointed by psz_filename. *****************************************************************************/ static int probe_luascript(vlc_object_t *obj, const char *filename, const luabatch_context_t *ctx) { stream_t *s = (stream_t *)obj; struct vlclua_playlist *sys = s->p_sys; /* Initialise Lua state structure */ lua_State *L = luaL_newstate(); if( !L ) return VLC_ENOMEM; sys->L = L; /* Load Lua libraries */ luaL_openlibs( L ); /* FIXME: Don't open all the libs? */ vlclua_set_this(L, s); luaL_register_namespace( L, "vlc", p_reg ); luaopen_msg( L ); luaopen_strings( L ); luaopen_stream( L ); luaopen_variables( L ); luaopen_xml( L ); if (sys->path != NULL) lua_pushstring(L, sys->path); else lua_pushnil(L); lua_setfield( L, -2, "path" ); if (sys->access != NULL) lua_pushstring(L, sys->access); else lua_pushnil(L); lua_setfield( L, -2, "access" ); lua_pop( L, 1 ); /* Setup the module search path */ if (vlclua_add_modules_path(L, filename)) { msg_Warn(s, "error setting the module search path for %s", filename); goto error; } /* Load and run the script(s) */ if (vlclua_dofile(VLC_OBJECT(s), L, filename)) { msg_Warn(s, "error loading script %s: %s", filename, lua_tostring(L, lua_gettop(L))); goto error; } lua_getglobal( L, "probe" ); if( !lua_isfunction( L, -1 ) ) { msg_Warn(s, "error running script %s: function %s(): %s", filename, "probe", "not found"); goto error; } if( lua_pcall( L, 0, 1, 0 ) ) { msg_Warn(s, "error running script %s: function %s(): %s", filename, "probe", lua_tostring(L, lua_gettop(L))); goto error; } if( lua_gettop( L ) ) { if( lua_toboolean( L, 1 ) ) { msg_Dbg(s, "Lua playlist script %s's " "probe() function was successful", filename ); lua_pop( L, 1 ); sys->filename = strdup(filename); return VLC_SUCCESS; } } (void) ctx; error: lua_pop( L, 1 ); lua_close(sys->L); return VLC_EGENERIC; }
/***************************************************************************** * Activate: initialize and create stuff *****************************************************************************/ static int Open( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys; char *psz_address; char *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL, *psz_crl = NULL; int i_port = 0; char *psz_src = NULL; httpd_handler_sys_t *p_art_handler_sys = NULL; psz_address = var_CreateGetNonEmptyString( p_intf, "http-host" ); if( psz_address != NULL ) { char *psz_parser = strrchr( psz_address, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; i_port = atoi( psz_parser ); } } else psz_address = strdup(""); p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) ); if( !p_intf->p_sys ) { free( psz_address ); return( VLC_ENOMEM ); } p_sys->p_playlist = pl_Get( p_this ); p_sys->p_input = NULL; p_sys->p_vlm = NULL; p_sys->psz_address = psz_address; p_sys->i_port = i_port; p_sys->p_art_handler = NULL; /* determine file handler associations */ p_sys->i_handlers = 0; p_sys->pp_handlers = NULL; #if defined( HAVE_FORK ) || defined( WIN32 ) psz_src = var_InheritString( p_intf, "http-handlers" ); if( psz_src != NULL ) { char *p = psz_src; while( p != NULL ) { http_association_t *p_handler; char *psz_ext = p; char *psz_program, *psz_options; p = strchr( p, '=' ); if( p == NULL ) break; *p++ = '\0'; psz_program = p; p = strchr( p, ',' ); if( p != NULL ) *p++ = '\0'; p_handler = malloc( sizeof( http_association_t ) ); p_handler->psz_ext = strdup( psz_ext ); psz_options = FirstWord( psz_program, psz_program ); p_handler->i_argc = 0; p_handler->ppsz_argv = NULL; TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv, strdup( psz_program ) ); while( psz_options != NULL && *psz_options ) { char *psz_next = FirstWord( psz_options, psz_options ); TAB_APPEND( p_handler->i_argc, p_handler->ppsz_argv, strdup( psz_options ) ); psz_options = psz_next; } /* NULL will be appended later on */ TAB_APPEND( p_sys->i_handlers, p_sys->pp_handlers, p_handler ); } free( psz_src ); } #endif /* determine SSL configuration */ psz_cert = var_InheritString( p_intf, "http-intf-cert" ); if ( psz_cert != NULL ) { msg_Dbg( p_intf, "enabling TLS for HTTP interface (cert file: %s)", psz_cert ); psz_key = var_InheritString( p_intf, "http-intf-key" ); psz_ca = var_InheritString( p_intf, "http-intf-ca" ); psz_crl = var_InheritString( p_intf, "http-intf-crl" ); if( i_port <= 0 ) i_port = 8443; } else { if( i_port <= 0 ) i_port= 8080; } msg_Dbg( p_intf, "base %s:%d", psz_address, i_port ); p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_intf), psz_address, i_port, psz_cert, psz_key, psz_ca, psz_crl ); free( psz_cert ); free( psz_key ); free( psz_ca ); free( psz_crl ); if( p_sys->p_httpd_host == NULL ) { msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port ); free( p_sys->psz_address ); free( p_sys ); return VLC_EGENERIC; } else { char psz_tmp[NI_MAXHOST + 6]; /* Ugly hack to run several HTTP servers on different ports */ snprintf( psz_tmp, sizeof (psz_tmp), "%s:%d", psz_address, i_port + 1 ); var_Create(p_intf->p_libvlc, "http-host", VLC_VAR_STRING ); var_SetString( p_intf->p_libvlc, "http-host", psz_tmp ); } p_sys->i_files = 0; p_sys->pp_files = NULL; psz_src = var_InheritString( p_intf, "http-src" ); if( psz_src == NULL ) { char *data_path = config_GetDataDir( p_intf ); if( asprintf( &psz_src, "%s" DIR_SEP "http", data_path ) == -1 ) psz_src = NULL; free( data_path ); } if( psz_src == NULL ) { msg_Err( p_intf, "invalid web interface source directory" ); goto failed; } /* remove trainling \ or / */ if( psz_src[strlen( psz_src ) - 1] == '\\' || psz_src[strlen( psz_src ) - 1] == '/' ) { psz_src[strlen( psz_src ) - 1] = '\0'; } ParseDirectory( p_intf, psz_src, psz_src ); if( p_sys->i_files <= 0 ) { msg_Err( p_intf, "cannot find any file in directory %s", psz_src ); goto failed; } if( var_InheritBool( p_intf, "http-album-art" ) ) { httpd_handler_sys_t *p_art_handler_sys = malloc( sizeof( httpd_handler_sys_t ) ); if( !p_art_handler_sys ) { msg_Err( p_intf, "out of memory: could not allocate /art URL" ); goto failed; } p_art_handler_sys->file.p_intf = p_intf; p_art_handler_sys->file.file = NULL; p_art_handler_sys->file.name = NULL; /* TODO: use ACL and login/password stuff here too */ p_sys->p_art_handler = httpd_HandlerNew( p_sys->p_httpd_host, "/art", NULL, NULL, NULL, ArtCallback, p_art_handler_sys ); } free( psz_src ); return VLC_SUCCESS; failed: free( psz_src ); free( p_sys->pp_files ); httpd_HostDelete( p_sys->p_httpd_host ); free( p_sys->psz_address ); free( p_sys ); free( p_art_handler_sys ); return VLC_EGENERIC; }
/***************************************************************************** * Open: *****************************************************************************/ static int Open( vlc_object_t *p_this ) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; vlc_value_t val; char *psz_files, *psz_sizes; int i_height = 0, i_width = 0; vlc_init_avcodec(); p_sys = calloc( 1, sizeof(sout_stream_sys_t) ); if( !p_sys ) return VLC_ENOMEM; if( !p_stream->p_next ) { msg_Err( p_stream, "cannot create chain" ); free( p_sys ); return VLC_EGENERIC; } config_ChainParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); var_Get( p_stream, SOUT_CFG_PREFIX "files", &val ); psz_files = val.psz_string; var_Get( p_stream, SOUT_CFG_PREFIX "sizes", &val ); psz_sizes = val.psz_string; p_sys->i_nb_pictures = 0; while ( psz_files && *psz_files ) { char * psz_file = psz_files; char * psz_size = psz_sizes; while ( *psz_files && *psz_files != ':' ) psz_files++; if ( *psz_files == ':' ) *psz_files++ = '\0'; if ( *psz_sizes ) { while ( *psz_sizes && *psz_sizes != ':' ) psz_sizes++; if ( *psz_sizes == ':' ) *psz_sizes++ = '\0'; if ( sscanf( psz_size, "%dx%d", &i_width, &i_height ) != 2 ) { msg_Err( p_stream, "bad size %s for file %s", psz_size, psz_file ); free( p_sys ); return VLC_EGENERIC; } } if ( UnpackFromFile( p_stream, psz_file, i_width, i_height, &p_sys->p_pictures[p_sys->i_nb_pictures] ) < 0 ) { free( p_sys ); return VLC_EGENERIC; } p_sys->i_nb_pictures++; } var_Get( p_stream, SOUT_CFG_PREFIX "aspect-ratio", &val ); if ( val.psz_string ) { char *psz_parser = strchr( val.psz_string, ':' ); if( psz_parser ) { *psz_parser++ = '\0'; p_sys->i_aspect = atoi( val.psz_string ) * VOUT_ASPECT_FACTOR / atoi( psz_parser ); } else { msg_Warn( p_stream, "bad aspect ratio %s", val.psz_string ); p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3; } free( val.psz_string ); } else { p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3; } var_Get( p_stream, SOUT_CFG_PREFIX "port", &val ); p_sys->i_fd = net_ListenUDP1( VLC_OBJECT(p_stream), NULL, val.i_int ); if ( p_sys->i_fd < 0 ) { free( p_sys ); return VLC_EGENERIC; } var_Get( p_stream, SOUT_CFG_PREFIX "command", &val ); p_sys->i_cmd = val.i_int; p_sys->i_old_cmd = 0; var_Get( p_stream, SOUT_CFG_PREFIX "gop", &val ); p_sys->i_gop = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "qscale", &val ); p_sys->i_qscale = val.i_int; var_Get( p_stream, SOUT_CFG_PREFIX "mute-audio", &val ); p_sys->b_audio = val.b_bool; p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_stream->p_sys = p_sys; #if LIBAVCODEC_VERSION_MAJOR >= 54 char *psz_opts = var_InheritString( p_stream, SOUT_CFG_PREFIX "options" ); if (psz_opts && *psz_opts) { p_sys->options = vlc_av_get_options(psz_opts); } else { p_sys->options = NULL; } free(psz_opts); #endif return VLC_SUCCESS; }
/** * Common open function */ static int OpenCommon( vlc_object_t *p_this, bool b_sub ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; char *psz_filename; /* */ if( !b_sub && !es_format_IsSimilar( &p_filter->fmt_in, &p_filter->fmt_out ) ) { msg_Err( p_filter, "Input and output format does not match" ); return VLC_EGENERIC; } /* */ p_filter->p_sys = p_sys = malloc( sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; /* */ p_sys->p_blend = NULL; if( !b_sub ) { p_sys->p_blend = filter_NewBlend( VLC_OBJECT(p_filter), &p_filter->fmt_in.video ); if( !p_sys->p_blend ) { free( p_sys ); return VLC_EGENERIC; } } /* */ config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options, p_filter->p_cfg ); /* */ logo_list_t *p_list = &p_sys->list; psz_filename = var_CreateGetStringCommand( p_filter, "logo-file" ); if( !psz_filename ) { if( p_sys->p_blend ) filter_DeleteBlend( p_sys->p_blend ); free( p_sys ); return VLC_ENOMEM; } if( *psz_filename == '\0' ) msg_Warn( p_this, "no logo file specified" ); p_list->i_alpha = var_CreateGetIntegerCommand( p_filter, "logo-opacity"); p_list->i_alpha = __MAX( __MIN( p_list->i_alpha, 255 ), 0 ); p_list->i_delay = var_CreateGetIntegerCommand( p_filter, "logo-delay" ); p_list->i_repeat = var_CreateGetIntegerCommand( p_filter, "logo-repeat" ); p_sys->i_pos = var_CreateGetIntegerCommand( p_filter, "logo-position" ); p_sys->i_pos_x = var_CreateGetIntegerCommand( p_filter, "logo-x" ); p_sys->i_pos_y = var_CreateGetIntegerCommand( p_filter, "logo-y" ); /* Ignore aligment if a position is given for video filter */ if( !b_sub && p_sys->i_pos_x >= 0 && p_sys->i_pos_y >= 0 ) p_sys->i_pos = 0; vlc_mutex_init( &p_sys->lock ); LogoListLoad( p_this, p_list, psz_filename ); p_sys->b_spu_update = true; p_sys->b_mouse_grab = false; for( int i = 0; ppsz_filter_callbacks[i]; i++ ) var_AddCallback( p_filter, ppsz_filter_callbacks[i], LogoCallback, p_sys ); /* Misc init */ if( b_sub ) { p_filter->pf_sub_filter = FilterSub; } else { p_filter->pf_video_filter = FilterVideo; p_filter->pf_video_mouse = Mouse; } free( psz_filename ); return VLC_SUCCESS; }
void SoundWidget::setMuted( bool mute ) { b_is_muted = mute; playlist_t *p_playlist = pl_Get( p_intf ); aout_SetMute( VLC_OBJECT(p_playlist), NULL, mute ); }
static int WindowOpen( vout_window_t *pWnd, const vout_window_cfg_t *cfg ) { if( cfg->type != VOUT_WINDOW_TYPE_INVALID ) { #ifdef X11_SKINS if( cfg->type != VOUT_WINDOW_TYPE_XID ) #else if( cfg->type != VOUT_WINDOW_TYPE_HWND ) #endif return VLC_EGENERIC; } vout_window_sys_t* sys; vlc_mutex_lock( &skin_load.mutex ); intf_thread_t *pIntf = skin_load.intf; if( pIntf ) vlc_object_hold( pIntf ); vlc_mutex_unlock( &skin_load.mutex ); if( pIntf == NULL ) return VLC_EGENERIC; if( !var_InheritBool( pIntf, "skinned-video") || cfg->is_standalone ) { vlc_object_release( pIntf ); return VLC_EGENERIC; } sys = (vout_window_sys_t*)calloc( 1, sizeof( *sys ) ); if( !sys ) { vlc_object_release( pIntf ); return VLC_ENOMEM; } pWnd->sys = sys; pWnd->sys->cfg = *cfg; pWnd->sys->pIntf = pIntf; #ifdef X11_SKINS pWnd->type = VOUT_WINDOW_TYPE_XID; #else pWnd->type = VOUT_WINDOW_TYPE_HWND; #endif pWnd->control = WindowControl; // force execution in the skins2 thread context CmdExecuteBlock* cmd = new CmdExecuteBlock( pIntf, VLC_OBJECT( pWnd ), WindowOpenLocal ); CmdExecuteBlock::executeWait( CmdGenericPtr( cmd ) ); #ifdef X11_SKINS pWnd->display.x11 = NULL; if( !pWnd->handle.xid ) #else if( !pWnd->handle.hwnd ) #endif { free( sys ); vlc_object_release( pIntf ); return VLC_EGENERIC; } return VLC_SUCCESS; }
void libvlc_audio_set_mute( libvlc_media_player_t *mp, int mute ) { aout_SetMute( VLC_OBJECT(mp), NULL, !!mute ); }
static int Open(vlc_va_t *va, AVCodecContext *ctx, const es_format_t *fmt) { VdpStatus err; VdpDecoderProfile profile; int level = fmt->i_level; if (av_vdpau_get_profile(ctx, &profile)) { msg_Err(va, "unsupported codec %d or profile %d", ctx->codec_id, fmt->i_profile); return VLC_EGENERIC; } switch (ctx->codec_id) { case AV_CODEC_ID_MPEG1VIDEO: level = VDP_DECODER_LEVEL_MPEG1_NA; break; case AV_CODEC_ID_MPEG2VIDEO: level = VDP_DECODER_LEVEL_MPEG2_HL; break; case AV_CODEC_ID_H263: level = VDP_DECODER_LEVEL_MPEG4_PART2_ASP_L5; break; case AV_CODEC_ID_H264: if ((fmt->i_profile & FF_PROFILE_H264_INTRA) && (fmt->i_level == 11)) level = VDP_DECODER_LEVEL_H264_1b; default: break; } if (!vlc_xlib_init(VLC_OBJECT(va))) { msg_Err(va, "Xlib is required for VDPAU"); return VLC_EGENERIC; } vlc_va_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; sys->context = av_vdpau_alloc_context(); if (unlikely(sys->context == NULL)) { free(sys); return VLC_ENOMEM; } err = vdp_get_x11(NULL, -1, &sys->vdp, &sys->device); if (err != VDP_STATUS_OK) { free(sys->context); free(sys); return VLC_EGENERIC; } void *func; err = vdp_get_proc_address(sys->vdp, sys->device, VDP_FUNC_ID_DECODER_RENDER, &func); if (err != VDP_STATUS_OK) goto error; sys->context->decoder = VDP_INVALID_HANDLE; sys->context->render = func; sys->profile = profile; /* Check capabilities */ VdpBool support; uint32_t l, mb, w, h; if (vdp_video_surface_query_capabilities(sys->vdp, sys->device, VDP_CHROMA_TYPE_420, &support, &w, &h) != VDP_STATUS_OK) support = VDP_FALSE; if (!support) { msg_Err(va, "video surface format not supported: %s", "YUV 4:2:0"); goto error; } msg_Dbg(va, "video surface limits: %"PRIu32"x%"PRIu32, w, h); if (w < fmt->video.i_width || h < fmt->video.i_height) { msg_Err(va, "video surface above limits: %ux%u", fmt->video.i_width, fmt->video.i_height); goto error; } if (vdp_decoder_query_capabilities(sys->vdp, sys->device, profile, &support, &l, &mb, &w, &h) != VDP_STATUS_OK) support = VDP_FALSE; if (!support) { msg_Err(va, "decoder profile not supported: %u", profile); goto error; } msg_Dbg(va, "decoder profile limits: level %"PRIu32" mb %"PRIu32" " "%"PRIu32"x%"PRIu32, l, mb, w, h); if ((int)l < level || w < fmt->video.i_width || h < fmt->video.i_height) { msg_Err(va, "decoder profile above limits: level %d %ux%u", level, fmt->video.i_width, fmt->video.i_height); goto error; } const char *infos; if (vdp_get_information_string(sys->vdp, &infos) != VDP_STATUS_OK) infos = "VDPAU"; va->sys = sys; va->description = infos; va->pix_fmt = AV_PIX_FMT_VDPAU; va->setup = Setup; va->get = Lock; va->release = Unlock; va->extract = Copy; return VLC_SUCCESS; error: vdp_release_x11(sys->vdp); av_free(sys->context); free(sys); return VLC_EGENERIC; }
static int Open(vlc_object_t *p_this) { struct aout_sys_t *p_sys; void *p_library; aout_instance_t *p_aout = (aout_instance_t*)(p_this); int status; int afSampleRate, afFrameCount, afLatency, minBufCount, minFrameCount; int type, channel, rate, format, size; p_library = InitLibrary(); if (!p_library) { msg_Err(VLC_OBJECT(p_this), "Could not initialize libmedia.so!"); return VLC_EGENERIC; } p_sys = (struct aout_sys_t*)malloc(sizeof(aout_sys_t)); if (p_sys == NULL) return VLC_ENOMEM; p_sys->libmedia = p_library; // AudioSystem::MUSIC = 3 type = 3; p_sys->type = type; // 4000 <= frequency <= 48000 if (p_aout->output.output.i_rate < 4000) p_aout->output.output.i_rate = 4000; if (p_aout->output.output.i_rate > 48000) p_aout->output.output.i_rate = 48000; rate = p_aout->output.output.i_rate; p_sys->rate = rate; // U8/S16 only if (p_aout->output.output.i_format != VLC_CODEC_U8 && p_aout->output.output.i_format != VLC_CODEC_S16L) p_aout->output.output.i_format = VLC_CODEC_S16L; // AudioSystem::PCM_16_BIT = 1 // AudioSystem::PCM_8_BIT = 2 format = (p_aout->output.output.i_format == VLC_CODEC_S16L) ? 1 : 2; p_sys->format = format; // TODO: android supports more channels channel = aout_FormatNbChannels(&p_aout->output.output); if (channel > 2) { channel = 2; p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } // AudioSystem::CHANNEL_OUT_STEREO = 12 // AudioSystem::CHANNEL_OUT_MONO = 4 channel = (channel == 2) ? 12 : 4; p_sys->channel = channel; // use the minium value if (!at_getMinFrameCount) { status = as_getOutputSamplingRate(&afSampleRate, type); status ^= as_getOutputFrameCount(&afFrameCount, type); status ^= as_getOutputLatency((uint32_t*)(&afLatency), type); if (status != 0) { free(p_sys); return VLC_EGENERIC; } minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate); if (minBufCount < 2) minBufCount = 2; minFrameCount = (afFrameCount * rate * minBufCount) / afSampleRate; p_aout->output.i_nb_samples = minFrameCount; } else { status = at_getMinFrameCount(&p_aout->output.i_nb_samples, type, rate); if (status != 0) { free(p_sys); return VLC_EGENERIC; } } p_aout->output.i_nb_samples <<= 1; p_sys->size = p_aout->output.i_nb_samples; // sizeof(AudioTrack) == 0x58 (not sure) on 2.2.1, this should be enough p_sys->AudioTrack = malloc(256); if (!p_sys->AudioTrack) { free(p_sys); return VLC_ENOMEM; } // higher than android 2.2 if (at_ctor) at_ctor(p_sys->AudioTrack, p_sys->type, p_sys->rate, p_sys->format, p_sys->channel, p_sys->size, 0, NULL, NULL, 0, 0); // higher than android 1.6 else if (at_ctor_legacy) at_ctor_legacy(p_sys->AudioTrack, p_sys->type, p_sys->rate, p_sys->format, p_sys->channel, p_sys->size, 0, NULL, NULL, 0); status = at_initCheck(p_sys->AudioTrack); // android 1.6 if (status != 0) { p_sys->channel = (p_sys->channel == 12) ? 2 : 1; at_ctor_legacy(p_sys->AudioTrack, p_sys->type, p_sys->rate, p_sys->format, p_sys->channel, p_sys->size, 0, NULL, NULL, 0); status = at_initCheck(p_sys->AudioTrack); } if (status != 0) { msg_Err(p_aout, "Cannot create AudioTrack!"); free(p_sys->AudioTrack); free(p_sys); return VLC_EGENERIC; } p_aout->output.p_sys = p_sys; p_aout->output.pf_play = Play; at_start(p_sys->AudioTrack); return VLC_SUCCESS; }
/** * Initialize a libvlc instance * This function initializes a previously allocated libvlc instance: * - CPU detection * - gettext initialization * - message queue, module bank and playlist initialization * - configuration and commandline parsing */ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, const char *ppsz_argv[] ) { libvlc_priv_t *priv = libvlc_priv (p_libvlc); char * psz_modules = NULL; char * psz_parser = NULL; char * psz_control = NULL; char *psz_val; /* System specific initialization code */ system_Init(); vlc_LogPreinit(p_libvlc); /* Initialize the module bank and load the configuration of the * core module. We need to do this at this stage to be able to display * a short help if required by the user. (short help == core module * options) */ module_InitBank (); /* Get command line options that affect module loading. */ if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, NULL ) ) { module_EndBank (false); return VLC_EGENERIC; } vlc_threads_setup (p_libvlc); /* Load the builtins and plugins into the module_bank. * We have to do it before config_Load*() because this also gets the * list of configuration options exported by each module and loads their * default values. */ size_t module_count = module_LoadPlugins (p_libvlc); /* * Override default configuration with config file settings */ if( !var_InheritBool( p_libvlc, "ignore-config" ) ) { if( var_InheritBool( p_libvlc, "reset-config" ) ) config_SaveConfigFile( p_libvlc ); /* Save default config */ else config_LoadConfigFile( p_libvlc ); } /* * Override configuration with command line settings */ int vlc_optind; if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) ) { vlc_LogDeinit (p_libvlc); module_EndBank (true); return VLC_EGENERIC; } vlc_LogInit(p_libvlc); /* * Support for gettext */ #if defined( ENABLE_NLS ) \ && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) ) vlc_bindtextdomain (PACKAGE_NAME); #endif /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */ msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") ); if (config_PrintHelp (VLC_OBJECT(p_libvlc))) { module_EndBank (true); exit(0); } if( module_count <= 1 ) { msg_Err( p_libvlc, "No plugins found! Check your VLC installation."); vlc_LogDeinit (p_libvlc); module_EndBank (true); return VLC_ENOMOD; } #ifdef HAVE_DAEMON /* Check for daemon mode */ if( var_InheritBool( p_libvlc, "daemon" ) ) { if( daemon( 1, 0) != 0 ) { msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" ); vlc_LogDeinit (p_libvlc); module_EndBank (true); return VLC_ENOMEM; } /* lets check if we need to write the pidfile */ char *pidfile = var_InheritString( p_libvlc, "pidfile" ); if( pidfile != NULL ) { FILE *stream = vlc_fopen( pidfile, "w" ); if( stream != NULL ) { fprintf( stream, "%d", (int)getpid() ); fclose( stream ); msg_Dbg( p_libvlc, "written PID file %s", pidfile ); } else msg_Err( p_libvlc, "cannot write PID file %s: %s", pidfile, vlc_strerror_c(errno) ); free( pidfile ); } } else { var_Create( p_libvlc, "pidfile", VLC_VAR_STRING ); var_SetString( p_libvlc, "pidfile", "" ); } #endif if( libvlc_InternalDialogInit( p_libvlc ) != VLC_SUCCESS ) { vlc_LogDeinit (p_libvlc); module_EndBank (true); return VLC_ENOMEM; } if( libvlc_InternalKeystoreInit( p_libvlc ) != VLC_SUCCESS ) msg_Warn( p_libvlc, "memory keystore init failed" ); /* FIXME: could be replaced by using Unix sockets */ #ifdef HAVE_DBUS #define MPRIS_APPEND "/org/mpris/MediaPlayer2/TrackList/Append" #define MPRIS_BUS_NAME "org.mpris.MediaPlayer2.vlc" #define MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2" #define MPRIS_TRACKLIST_INTERFACE "org.mpris.MediaPlayer2.TrackList" if( var_InheritBool( p_libvlc, "one-instance" ) || ( var_InheritBool( p_libvlc, "one-instance-when-started-from-file" ) && var_InheritBool( p_libvlc, "started-from-file" ) ) ) { for( int i = vlc_optind; i < i_argc; i++ ) if( ppsz_argv[i][0] == ':' ) { msg_Err( p_libvlc, "item option %s incompatible with single instance", ppsz_argv[i] ); goto dbus_out; } /* Initialise D-Bus interface, check for other instances */ dbus_threads_init_default(); DBusError err; dbus_error_init( &err ); /* connect to the session bus */ DBusConnection *conn = dbus_bus_get( DBUS_BUS_SESSION, &err ); if( conn == NULL ) { msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s", err.message ); dbus_error_free( &err ); goto dbus_out; } /* check if VLC is available on the bus * if not: D-Bus control is not enabled on the other * instance and we can't pass MRLs to it */ /* FIXME: This check is totally brain-dead and buggy. */ if( !dbus_bus_name_has_owner( conn, MPRIS_BUS_NAME, &err ) ) { dbus_connection_unref( conn ); if( dbus_error_is_set( &err ) ) { msg_Err( p_libvlc, "D-Bus error: %s", err.message ); } else msg_Dbg( p_libvlc, "No media player running. Continuing normally." ); dbus_error_free( &err ); goto dbus_out; } const dbus_bool_t play = !var_InheritBool( p_libvlc, "playlist-enqueue" ); msg_Warn( p_libvlc, "media player running. Exiting..."); for( int i = vlc_optind; i < i_argc; i++ ) { DBusMessage *msg = dbus_message_new_method_call( MPRIS_BUS_NAME, MPRIS_OBJECT_PATH, MPRIS_TRACKLIST_INTERFACE, "AddTrack" ); if( unlikely(msg == NULL) ) continue; /* We need to resolve relative paths in this instance */ char *mrl; if( strstr( ppsz_argv[i], "://" ) ) mrl = strdup( ppsz_argv[i] ); else mrl = vlc_path2uri( ppsz_argv[i], NULL ); if( mrl == NULL ) { dbus_message_unref( msg ); continue; } const char *after_track = MPRIS_APPEND; /* append MRLs */ if( !dbus_message_append_args( msg, DBUS_TYPE_STRING, &mrl, DBUS_TYPE_OBJECT_PATH, &after_track, DBUS_TYPE_BOOLEAN, &play, DBUS_TYPE_INVALID ) ) { dbus_message_unref( msg ); msg = NULL; free( mrl ); continue; } msg_Dbg( p_libvlc, "Adds %s to the running media player", mrl ); free( mrl ); /* send message and get a handle for a reply */ DBusMessage *reply = dbus_connection_send_with_reply_and_block( conn, msg, -1, &err ); dbus_message_unref( msg ); if( reply == NULL ) { msg_Err( p_libvlc, "D-Bus error: %s", err.message ); continue; } dbus_message_unref( reply ); } /* we unreference the connection when we've finished with it */ dbus_connection_unref( conn ); exit( 0 ); } #undef MPRIS_APPEND #undef MPRIS_BUS_NAME #undef MPRIS_OBJECT_PATH #undef MPRIS_TRACKLIST_INTERFACE dbus_out: #endif // HAVE_DBUS vlc_CPU_dump( VLC_OBJECT(p_libvlc) ); priv->b_stats = var_InheritBool( p_libvlc, "stats" ); /* * Initialize hotkey handling */ priv->actions = vlc_InitActions( p_libvlc ); /* * Meta data handling */ priv->parser = playlist_preparser_New(VLC_OBJECT(p_libvlc)); /* Create a variable for showing the fullscreen interface */ var_Create( p_libvlc, "intf-toggle-fscontrol", VLC_VAR_BOOL ); var_SetBool( p_libvlc, "intf-toggle-fscontrol", true ); /* Create a variable for the Boss Key */ var_Create( p_libvlc, "intf-boss", VLC_VAR_VOID ); /* Create a variable for showing the main interface */ var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL ); /* Create a variable for showing the right click menu */ var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL ); /* variables for signalling creation of new files */ var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING ); var_Create( p_libvlc, "record-file", VLC_VAR_STRING ); /* some default internal settings */ var_Create( p_libvlc, "window", VLC_VAR_STRING ); /* NOTE: Because the playlist and interfaces start before this function * returns control to the application (DESIGN BUG!), all these variables * must be created (in place of libvlc_new()) and set to VLC defaults * (in place of VLC main()) *here*. */ var_Create( p_libvlc, "user-agent", VLC_VAR_STRING ); var_SetString( p_libvlc, "user-agent", "VLC media player (LibVLC "VERSION")" ); var_Create( p_libvlc, "http-user-agent", VLC_VAR_STRING ); var_SetString( p_libvlc, "http-user-agent", "VLC/"PACKAGE_VERSION" LibVLC/"PACKAGE_VERSION ); var_Create( p_libvlc, "app-icon-name", VLC_VAR_STRING ); var_SetString( p_libvlc, "app-icon-name", PACKAGE_NAME ); var_Create( p_libvlc, "app-id", VLC_VAR_STRING ); var_SetString( p_libvlc, "app-id", "org.VideoLAN.VLC" ); var_Create( p_libvlc, "app-version", VLC_VAR_STRING ); var_SetString( p_libvlc, "app-version", PACKAGE_VERSION ); /* System specific configuration */ system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind ); #ifdef ENABLE_VLM /* Initialize VLM if vlm-conf is specified */ psz_parser = var_CreateGetNonEmptyString( p_libvlc, "vlm-conf" ); if( psz_parser ) { priv->p_vlm = vlm_New( p_libvlc ); if( !priv->p_vlm ) msg_Err( p_libvlc, "VLM initialization failed" ); } free( psz_parser ); #endif /* * Load background interfaces */ psz_modules = var_CreateGetNonEmptyString( p_libvlc, "extraintf" ); psz_control = var_CreateGetNonEmptyString( p_libvlc, "control" ); if( psz_modules && psz_control ) { char* psz_tmp; if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 ) { free( psz_modules ); psz_modules = psz_tmp; } } else if( psz_control ) { free( psz_modules ); psz_modules = strdup( psz_control ); } psz_parser = psz_modules; while ( psz_parser && *psz_parser ) { char *psz_module, *psz_temp; psz_module = psz_parser; psz_parser = strchr( psz_module, ':' ); if ( psz_parser ) { *psz_parser = '\0'; psz_parser++; } if( asprintf( &psz_temp, "%s,none", psz_module ) != -1) { libvlc_InternalAddIntf( p_libvlc, psz_temp ); free( psz_temp ); } } free( psz_modules ); free( psz_control ); if( var_InheritBool( p_libvlc, "network-synchronisation") ) libvlc_InternalAddIntf( p_libvlc, "netsync,none" ); #ifdef __APPLE__ var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER ); var_Create( p_libvlc, "drawable-nsobject", VLC_VAR_ADDRESS ); #endif /* * Get input filenames given as commandline arguments. * We assume that the remaining parameters are filenames * and their input options. */ GetFilenames( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind ); /* * Get --open argument */ psz_val = var_InheritString( p_libvlc, "open" ); if ( psz_val != NULL ) { intf_InsertItem( p_libvlc, psz_val, 0, NULL, 0 ); free( psz_val ); } return VLC_SUCCESS; }
uint32_t samples; decklink_sys->p_output->GetBufferedAudioSampleFrameCount(&samples); msleep(CLOCK_FREQ * samples / decklink_sys->i_rate); } else if (decklink_sys->p_output->FlushBufferedAudioSamples() == E_FAIL) msg_Err(aout, "Flush failed"); } static int TimeGet(audio_output_t *, mtime_t* restrict) { /* synchronization is handled by the card */ return -1; } static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt) { struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(aout)); if (decklink_sys->i_rate == 0) return VLC_EGENERIC; fmt->i_format = VLC_CODEC_S16N; fmt->i_channels = 2; //decklink_sys->i_channels; fmt->i_physical_channels = AOUT_CHANS_STEREO; //pi_channels_maps[fmt->i_channels]; fmt->i_rate = decklink_sys->i_rate; fmt->i_bitspersample = 16; fmt->i_blockalign = fmt->i_channels * fmt->i_bitspersample /8 ; fmt->i_frame_length = FRAME_SIZE; return VLC_SUCCESS; }
/** * Creates an audio output object and initializes an output module. */ audio_output_t *aout_New (vlc_object_t *parent) { vlc_value_t val, text; audio_output_t *aout = vlc_custom_create (parent, sizeof (aout_instance_t), "audio output"); if (unlikely(aout == NULL)) return NULL; aout_owner_t *owner = aout_owner (aout); vlc_mutex_init (&owner->lock); vlc_mutex_init (&owner->req.lock); vlc_mutex_init (&owner->dev.lock); owner->req.device = (char *)unset_str; owner->req.volume = -1.f; owner->req.mute = -1; vlc_object_set_destructor (aout, aout_Destructor); /* Audio output module callbacks */ var_Create (aout, "volume", VLC_VAR_FLOAT); var_AddCallback (aout, "volume", var_Copy, parent); var_Create (aout, "mute", VLC_VAR_BOOL | VLC_VAR_DOINHERIT); var_AddCallback (aout, "mute", var_Copy, parent); var_Create (aout, "device", VLC_VAR_STRING); aout->event.volume_report = aout_VolumeNotify; aout->event.mute_report = aout_MuteNotify; aout->event.policy_report = aout_PolicyNotify; aout->event.device_report = aout_DeviceNotify; aout->event.hotplug_report = aout_HotplugNotify; aout->event.gain_request = aout_GainNotify; aout->event.restart_request = aout_RestartNotify; /* Audio output module initialization */ aout->start = NULL; aout->stop = NULL; aout->volume_set = NULL; aout->mute_set = NULL; aout->device_select = NULL; owner->module = module_need (aout, "audio output", "$aout", false); if (owner->module == NULL) { msg_Err (aout, "no suitable audio output module"); vlc_object_release (aout); return NULL; } /* * Persistent audio output variables */ module_config_t *cfg; char *str; /* Visualizations */ var_Create (aout, "visual", VLC_VAR_STRING | VLC_VAR_HASCHOICE); text.psz_string = _("Visualizations"); var_Change (aout, "visual", VLC_VAR_SETTEXT, &text, NULL); val.psz_string = (char *)""; text.psz_string = _("Disable"); var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); val.psz_string = (char *)"spectrometer"; text.psz_string = _("Spectrometer"); var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); val.psz_string = (char *)"scope"; text.psz_string = _("Scope"); var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); val.psz_string = (char *)"spectrum"; text.psz_string = _("Spectrum"); var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); val.psz_string = (char *)"vuMeter"; text.psz_string = _("Vu meter"); var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); /* Look for goom plugin */ if (module_exists ("goom")) { val.psz_string = (char *)"goom"; text.psz_string = (char *)"Goom"; var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); } /* Look for libprojectM plugin */ if (module_exists ("projectm")) { val.psz_string = (char *)"projectm"; text.psz_string = (char*)"projectM"; var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); } /* Look for VSXu plugin */ if (module_exists ("vsxu")) { val.psz_string = (char *)"vsxu"; text.psz_string = (char*)"Vovoid VSXu"; var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); } /* Look for glspectrum plugin */ if (module_exists ("glspectrum")) { val.psz_string = (char *)"glspectrum"; text.psz_string = (char*)"3D spectrum"; var_Change (aout, "visual", VLC_VAR_ADDCHOICE, &val, &text); } str = var_GetNonEmptyString (aout, "effect-list"); if (str != NULL) { var_SetString (aout, "visual", str); free (str); } /* Equalizer */ var_Create (aout, "equalizer", VLC_VAR_STRING | VLC_VAR_HASCHOICE); text.psz_string = _("Equalizer"); var_Change (aout, "equalizer", VLC_VAR_SETTEXT, &text, NULL); val.psz_string = (char*)""; text.psz_string = _("Disable"); var_Change (aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text); cfg = config_FindConfig (VLC_OBJECT(aout), "equalizer-preset"); if (likely(cfg != NULL)) for (unsigned i = 0; i < cfg->list_count; i++) { val.psz_string = cfg->list.psz[i]; text.psz_string = vlc_gettext(cfg->list_text[i]); var_Change (aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text); } var_Create (aout, "audio-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT); text.psz_string = _("Audio filters"); var_Change (aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL); var_Create (aout, "audio-visual", VLC_VAR_STRING | VLC_VAR_DOINHERIT); text.psz_string = _("Audio visualizations"); var_Change (aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL); /* Replay gain */ var_Create (aout, "audio-replay-gain-mode", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Replay gain"); var_Change (aout, "audio-replay-gain-mode", VLC_VAR_SETTEXT, &text, NULL); cfg = config_FindConfig (VLC_OBJECT(aout), "audio-replay-gain-mode"); if (likely(cfg != NULL)) for (unsigned i = 0; i < cfg->list_count; i++) { val.psz_string = cfg->list.psz[i]; text.psz_string = vlc_gettext(cfg->list_text[i]); var_Change (aout, "audio-replay-gain-mode", VLC_VAR_ADDCHOICE, &val, &text); } var_Create (aout, "equalizer-preamp", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT); var_Create (aout, "equalizer-bands", VLC_VAR_STRING | VLC_VAR_DOINHERIT); return aout; }
static struct decklink_sys_t *OpenDecklink(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; #define CHECK(message) do { \ if (result != S_OK) \ { \ msg_Err(vd, message ": 0x%X", result); \ goto error; \ } \ } while(0) HRESULT result; IDeckLinkIterator *decklink_iterator = NULL; IDeckLinkDisplayMode *p_display_mode = NULL; IDeckLinkDisplayModeIterator *p_display_iterator = NULL; IDeckLinkConfiguration *p_config = NULL; IDeckLink *p_card = NULL; struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(vd)); vlc_mutex_lock(&decklink_sys->lock); decklink_sys->users++; /* wait until aout is ready */ while (decklink_sys->i_rate == -1) vlc_cond_wait(&decklink_sys->cond, &decklink_sys->lock); int i_card_index = var_InheritInteger(vd, CFG_PREFIX "card-index"); BMDVideoConnection vconn = getVConn(vd); char *mode = var_InheritString(vd, VIDEO_CFG_PREFIX "mode"); size_t len = mode ? strlen(mode) : 0; if (!mode || len > 4) { free(mode); msg_Err(vd, "Missing or invalid mode"); goto error; } BMDDisplayMode wanted_mode_id; memset(&wanted_mode_id, ' ', 4); strncpy((char*)&wanted_mode_id, mode, 4); free(mode); if (i_card_index < 0) { msg_Err(vd, "Invalid card index %d", i_card_index); goto error; } decklink_iterator = CreateDeckLinkIteratorInstance(); if (!decklink_iterator) { msg_Err(vd, "DeckLink drivers not found."); goto error; } for(int i = 0; i <= i_card_index; ++i) { if (p_card) p_card->Release(); result = decklink_iterator->Next(&p_card); CHECK("Card not found"); } const char *psz_model_name; result = p_card->GetModelName(&psz_model_name); CHECK("Unknown model name"); msg_Dbg(vd, "Opened DeckLink PCI card %s", psz_model_name); result = p_card->QueryInterface(IID_IDeckLinkOutput, (void**)&decklink_sys->p_output); CHECK("No outputs"); result = p_card->QueryInterface(IID_IDeckLinkConfiguration, (void**)&p_config); CHECK("Could not get config interface"); if (vconn) { result = p_config->SetInt( bmdDeckLinkConfigVideoOutputConnection, vconn); CHECK("Could not set video output connection"); } result = decklink_sys->p_output->GetDisplayModeIterator(&p_display_iterator); CHECK("Could not enumerate display modes"); for (; ; p_display_mode->Release()) { int w, h; result = p_display_iterator->Next(&p_display_mode); if (result != S_OK) break; BMDDisplayMode mode_id = ntohl(p_display_mode->GetDisplayMode()); const char *psz_mode_name; result = p_display_mode->GetName(&psz_mode_name); CHECK("Could not get display mode name"); result = p_display_mode->GetFrameRate(&decklink_sys->frameduration, &decklink_sys->timescale); CHECK("Could not get frame rate"); w = p_display_mode->GetWidth(); h = p_display_mode->GetHeight(); msg_Dbg(vd, "Found mode '%4.4s': %s (%dx%d, %.3f fps)", (char*)&mode_id, psz_mode_name, w, h, double(decklink_sys->timescale) / decklink_sys->frameduration); msg_Dbg(vd, "scale %d dur %d", (int)decklink_sys->timescale, (int)decklink_sys->frameduration); if (wanted_mode_id != mode_id) continue; decklink_sys->i_width = w; decklink_sys->i_height = h; mode_id = htonl(mode_id); BMDVideoOutputFlags flags = bmdVideoOutputVANC; if (mode_id == bmdModeNTSC || mode_id == bmdModeNTSC2398 || mode_id == bmdModePAL) { flags = bmdVideoOutputVITC; } BMDDisplayModeSupport support; IDeckLinkDisplayMode *resultMode; result = decklink_sys->p_output->DoesSupportVideoMode(mode_id, sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV, flags, &support, &resultMode); CHECK("Does not support video mode"); if (support == bmdDisplayModeNotSupported) { msg_Err(vd, "Video mode not supported"); goto error; } result = decklink_sys->p_output->EnableVideoOutput(mode_id, flags); CHECK("Could not enable video output"); break; } if (decklink_sys->i_width < 0 || decklink_sys->i_width & 1) { msg_Err(vd, "Unknown video mode specified."); goto error; } if (/*decklink_sys->i_channels > 0 &&*/ decklink_sys->i_rate > 0) { result = decklink_sys->p_output->EnableAudioOutput( decklink_sys->i_rate, bmdAudioSampleType16bitInteger, /*decklink_sys->i_channels*/ 2, bmdAudioOutputStreamTimestamped); } CHECK("Could not start audio output"); /* start */ result = decklink_sys->p_output->StartScheduledPlayback( (mdate() * decklink_sys->timescale) / CLOCK_FREQ, decklink_sys->timescale, 1.0); CHECK("Could not start playback"); p_config->Release(); p_display_mode->Release(); p_display_iterator->Release(); p_card->Release(); decklink_iterator->Release(); vlc_mutex_unlock(&decklink_sys->lock); return decklink_sys; error: if (decklink_sys->p_output) { decklink_sys->p_output->Release(); decklink_sys->p_output = NULL; } if (p_card) p_card->Release(); if (p_config) p_config->Release(); if (p_display_iterator) p_display_iterator->Release(); if (decklink_iterator) decklink_iterator->Release(); if (p_display_mode) p_display_mode->Release(); vlc_mutex_unlock(&decklink_sys->lock); ReleaseDLSys(VLC_OBJECT(vd)); return NULL; #undef CHECK }
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 = malloc(sizeof(*sys)); if (!sys) return VLC_ENOMEM; sys->context = NULL; /* */ vlc_init_avformat(object); if (!access->psz_path) goto error; int ret; #if LIBAVFORMAT_VERSION_MAJOR < 54 ret = avio_open(&sys->context, access->psz_path, AVIO_FLAG_WRITE); #else AVIOInterruptCB cb = { .callback = UrlInterruptCallback, .opaque = access, }; AVDictionary *options = NULL; char *psz_opts = var_InheritString(access, "sout-avio-options"); if (psz_opts && *psz_opts) { options = vlc_av_get_options(psz_opts); free(psz_opts); } ret = avio_open2(&sys->context, access->psz_path, AVIO_FLAG_WRITE, &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); #endif if (ret < 0) { errno = AVUNERROR(ret); msg_Err(access, "Failed to open %s", access->psz_path); goto error; } #if LIBAVFORMAT_VERSION_MAJOR < 54 /* We can accept only one active user at any time */ if (SetupAvioCb(VLC_OBJECT(access))) { msg_Err(access, "Module aready in use"); goto error; } #endif access->pf_write = Write; access->pf_control = OutControl; access->pf_seek = OutSeek; access->p_sys = sys; return VLC_SUCCESS; error: free(sys); return VLC_EGENERIC; }
static void DisplayVideo(vout_display_t *vd, picture_t *picture, subpicture_t *) { vout_display_sys_t *sys = vd->sys; struct decklink_sys_t *decklink_sys = GetDLSys(VLC_OBJECT(vd)); mtime_t now = mdate(); if (!picture) return; picture_t *orig_picture = picture; if (now - picture->date > sys->nosignal_delay * CLOCK_FREQ) { msg_Dbg(vd, "no signal"); if (sys->pic_nosignal) { picture = sys->pic_nosignal; } else { if (sys->tenbits) { // I422_10L plane_t *y = &picture->p[0]; memset(y->p_pixels, 0x0, y->i_lines * y->i_pitch); for (int i = 1; i < picture->i_planes; i++) { plane_t *p = &picture->p[i]; size_t len = p->i_lines * p->i_pitch / 2; int16_t *data = (int16_t*)p->p_pixels; for (size_t j = 0; j < len; j++) // XXX: SIMD data[j] = 0x200; } } else { // UYVY size_t len = picture->p[0].i_lines * picture->p[0].i_pitch; for (size_t i = 0; i < len; i+= 2) { // XXX: SIMD picture->p[0].p_pixels[i+0] = 0x80; picture->p[0].p_pixels[i+1] = 0; } } } picture->date = now; } HRESULT result; int w, h, stride, length; w = decklink_sys->i_width; h = decklink_sys->i_height; IDeckLinkMutableVideoFrame *pDLVideoFrame; result = decklink_sys->p_output->CreateVideoFrame(w, h, w*3, sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV, bmdFrameFlagDefault, &pDLVideoFrame); if (result != S_OK) { msg_Err(vd, "Failed to create video frame: 0x%X", result); pDLVideoFrame = NULL; goto end; } void *frame_bytes; pDLVideoFrame->GetBytes((void**)&frame_bytes); stride = pDLVideoFrame->GetRowBytes(); if (sys->tenbits) v210_convert(frame_bytes, picture, stride); else for(int y = 0; y < h; ++y) { uint8_t *dst = (uint8_t *)frame_bytes + stride * y; const uint8_t *src = (const uint8_t *)picture->p[0].p_pixels + picture->p[0].i_pitch * y; memcpy(dst, src, w * 2 /* bpp */); } // compute frame duration in CLOCK_FREQ units length = (decklink_sys->frameduration * CLOCK_FREQ) / decklink_sys->timescale; picture->date -= decklink_sys->offset; result = decklink_sys->p_output->ScheduleVideoFrame(pDLVideoFrame, picture->date, length, CLOCK_FREQ); if (result != S_OK) { msg_Err(vd, "Dropped Video frame %"PRId64 ": 0x%x", picture->date, result); goto end; } now = mdate() - decklink_sys->offset; BMDTimeValue decklink_now; double speed; decklink_sys->p_output->GetScheduledStreamTime (CLOCK_FREQ, &decklink_now, &speed); if ((now - decklink_now) > 400000) { /* XXX: workaround card clock drift */ decklink_sys->offset += 50000; msg_Err(vd, "Delaying: offset now %"PRId64"", decklink_sys->offset); } end: if (pDLVideoFrame) pDLVideoFrame->Release(); picture_Release(orig_picture); }
static void DisplaySubpicture(vout_display_t *vd, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; struct md5_s hash; InitMD5(&hash); if (subpicture) { for (subpicture_region_t *r = subpicture->p_region; r != NULL; r = r->p_next) { AddMD5(&hash, &r->i_x, sizeof(r->i_x)); AddMD5(&hash, &r->i_y, sizeof(r->i_y)); AddMD5(&hash, &r->fmt.i_visible_width, sizeof(r->fmt.i_visible_width)); AddMD5(&hash, &r->fmt.i_visible_height, sizeof(r->fmt.i_visible_height)); AddMD5(&hash, &r->fmt.i_x_offset, sizeof(r->fmt.i_x_offset)); AddMD5(&hash, &r->fmt.i_y_offset, sizeof(r->fmt.i_y_offset)); const int pixels_offset = r->fmt.i_y_offset * r->p_picture->p->i_pitch + r->fmt.i_x_offset * r->p_picture->p->i_pixel_pitch; for (int y = 0; y < r->fmt.i_visible_height; y++) AddMD5(&hash, &r->p_picture->p->p_pixels[pixels_offset + y*r->p_picture->p->i_pitch], r->fmt.i_visible_width); } } EndMD5(&hash); if (!memcmp(hash.buf, sys->hash, 16)) return; memcpy(sys->hash, hash.buf, 16); jobject jsurf = jni_LockAndGetSubtitlesSurface(); if (sys->window && jsurf != sys->jsurf) { sys->native_window.winRelease(sys->window); sys->window = NULL; } sys->jsurf = jsurf; if (!sys->window) { JNIEnv *p_env; (*myVm)->AttachCurrentThread(myVm, &p_env, NULL); sys->window = sys->native_window.winFromSurface(p_env, jsurf); (*myVm)->DetachCurrentThread(myVm); } ANativeWindow_Buffer buf = { 0 }; sys->native_window.winLock(sys->window, &buf, NULL); if (buf.width >= sys->fmt.i_width && buf.height >= sys->fmt.i_height) { /* Wrap the NativeWindow corresponding to the subtitles surface in a picture_t */ picture_t *picture = sys->subtitles_picture; picture->p[0].p_pixels = (uint8_t*)buf.bits; picture->p[0].i_lines = buf.height; picture->p[0].i_pitch = picture->p[0].i_pixel_pitch * buf.stride; /* Clear the subtitles surface. */ memset(picture->p[0].p_pixels, 0, picture->p[0].i_pitch * picture->p[0].i_lines); if (subpicture) { /* Allocate a blending filter if needed. */ if (unlikely(!sys->p_spu_blend)) sys->p_spu_blend = filter_NewBlend(VLC_OBJECT(vd), &picture->format); picture_BlendSubpicture(picture, sys->p_spu_blend, subpicture); } } sys->native_window.unlockAndPost(sys->window); jni_UnlockAndroidSurface(); }
/***************************************************************************** * Open: open a scope effect plugin *****************************************************************************/ static int Open( vlc_object_t *p_this ) { aout_filter_t *p_filter = (aout_filter_t *)p_this; aout_filter_sys_t *p_sys; goom_thread_t *p_thread; vlc_value_t width, height; if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' ) || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') ) { msg_Warn( p_filter, "Bad input or output format" ); return VLC_EGENERIC; } if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) ) { msg_Warn( p_filter, "input and output formats are not similar" ); return VLC_EGENERIC; } p_filter->pf_do_work = DoWork; p_filter->b_in_place = 1; /* Allocate structure */ p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) ); /* Create goom thread */ p_sys->p_thread = p_thread = vlc_object_create( p_filter, sizeof( goom_thread_t ) ); vlc_object_attach( p_thread, p_this ); var_Create( p_thread, "goom-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "goom-width", &width ); var_Create( p_thread, "goom-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT ); var_Get( p_thread, "goom-height", &height ); p_thread->p_vout = vout_Request( p_filter, NULL, width.i_int, height.i_int, VLC_FOURCC('R','V','3','2'), VOUT_ASPECT_FACTOR * width.i_int/height.i_int ); if( p_thread->p_vout == NULL ) { msg_Err( p_filter, "no suitable vout module" ); vlc_object_detach( p_thread ); vlc_object_destroy( p_thread ); free( p_sys ); return VLC_EGENERIC; } vlc_mutex_init( p_filter, &p_thread->lock ); vlc_cond_init( p_filter, &p_thread->wait ); p_thread->i_blocks = 0; aout_DateInit( &p_thread->date, p_filter->output.i_rate ); aout_DateSet( &p_thread->date, 0 ); p_thread->i_channels = aout_FormatNbChannels( &p_filter->input ); p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) ); if( vlc_thread_create( p_thread, "Goom Update Thread", Thread, VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) { msg_Err( p_filter, "cannot lauch goom thread" ); vout_Destroy( p_thread->p_vout ); vlc_mutex_destroy( &p_thread->lock ); vlc_cond_destroy( &p_thread->wait ); if( p_thread->psz_title ) free( p_thread->psz_title ); vlc_object_detach( p_thread ); vlc_object_destroy( p_thread ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * aout_InputNew : allocate a new input and rework the filter pipeline *****************************************************************************/ int aout_InputNew( aout_instance_t * p_aout, aout_input_t * p_input ) { audio_sample_format_t chain_input_format; audio_sample_format_t chain_output_format; vlc_value_t val, text; char * psz_filters, *psz_visual; int i_visual; aout_FormatPrint( p_aout, "input", &p_input->input ); p_input->i_nb_filters = 0; /* Prepare FIFO. */ aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate ); p_input->p_first_byte_to_mix = NULL; /* Prepare format structure */ memcpy( &chain_input_format, &p_input->input, sizeof(audio_sample_format_t) ); memcpy( &chain_output_format, &p_aout->mixer.mixer, sizeof(audio_sample_format_t) ); chain_output_format.i_rate = p_input->input.i_rate; aout_FormatPrepare( &chain_output_format ); /* Now add user filters */ if( var_Type( p_aout, "visual" ) == 0 ) { module_t *p_module; var_Create( p_aout, "visual", VLC_VAR_STRING | VLC_VAR_HASCHOICE ); text.psz_string = _("Visualizations"); var_Change( p_aout, "visual", VLC_VAR_SETTEXT, &text, NULL ); val.psz_string = ""; text.psz_string = _("Disable"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = "spectrometer"; text.psz_string = _("Spectrometer"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = "scope"; text.psz_string = _("Scope"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = "spectrum"; text.psz_string = _("Spectrum"); var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); /* Look for goom plugin */ p_module = config_FindModule( VLC_OBJECT(p_aout), "goom" ); if( p_module ) { val.psz_string = "goom"; text.psz_string = "Goom"; var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); } /* Look for galaktos plugin */ p_module = config_FindModule( VLC_OBJECT(p_aout), "galaktos" ); if( p_module ) { val.psz_string = "galaktos"; text.psz_string = "GaLaktos"; var_Change( p_aout, "visual", VLC_VAR_ADDCHOICE, &val, &text ); } if( var_Get( p_aout, "effect-list", &val ) == VLC_SUCCESS ) { var_Set( p_aout, "visual", val ); if( val.psz_string ) free( val.psz_string ); } var_AddCallback( p_aout, "visual", VisualizationCallback, NULL ); } if( var_Type( p_aout, "equalizer" ) == 0 ) { module_config_t *p_config; int i; p_config = config_FindConfig( VLC_OBJECT(p_aout), "equalizer-preset" ); if( p_config && p_config->i_list ) { var_Create( p_aout, "equalizer", VLC_VAR_STRING | VLC_VAR_HASCHOICE ); text.psz_string = _("Equalizer"); var_Change( p_aout, "equalizer", VLC_VAR_SETTEXT, &text, NULL ); val.psz_string = ""; text.psz_string = _("Disable"); var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text ); for( i = 0; i < p_config->i_list; i++ ) { val.psz_string = p_config->ppsz_list[i]; text.psz_string = p_config->ppsz_list_text[i]; var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text ); } var_AddCallback( p_aout, "equalizer", EqualizerCallback, NULL ); } } if( var_Type( p_aout, "audio-filter" ) == 0 ) { var_Create( p_aout, "audio-filter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Audio filters"); var_Change( p_aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL ); } if( var_Type( p_aout, "audio-visual" ) == 0 ) { var_Create( p_aout, "audio-visual", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); text.psz_string = _("Audio visualizations"); var_Change( p_aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL ); } var_Get( p_aout, "audio-filter", &val ); psz_filters = val.psz_string; var_Get( p_aout, "audio-visual", &val ); psz_visual = val.psz_string; /* parse user filter lists */ for( i_visual = 0; i_visual < 2; i_visual++ ) { char *psz_next = NULL; char *psz_parser = i_visual ? psz_visual : psz_filters; if( psz_parser == NULL || !*psz_parser ) continue; while( psz_parser && *psz_parser ) { aout_filter_t * p_filter = NULL; if( p_input->i_nb_filters >= AOUT_MAX_FILTERS ) { msg_Dbg( p_aout, "max filters reached (%d)", AOUT_MAX_FILTERS ); break; } while( *psz_parser == ' ' && *psz_parser == ':' ) { psz_parser++; } if( ( psz_next = strchr( psz_parser , ':' ) ) ) { *psz_next++ = '\0'; } if( *psz_parser =='\0' ) { break; } /* Create a VLC object */ p_filter = vlc_object_create( p_aout, sizeof(aout_filter_t) ); if( p_filter == NULL ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); psz_parser = psz_next; continue; } vlc_object_attach( p_filter , p_aout ); /* try to find the requested filter */ if( i_visual == 1 ) /* this can only be a visualization module */ { /* request format */ memcpy( &p_filter->input, &chain_output_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->output, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_Need( p_filter, "visualization", psz_parser, VLC_TRUE ); } else /* this can be a audio filter module as well as a visualization module */ { /* request format */ memcpy( &p_filter->input, &chain_input_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->output, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_Need( p_filter, "audio filter", psz_parser, VLC_TRUE ); if ( p_filter->p_module == NULL ) { /* if the filter requested a special format, retry */ if ( !( AOUT_FMTS_IDENTICAL( &p_filter->input, &chain_input_format ) && AOUT_FMTS_IDENTICAL( &p_filter->output, &chain_output_format ) ) ) { aout_FormatPrepare( &p_filter->input ); aout_FormatPrepare( &p_filter->output ); p_filter->p_module = module_Need( p_filter, "audio filter", psz_parser, VLC_TRUE ); } /* try visual filters */ else { memcpy( &p_filter->input, &chain_output_format, sizeof(audio_sample_format_t) ); memcpy( &p_filter->output, &chain_output_format, sizeof(audio_sample_format_t) ); p_filter->p_module = module_Need( p_filter, "visualization", psz_parser, VLC_TRUE ); } } } /* failure */ if ( p_filter->p_module == NULL ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); vlc_object_detach( p_filter ); vlc_object_destroy( p_filter ); psz_parser = psz_next; continue; } /* complete the filter chain if necessary */ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &p_filter->input ) ) { if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, &p_input->i_nb_filters, &chain_input_format, &p_filter->input ) < 0 ) { msg_Err( p_aout, "cannot add user filter %s (skipped)", psz_parser ); module_Unneed( p_filter, p_filter->p_module ); vlc_object_detach( p_filter ); vlc_object_destroy( p_filter ); psz_parser = psz_next; continue; } } /* success */ p_filter->b_continuity = VLC_FALSE; p_input->pp_filters[p_input->i_nb_filters++] = p_filter; memcpy( &chain_input_format, &p_filter->output, sizeof( audio_sample_format_t ) ); /* next filter if any */ psz_parser = psz_next; } } if( psz_filters ) free( psz_filters ); if( psz_visual ) free( psz_visual ); /* complete the filter chain if necessary */ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &chain_output_format ) ) { if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters, &p_input->i_nb_filters, &chain_input_format, &chain_output_format ) < 0 ) { inputFailure( p_aout, p_input, "couldn't set an input pipeline" ); return -1; } } /* Prepare hints for the buffer allocator. */ p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP; p_input->input_alloc.i_bytes_per_sec = -1; /* Create resamplers. */ if ( AOUT_FMT_NON_LINEAR( &p_aout->mixer.mixer ) ) { p_input->i_nb_resamplers = 0; } else { chain_output_format.i_rate = (__MAX(p_input->input.i_rate, p_aout->mixer.mixer.i_rate) * (100 + AOUT_MAX_RESAMPLING)) / 100; if ( chain_output_format.i_rate == p_aout->mixer.mixer.i_rate ) { /* Just in case... */ chain_output_format.i_rate++; } p_input->i_nb_resamplers = 0; if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_resamplers, &p_input->i_nb_resamplers, &chain_output_format, &p_aout->mixer.mixer ) < 0 ) { inputFailure( p_aout, p_input, "couldn't set a resampler pipeline"); return -1; } aout_FiltersHintBuffers( p_aout, p_input->pp_resamplers, p_input->i_nb_resamplers, &p_input->input_alloc ); p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP; /* Setup the initial rate of the resampler */ p_input->pp_resamplers[0]->input.i_rate = p_input->input.i_rate; } p_input->i_resampling_type = AOUT_RESAMPLING_NONE; aout_FiltersHintBuffers( p_aout, p_input->pp_filters, p_input->i_nb_filters, &p_input->input_alloc ); p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP; /* i_bytes_per_sec is still == -1 if no filters */ p_input->input_alloc.i_bytes_per_sec = __MAX( p_input->input_alloc.i_bytes_per_sec, (int)(p_input->input.i_bytes_per_frame * p_input->input.i_rate / p_input->input.i_frame_length) ); /* Success */ p_input->b_error = VLC_FALSE; p_input->b_restart = VLC_FALSE; return 0; }
/** * Find the drawable set by libvlc application. */ static int Open (vlc_object_t *obj, const char *varname, bool ptr) { vout_window_t *wnd = (vout_window_t *)obj; void **used, *val; size_t n = 0; if (var_Create (obj->p_libvlc, "drawables-in-use", VLC_VAR_ADDRESS) || var_Create (obj, varname, VLC_VAR_DOINHERIT | (ptr ? VLC_VAR_ADDRESS : VLC_VAR_INTEGER))) return VLC_ENOMEM; if (ptr) val = var_GetAddress (obj, varname); else val = (void *)(uintptr_t)var_GetInteger (obj, varname); var_Destroy (obj, varname); /* Keep a list of busy drawables, so we don't overlap videos if there are * more than one video track in the stream. */ vlc_mutex_lock (&serializer); /* TODO: per-type list of busy drawables */ used = var_GetAddress (VLC_OBJECT (obj->p_libvlc), "drawables-in-use"); if (used != NULL) { while (used[n] != NULL) { if (used[n] == val) goto skip; n++; } } used = realloc (used, sizeof (*used) * (n + 2)); if (used != NULL) { used[n] = val; used[n + 1] = NULL; var_SetAddress (obj->p_libvlc, "drawables-in-use", used); } else { skip: msg_Warn (wnd, "drawable %p is busy", val); val = NULL; } vlc_mutex_unlock (&serializer); if (val == NULL) return VLC_EGENERIC; if (ptr) wnd->handle.hwnd = val; else wnd->handle.xid = (uintptr_t)val; /* FIXME: check that X server matches --x11-display (if specified) */ /* FIXME: get window size (in platform-dependent ways) */ wnd->control = Control; wnd->p_sys = val; return VLC_SUCCESS; }
static int Open (vlc_object_t *p_this) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; if (p_enc->fmt_out.i_codec != VLC_CODEC_HEVC && !p_enc->b_force) return VLC_EGENERIC; p_enc->fmt_out.i_cat = VIDEO_ES; p_enc->fmt_out.i_codec = VLC_CODEC_HEVC; p_enc->p_sys = p_sys = malloc(sizeof(encoder_sys_t)); if (!p_sys) return VLC_ENOMEM; p_enc->fmt_in.i_codec = VLC_CODEC_I420; x265_param *param = &p_sys->param; x265_param_default(param); param->frameNumThreads = vlc_GetCPUCount(); param->bEnableWavefront = 0; // buggy in x265, use frame threading for now param->maxCUSize = 16; /* use smaller macroblock */ param->frameRate = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base; param->sourceWidth = p_enc->fmt_in.video.i_visible_width; param->sourceHeight = p_enc->fmt_in.video.i_visible_height; if (param->sourceWidth & (param->maxCUSize - 1)) { msg_Err(p_enc, "Width (%d) must be a multiple of %d", param->sourceWidth, param->maxCUSize); free(p_sys); return VLC_EGENERIC; } if (param->sourceHeight & 7) { msg_Err(p_enc, "Height (%d) must be a multiple of 8", param->sourceHeight); free(p_sys); return VLC_EGENERIC; } if (p_enc->fmt_out.i_bitrate > 0) { param->rc.bitrate = p_enc->fmt_out.i_bitrate / 1000; param->rc.rateControlMode = X265_RC_ABR; } p_sys->h = x265_encoder_open(param); if (p_sys->h == NULL) { msg_Err(p_enc, "cannot open x265 encoder"); free(p_sys); return VLC_EGENERIC; } x265_nal *nal; uint32_t i_nal; if (x265_encoder_headers(p_sys->h, &nal, &i_nal)) { msg_Err(p_enc, "cannot get x265 headers"); Close(VLC_OBJECT(p_enc)); return VLC_EGENERIC; } size_t i_extra = 0; for (uint32_t i = 0; i < i_nal; i++) i_extra += nal[i].sizeBytes; p_enc->fmt_out.i_extra = i_extra; uint8_t *p_extra = p_enc->fmt_out.p_extra = malloc(i_extra); if (!p_extra) { Close(VLC_OBJECT(p_enc)); return VLC_ENOMEM; } for (uint32_t i = 0; i < i_nal; i++) { memcpy(p_extra, nal[i].payload, nal[i].sizeBytes); p_extra += nal[i].sizeBytes; } p_sys->dts = 0; p_sys->initial_date = 0; p_sys->i_initial_delay = 0; p_sys->write_headers = true; p_enc->pf_encode_video = Encode; p_enc->pf_encode_audio = NULL; return VLC_SUCCESS; }
/***************************************************************************** * StartMediaCodec: Create the mediacodec instance *****************************************************************************/ static int StartMediaCodec(decoder_t *p_dec) { decoder_sys_t *p_sys = p_dec->p_sys; int i_ret = 0; union mc_api_args args; if (p_dec->fmt_in.i_extra && !p_sys->p_csd) { /* Try first to configure specific Video CSD */ if (p_dec->fmt_in.i_cat == VIDEO_ES) i_ret = ParseVideoExtra(p_dec, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra); if (i_ret != VLC_SUCCESS) return i_ret; /* Set default CSD if ParseVideoExtra failed to configure one */ if (!p_sys->p_csd) { struct csd csd; csd.p_buf = p_dec->fmt_in.p_extra; csd.i_size = p_dec->fmt_in.i_extra; CSDDup(p_dec, &csd, 1); } p_sys->i_csd_send = 0; } if (p_dec->fmt_in.i_cat == VIDEO_ES) { if (!p_sys->u.video.i_width || !p_sys->u.video.i_height) { msg_Err(p_dec, "invalid size, abort MediaCodec"); return VLC_EGENERIC; } args.video.i_width = p_sys->u.video.i_width; args.video.i_height = p_sys->u.video.i_height; switch (p_dec->fmt_in.video.orientation) { case ORIENT_ROTATED_90: args.video.i_angle = 90; break; case ORIENT_ROTATED_180: args.video.i_angle = 180; break; case ORIENT_ROTATED_270: args.video.i_angle = 270; break; default: args.video.i_angle = 0; } /* Check again the codec name if h264 profile changed */ if (p_dec->fmt_in.i_codec == VLC_CODEC_H264 && !p_sys->u.video.i_h264_profile) { h264_get_profile_level(&p_dec->fmt_in, &p_sys->u.video.i_h264_profile, NULL, NULL); if (p_sys->u.video.i_h264_profile) { free(p_sys->psz_name); p_sys->psz_name = MediaCodec_GetName(VLC_OBJECT(p_dec), p_sys->mime, p_sys->u.video.i_h264_profile); if (!p_sys->psz_name) return VLC_EGENERIC; } } if (!p_sys->u.video.p_awh && var_InheritBool(p_dec, CFG_PREFIX "dr")) p_sys->u.video.p_awh = AWindowHandler_new(VLC_OBJECT(p_dec)); args.video.p_awh = p_sys->u.video.p_awh; } else { date_Set(&p_sys->u.audio.i_end_date, VLC_TS_INVALID); args.audio.i_sample_rate = p_dec->fmt_in.audio.i_rate; args.audio.i_channel_count = p_dec->p_sys->u.audio.i_channels; } i_ret = p_sys->api->start(p_sys->api, p_sys->psz_name, p_sys->mime, &args); if (i_ret == VLC_SUCCESS) { if (p_sys->api->b_direct_rendering) p_dec->fmt_out.i_codec = VLC_CODEC_ANDROID_OPAQUE; p_sys->b_update_format = true; return VLC_SUCCESS; } else return VLC_EGENERIC; }