/***************************************************************************** * Control input stream *****************************************************************************/ static int Control( access_t *p_access, int i_query, va_list args ) { access_sys_t *p_sys = p_access->p_sys; input_title_t ***ppp_title; int i; int64_t *pi64; vlc_meta_t *p_meta; switch( i_query ) { case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_PAUSE: case ACCESS_CAN_CONTROL_PACE: *va_arg( args, bool* ) = true; break; case ACCESS_GET_PTS_DELAY: pi64 = va_arg( args, int64_t * ); *pi64 = INT64_C(1000) * var_InheritInteger( p_access, "file-caching" ); break; case ACCESS_SET_PAUSE_STATE: /* nothing to do */ break; case ACCESS_GET_TITLE_INFO: /* return a copy of our seek points */ if( !p_sys->p_marks ) return VLC_EGENERIC; ppp_title = va_arg( args, input_title_t*** ); *va_arg( args, int* ) = 1; *ppp_title = malloc( sizeof( input_title_t** ) ); if( !*ppp_title ) return VLC_ENOMEM; **ppp_title = vlc_input_title_Duplicate( p_sys->p_marks ); break; case ACCESS_SET_TITLE: /* ignore - only one title */ break; case ACCESS_SET_SEEKPOINT: i = va_arg( args, int ); /* Seek updates p_access->info */ return Seek( p_access, p_sys->p_marks->seekpoint[i]->i_byte_offset ); case ACCESS_GET_META: if( !p_sys->p_meta ) return VLC_EGENERIC; p_meta = va_arg( args, vlc_meta_t* ); vlc_meta_Merge( p_meta, p_sys->p_meta ); break; case ACCESS_SET_PRIVATE_ID_STATE: case ACCESS_GET_CONTENT_TYPE: return VLC_EGENERIC; default: msg_Warn( p_access, "unimplemented query in control" ); return VLC_EGENERIC; } return VLC_SUCCESS; }
static int spectrometer_Run(visual_effect_t * p_effect, vlc_object_t *p_aout, const block_t * p_buffer , picture_t * p_picture) { #define Y(R,G,B) ((uint8_t)( (R * .299) + (G * .587) + (B * .114) )) #define U(R,G,B) ((uint8_t)( (R * -.169) + (G * -.332) + (B * .500) + 128 )) #define V(R,G,B) ((uint8_t)( (R * .500) + (G * -.419) + (B * -.0813) + 128 )) float p_output[FFT_BUFFER_SIZE]; /* Raw FFT Result */ int *height; /* Bar heights */ int *peaks; /* Peaks */ int i_80_bands; /* number of bands : 80 if true else 20 */ int i_nb_bands; /* number of bands : 80 or 20 */ int i_band_width; /* width of bands */ int i_separ; /* Should we let blanks ? */ int i_amp; /* Vertical amplification */ int i_peak; /* Should we draw peaks ? */ int i_original; /* original spectrum graphic routine */ int i_rad; /* radius of circle of base of bands */ int i_sections; /* sections of spectranalysis */ int i_extra_width; /* extra width on peak */ int i_peak_height; /* height of peak */ int c; /* sentinel container of total spectral sections */ double band_sep_angle; /* angled separation between beginning of each band */ double section_sep_angle;/* " " ' " ' " " spectrum section */ int max_band_length; /* try not to go out of screen */ int i_show_base; /* Should we draw base of circle ? */ int i_show_bands; /* Should we draw bands ? */ //int i_invert_bands; /* do the bands point inward ? */ double a; /* for various misc angle situations in radians */ int x,y,xx,yy; /* various misc x/y */ char color1; /* V slide on a YUV color cube */ //char color2; /* U slide.. ? color2 fade color ? */ /* Horizontal scale for 20-band equalizer */ const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27, 36,47,62,82,107,141,184,255}; /* Horizontal scale for 80-band equalizer */ const int xscale2[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51, 52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105, 110,115,121,130,141,152,163,174,185,200,255}; const int *xscale; const double y_scale = 3.60673760222; /* (log 256) */ fft_state *p_state; /* internal FFT data */ int i , j , k; int i_line = 0; int16_t p_dest[FFT_BUFFER_SIZE]; /* Adapted FFT result */ int16_t p_buffer1[FFT_BUFFER_SIZE]; /* Buffer on which we perform the FFT (first channel) */ float *p_buffl = /* Original buffer */ (float*)p_buffer->p_buffer; int16_t *p_buffs; /* int16_t converted buffer */ int16_t *p_s16_buff; /* int16_t converted buffer */ /* Create the data struct if needed */ spectrometer_data *p_data = p_effect->p_data; if( !p_data ) { p_data = malloc( sizeof(spectrometer_data) ); if( !p_data ) return -1; p_data->peaks = calloc( 80, sizeof(int) ); if( !p_data->peaks ) { free( p_data ); return -1; } p_data->i_prev_nb_samples = 0; p_data->p_prev_s16_buff = NULL; p_effect->p_data = (void*)p_data; } peaks = p_data->peaks; /* Allocate the buffer only if the number of samples change */ if( p_buffer->i_nb_samples != p_data->i_prev_nb_samples ) { free( p_data->p_prev_s16_buff ); p_data->p_prev_s16_buff = malloc( p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t)); p_data->i_prev_nb_samples = p_buffer->i_nb_samples; if( !p_data->p_prev_s16_buff ) return -1; } p_buffs = p_s16_buff = p_data->p_prev_s16_buff; i_original = var_InheritInteger( p_aout, "spect-show-original" ); i_80_bands = var_InheritInteger( p_aout, "spect-80-bands" ); i_separ = var_InheritInteger( p_aout, "spect-separ" ); i_amp = var_InheritInteger( p_aout, "spect-amp" ); i_peak = var_InheritInteger( p_aout, "spect-show-peaks" ); i_show_base = var_InheritInteger( p_aout, "spect-show-base" ); i_show_bands = var_InheritInteger( p_aout, "spect-show-bands" ); i_rad = var_InheritInteger( p_aout, "spect-radius" ); i_sections = var_InheritInteger( p_aout, "spect-sections" ); i_extra_width = var_InheritInteger( p_aout, "spect-peak-width" ); i_peak_height = var_InheritInteger( p_aout, "spect-peak-height" ); color1 = var_InheritInteger( p_aout, "spect-color" ); if( i_80_bands != 0) { xscale = xscale2; i_nb_bands = 80; } else { xscale = xscale1; i_nb_bands = 20; } height = malloc( i_nb_bands * sizeof(int) ); if( !height) return -1; /* Convert the buffer to int16_t */ /* Pasted from float32tos16.c */ for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; ) { union { float f; int32_t i; } u; u.f = *p_buffl + 384.0; if(u.i > 0x43c07fff ) * p_buffs = 32767; else if ( u.i < 0x43bf8000 ) *p_buffs = -32768; else *p_buffs = u.i - 0x43c00000; p_buffl++ ; p_buffs++ ; } p_state = visual_fft_init(); if( !p_state) { msg_Err(p_aout,"unable to initialize FFT transform"); free( height ); return -1; } p_buffs = p_s16_buff; for ( i = 0 ; i < FFT_BUFFER_SIZE; i++) { p_output[i] = 0; p_buffer1[i] = *p_buffs; p_buffs += p_effect->i_nb_chans; if( p_buffs >= &p_s16_buff[p_buffer->i_nb_samples * p_effect->i_nb_chans] ) p_buffs = p_s16_buff; } fft_perform( p_buffer1, p_output, p_state); for(i = 0; i < FFT_BUFFER_SIZE; i++) { int sqrti = sqrt(p_output[i]); p_dest[i] = sqrti >> 8; } i_nb_bands *= i_sections; for ( i = 0 ; i< i_nb_bands/i_sections ;i++) { /* We search the maximum on one scale */ for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ ) { if ( p_dest[j] > y ) y = p_dest[j]; } /* Calculate the height of the bar */ y >>=7;/* remove some noise */ if( y != 0) { int logy = log(y); height[i] = logy * y_scale; if(height[i] > 150) height[i] = 150; } else { height[i] = 0 ; } /* Draw the bar now */ i_band_width = floor( p_effect->i_width / (i_nb_bands/i_sections)) ; if( i_amp * height[i] > peaks[i]) { peaks[i] = i_amp * height[i]; } else if (peaks[i] > 0 ) { peaks[i] -= PEAK_SPEED; if( peaks[i] < i_amp * height[i] ) { peaks[i] = i_amp * height[i]; } if( peaks[i] < 0 ) { peaks[i] = 0; } } if( i_original != 0 ) { if( peaks[i] > 0 && i_peak ) { if( peaks[i] >= p_effect->i_height ) peaks[i] = p_effect->i_height - 2; i_line = peaks[i]; for( j = 0 ; j< i_band_width - i_separ; j++) { for( k = 0 ; k< 3 ; k ++) { //* Draw the peak *(p_picture->p[0].p_pixels + (p_effect->i_height - i_line -1 -k ) * p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff; *(p_picture->p[1].p_pixels + ( ( p_effect->i_height - i_line ) / 2 -1 -k/2 ) * p_picture->p[1].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0x00; if( 0x04 * (i_line + k ) - 0x0f > 0 ) { if ( 0x04 * (i_line + k ) -0x0f < 0xff) *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = ( 0x04 * ( i_line + k ) ) -0x0f ; else *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0xff; } else { *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0x10 ; } } } } if(height[i] * i_amp > p_effect->i_height) height[i] = floor(p_effect->i_height / i_amp ); for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ ) { for( j = 0 ; j< i_band_width - i_separ ; j++) { *(p_picture->p[0].p_pixels + (p_effect->i_height - i_line -1) * p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff; *(p_picture->p[1].p_pixels + ( ( p_effect->i_height - i_line ) / 2 -1) * p_picture->p[1].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0x00; if( 0x04 * i_line - 0x0f > 0 ) { if( 0x04 * i_line - 0x0f < 0xff ) *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = ( 0x04 * i_line) -0x0f ; else *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0xff; } else { *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_band_width * i + j ) /2 ) ) = 0x10 ; } } } } } band_sep_angle = 360.0 / i_nb_bands; section_sep_angle = 360.0 / i_sections; if( i_peak_height < 1 ) i_peak_height = 1; max_band_length = p_effect->i_height / 2 - ( i_rad + i_peak_height + 1 ); i_band_width = floor( 360 / i_nb_bands - i_separ ); if( i_band_width < 1 ) i_band_width = 1; for( c = 0 ; c < i_sections ; c++ ) for( i = 0 ; i < (i_nb_bands / i_sections) ; i++ ) { /* DO A PEAK */ if( peaks[i] > 0 && i_peak ) { if( peaks[i] >= p_effect->i_height ) peaks[i] = p_effect->i_height - 2; i_line = peaks[i]; /* circular line pattern(so color blend is more visible) */ for( j = 0 ; j < i_peak_height ; j++ ) { //x = p_picture->p[0].i_pitch / 2; x = p_effect->i_width / 2; y = p_effect->i_height / 2; xx = x; yy = y; for( k = 0 ; k < (i_band_width + i_extra_width) ; k++ ) { x = xx; y = yy; a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + k ) * 3.141592 / 180.0; x += (double)( cos(a) * (double)( i_line + j + i_rad ) ); y += (double)( -sin(a) * (double)( i_line + j + i_rad ) ); *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch ) = 255;/* Y(R,G,B); */ x /= 2; y /= 2; *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch ) = 0;/* U(R,G,B); */ if( 0x04 * (i_line + k ) - 0x0f > 0 ) { if ( 0x04 * (i_line + k ) -0x0f < 0xff) *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = ( 0x04 * ( i_line + k ) ) -(color1-1);/* -V(R,G,B); */ else *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = 255;/* V(R,G,B); */ } else { *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = color1;/* V(R,G,B); */ } } } } if( (height[i] * i_amp) > p_effect->i_height ) height[i] = floor( p_effect->i_height / i_amp ); /* DO BASE OF BAND (mostly makes a circle) */ if( i_show_base != 0 ) { //x = p_picture->p[0].i_pitch / 2; x = p_effect->i_width / 2; y = p_effect->i_height / 2; a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) ) * 3.141592 / 180.0; x += (double)( cos(a) * (double)i_rad );/* newb-forceful casting */ y += (double)( -sin(a) * (double)i_rad ); *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch ) = 255;/* Y(R,G,B); */ x /= 2; y /= 2; *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch ) = 0;/* U(R,G,B); */ if( 0x04 * i_line - 0x0f > 0 ) { if( 0x04 * i_line -0x0f < 0xff) *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = ( 0x04 * i_line) -(color1-1);/* -V(R,G,B); */ else *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = 255;/* V(R,G,B); */ } else { *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = color1;/* V(R,G,B); */ } } /* DO A BAND */ if( i_show_bands != 0 ) for( j = 0 ; j < i_band_width ; j++ ) { x = p_effect->i_width / 2; y = p_effect->i_height / 2; xx = x; yy = y; a = ( (i+1) * band_sep_angle + section_sep_angle * (c+1) + j ) * 3.141592/180.0; for( k = (i_rad+1) ; k < max_band_length ; k++ ) { if( (k-i_rad) > height[i] ) break;/* uhh.. */ x = xx; y = yy; x += (double)( cos(a) * (double)k );/* newbed! */ y += (double)( -sin(a) * (double)k ); *(p_picture->p[0].p_pixels + x + y * p_picture->p[0].i_pitch ) = 255; x /= 2; y /= 2; *(p_picture->p[1].p_pixels + x + y * p_picture->p[1].i_pitch ) = 0; if( 0x04 * i_line - 0x0f > 0 ) { if ( 0x04 * i_line -0x0f < 0xff) *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = ( 0x04 * i_line) -(color1-1); else *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = 255; } else { *(p_picture->p[2].p_pixels + x + y * p_picture->p[2].i_pitch ) = color1; } } } } fft_close( p_state ); free( height ); return 0; }
static int Control (access_t *access, int query, va_list args) { access_sys_t *sys = access->p_sys; dvb_device_t *dev = sys->dev; switch (query) { case ACCESS_CAN_SEEK: case ACCESS_CAN_FASTSEEK: case ACCESS_CAN_PAUSE: case ACCESS_CAN_CONTROL_PACE: { bool *v = va_arg (args, bool *); *v = false; return VLC_SUCCESS; } case ACCESS_GET_PTS_DELAY: { int64_t *v = va_arg (args, int64_t *); *v = var_InheritInteger (access, "live-caching") * INT64_C(1000); return VLC_SUCCESS; } case ACCESS_GET_TITLE_INFO: case ACCESS_GET_META: return VLC_EGENERIC; case ACCESS_GET_CONTENT_TYPE: { char **pt = va_arg (args, char **); *pt = strdup ("video/MP2T"); return VLC_SUCCESS; } case ACCESS_SET_PAUSE_STATE: case ACCESS_SET_TITLE: case ACCESS_SET_SEEKPOINT: return VLC_EGENERIC; case ACCESS_GET_SIGNAL: *va_arg (args, double *) = dvb_get_snr (dev); *va_arg (args, double *) = dvb_get_signal_strength (dev); return VLC_SUCCESS; case ACCESS_SET_PRIVATE_ID_STATE: { unsigned pid = va_arg (args, unsigned); bool add = va_arg (args, unsigned); if (unlikely(pid > 0x1FFF)) return VLC_EGENERIC; if (add) { if (dvb_add_pid (dev, pid)) return VLC_EGENERIC; } else dvb_remove_pid (dev, pid); return VLC_SUCCESS; } case ACCESS_SET_PRIVATE_ID_CA: #ifdef HAVE_DVBPSI { struct dvbpsi_pmt_s *pmt = va_arg (args, struct dvbpsi_pmt_s *); dvb_set_ca_pmt (dev, pmt); return VLC_SUCCESS; } #endif case ACCESS_GET_PRIVATE_ID_STATE: return VLC_EGENERIC; } msg_Warn (access, "unimplemented query %d in control", query); return VLC_EGENERIC; }
/***************************************************************************** * InitVideo: initialize the video decoder ***************************************************************************** * the ffmpeg codec will be opened, some memory allocated. The vout is not yet * opened (done after the first decoded frame). *****************************************************************************/ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, AVCodec *p_codec, int i_codec_id, const char *psz_namecodec ) { decoder_sys_t *p_sys; int i_val; /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL ) return VLC_ENOMEM; p_codec->type = AVMEDIA_TYPE_VIDEO; p_context->codec_type = AVMEDIA_TYPE_VIDEO; p_context->codec_id = i_codec_id; p_sys->p_context = p_context; p_sys->p_codec = p_codec; p_sys->i_codec_id = i_codec_id; p_sys->psz_namecodec = psz_namecodec; p_sys->p_ff_pic = avcodec_alloc_frame(); p_sys->b_delayed_open = true; p_sys->p_va = NULL; vlc_sem_init( &p_sys->sem_mt, 0 ); /* ***** Fill p_context with init values ***** */ p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ? p_dec->fmt_in.i_original_fourcc : p_dec->fmt_in.i_codec ); // sunqueen modify /* ***** Get configuration of ffmpeg plugin ***** */ p_sys->p_context->workaround_bugs = var_InheritInteger( p_dec, "avcodec-workaround-bugs" ); p_sys->p_context->err_recognition = var_InheritInteger( p_dec, "avcodec-error-resilience" ); if( var_CreateGetBool( p_dec, "grayscale" ) ) p_sys->p_context->flags |= CODEC_FLAG_GRAY; /* ***** Output always the frames ***** */ #if LIBAVCODEC_VERSION_CHECK(55, 23, 1, 40, 101) p_sys->p_context->flags |= CODEC_FLAG_OUTPUT_CORRUPT; #endif i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" ); if( i_val ) p_sys->p_context->debug_mv = i_val; i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" ); if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL; else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY; else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR; else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF; if( var_CreateGetBool( p_dec, "avcodec-fast" ) ) p_sys->p_context->flags2 |= CODEC_FLAG2_FAST; /* ***** libavcodec frame skipping ***** */ p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" ); i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" ); if( i_val >= 4 ) p_sys->p_context->skip_frame = AVDISCARD_ALL; else if( i_val == 3 ) p_sys->p_context->skip_frame = AVDISCARD_NONKEY; else if( i_val == 2 ) p_sys->p_context->skip_frame = AVDISCARD_BIDIR; else if( i_val == 1 ) p_sys->p_context->skip_frame = AVDISCARD_NONREF; else if( i_val == -1 ) p_sys->p_context->skip_frame = AVDISCARD_NONE; else p_sys->p_context->skip_frame = AVDISCARD_DEFAULT; p_sys->i_skip_frame = p_sys->p_context->skip_frame; i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" ); if( i_val >= 4 ) p_sys->p_context->skip_idct = AVDISCARD_ALL; else if( i_val == 3 ) p_sys->p_context->skip_idct = AVDISCARD_NONKEY; else if( i_val == 2 ) p_sys->p_context->skip_idct = AVDISCARD_BIDIR; else if( i_val == 1 ) p_sys->p_context->skip_idct = AVDISCARD_NONREF; else if( i_val == -1 ) p_sys->p_context->skip_idct = AVDISCARD_NONE; else p_sys->p_context->skip_idct = AVDISCARD_DEFAULT; p_sys->i_skip_idct = p_sys->p_context->skip_idct; /* ***** libavcodec direct rendering ***** */ p_sys->b_direct_rendering = false; p_sys->i_direct_rendering_used = -1; if( var_CreateGetBool( p_dec, "avcodec-dr" ) && (p_sys->p_codec->capabilities & CODEC_CAP_DR1) && /* No idea why ... but this fixes flickering on some TSCC streams */ p_sys->i_codec_id != AV_CODEC_ID_TSCC && p_sys->i_codec_id != AV_CODEC_ID_CSCD && p_sys->i_codec_id != AV_CODEC_ID_CINEPAK && !p_sys->p_context->debug_mv ) { /* Some codecs set pix_fmt only after the 1st frame has been decoded, * so we need to do another check in ffmpeg_GetFrameBuf() */ p_sys->b_direct_rendering = true; } /* libavcodec doesn't properly release old pictures when frames are skipped */ //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false; if( p_sys->b_direct_rendering ) { msg_Dbg( p_dec, "trying to use direct rendering" ); p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE; } else { msg_Dbg( p_dec, "direct rendering is disabled" ); } p_sys->p_context->get_format = ffmpeg_GetFormat; /* Always use our get_buffer wrapper so we can calculate the * PTS correctly */ #if LIBAVCODEC_VERSION_MAJOR >= 55 p_sys->p_context->get_buffer2 = lavc_GetFrame; #else p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf; p_sys->p_context->reget_buffer = avcodec_default_reget_buffer; p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf; #endif p_sys->p_context->opaque = p_dec; #ifdef HAVE_AVCODEC_MT int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" ); if( i_thread_count <= 0 ) { i_thread_count = vlc_GetCPUCount(); if( i_thread_count > 1 ) i_thread_count++; //FIXME: take in count the decoding time i_thread_count = __MIN( i_thread_count, 4 ); } i_thread_count = __MIN( i_thread_count, 16 ); msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count ); p_sys->p_context->thread_count = i_thread_count; p_sys->p_context->thread_safe_callbacks = true; switch( i_codec_id ) { case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_H263: p_sys->p_context->thread_type = 0; break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: p_sys->p_context->thread_type &= ~FF_THREAD_SLICE; /* fall through */ # if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0)) case AV_CODEC_ID_H264: case AV_CODEC_ID_VC1: case AV_CODEC_ID_WMV3: p_sys->p_context->thread_type &= ~FF_THREAD_FRAME; # endif } /* Workaround: frame multithreading is not compatible with * DXVA2. When a frame is being copied to host memory, the frame * is locked and cannot be used as a reference frame * simultaneously and thus decoding fails for some frames. This * causes major image corruption. */ # if defined(_WIN32) char *avcodec_hw = var_InheritString( p_dec, "avcodec-hw" ); if( avcodec_hw == NULL || strcasecmp( avcodec_hw, "none" ) ) { msg_Warn( p_dec, "threaded frame decoding is not compatible with DXVA2, disabled" ); p_sys->p_context->thread_type &= ~FF_THREAD_FRAME; } free( avcodec_hw ); # endif if( p_sys->p_context->thread_type & FF_THREAD_FRAME ) p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count; #endif /* ***** misc init ***** */ p_sys->i_pts = VLC_TS_INVALID; p_sys->b_has_b_frames = false; p_sys->b_first_frame = true; p_sys->b_flush = false; p_sys->i_late_frames = 0; /* Set output properties */ p_dec->fmt_out.i_cat = VIDEO_ES; if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ) { /* we are doomed. but not really, because most codecs set their pix_fmt later on */ p_dec->fmt_out.i_codec = VLC_CODEC_I420; } p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation; #if LIBAVCODEC_VERSION_MAJOR < 54 /* Setup palette */ memset( &p_sys->palette, 0, sizeof(p_sys->palette) ); if( p_dec->fmt_in.video.p_palette ) { p_sys->palette.palette_changed = 1; for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ ) { union { uint32_t u; uint8_t a[4]; } c; c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0]; c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1]; c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2]; c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3]; p_sys->palette.palette[i] = c.u; } p_sys->p_context->palctrl = &p_sys->palette; p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) ); if( p_dec->fmt_out.video.p_palette ) *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette; } else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK ) { p_sys->p_context->palctrl = &p_sys->palette; } #else if( p_dec->fmt_in.video.p_palette ) { p_sys->palette_sent = false; p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) ); if( p_dec->fmt_out.video.p_palette ) *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette; } else p_sys->palette_sent = true; #endif /* ***** init this codec with special data ***** */ ffmpeg_InitCodec( p_dec ); /* ***** Open the codec ***** */ if( ffmpeg_OpenCodec( p_dec ) < 0 ) { msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec ); avcodec_free_frame( &p_sys->p_ff_pic ); vlc_sem_destroy( &p_sys->sem_mt ); free( p_sys ); return VLC_EGENERIC; } if ( p_dec->fmt_in.i_codec == VLC_CODEC_VP9 ) p_dec->b_need_packetized = true; return VLC_SUCCESS; }
/** * It creates a Direct3D vout display. */ 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 = calloc(1, sizeof(vout_display_sys_t)); if (!sys) return VLC_ENOMEM; if (Direct3DCreate(vd)) { msg_Err(vd, "Direct3D could not be initialized"); Direct3DDestroy(vd); free(sys); return VLC_EGENERIC; } sys->use_desktop = var_CreateGetBool(vd, "video-wallpaper"); sys->reset_device = false; sys->reset_device = false; sys->allow_hw_yuv = var_CreateGetBool(vd, "directx-hw-yuv"); sys->desktop_save.is_fullscreen = vd->cfg->is_fullscreen; sys->desktop_save.is_on_top = false; sys->desktop_save.win.left = var_InheritInteger(vd, "video-x"); sys->desktop_save.win.right = vd->cfg->display.width; sys->desktop_save.win.top = var_InheritInteger(vd, "video-y"); sys->desktop_save.win.bottom = vd->cfg->display.height; if (CommonInit(vd)) goto error; /* */ video_format_t fmt; if (Direct3DOpen(vd, &fmt)) { msg_Err(vd, "Direct3D could not be opened"); goto error; } /* */ vout_display_info_t info = vd->info; info.is_slow = true; info.has_double_click = true; info.has_hide_mouse = false; info.has_pictures_invalid = true; info.has_event_thread = true; if (var_InheritBool(vd, "direct3d-hw-blending") && sys->d3dregion_format != D3DFMT_UNKNOWN && (sys->d3dcaps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) && (sys->d3dcaps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) && (sys->d3dcaps.TextureCaps & D3DPTEXTURECAPS_ALPHA) && (sys->d3dcaps.TextureOpCaps & D3DTEXOPCAPS_SELECTARG1) && (sys->d3dcaps.TextureOpCaps & D3DTEXOPCAPS_MODULATE)) info.subpicture_chromas = d3d_subpicture_chromas; else info.subpicture_chromas = NULL; /* Interaction */ vlc_mutex_init(&sys->lock); sys->ch_desktop = false; sys->desktop_requested = sys->use_desktop; vlc_value_t val; val.psz_string = _("Desktop"); var_Change(vd, "video-wallpaper", VLC_VAR_SETTEXT, &val, NULL); var_AddCallback(vd, "video-wallpaper", DesktopCallback, NULL); /* Setup vout_display now that everything is fine */ vd->fmt = fmt; vd->info = info; vd->pool = Pool; vd->prepare = Prepare; vd->display = Display; vd->control = Control; vd->manage = Manage; /* Fix state in case of desktop mode */ if (sys->use_desktop && vd->cfg->is_fullscreen) vout_display_SendEventFullscreen(vd, false); return VLC_SUCCESS; error: Direct3DClose(vd); CommonClean(vd); Direct3DDestroy(vd); free(vd->sys); return VLC_EGENERIC; }
/***************************************************************************** * OpenFilter: *****************************************************************************/ static int OpenFilter( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; audio_format_t *audio_in = &p_filter->fmt_in.audio; audio_format_t *audio_out = &p_filter->fmt_out.audio; if( ( audio_in->i_format != audio_out->i_format ) || ( audio_in->i_rate != audio_out->i_rate ) ) return VLC_EGENERIC; /* Allocate the memory needed to store the module's structure */ p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) ); if( unlikely( p_sys == NULL ) ) return VLC_ENOMEM; /* get number of and layout of input channels */ uint32_t i_output_physical = 0; uint8_t pi_map_ch[ AOUT_CHAN_MAX ] = { 0 }; /* which out channel each in channel is mapped to */ p_sys->b_normalize = var_InheritBool( p_this, REMAP_CFG "normalize" ); for( uint8_t in_ch = 0, wg4_i = 0; in_ch < audio_in->i_channels; in_ch++, wg4_i++ ) { /* explode in_channels in the right order */ while( ( audio_in->i_physical_channels & pi_vlc_chan_order_wg4[ wg4_i ] ) == 0 ) { wg4_i++; assert( wg4_i < sizeof( pi_vlc_chan_order_wg4 )/sizeof( pi_vlc_chan_order_wg4[0] ) ); } unsigned channel_wg4idx_len = sizeof( channel_wg4idx )/sizeof( channel_wg4idx[0] ); uint8_t *pi_chnidx = memchr( channel_wg4idx, wg4_i, channel_wg4idx_len ); assert( pi_chnidx != NULL ); uint8_t chnidx = pi_chnidx - channel_wg4idx; uint8_t out_idx = var_InheritInteger( p_this, channel_name[chnidx] ); pi_map_ch[in_ch] = channel_wg4idx[ out_idx ]; i_output_physical |= channel_flag[ out_idx ]; } i_output_physical = CanonicaliseChannels( i_output_physical ); audio_out->i_physical_channels = i_output_physical; aout_FormatPrepare( audio_out ); /* condense out_channels */ uint8_t out_ch_sorted[ AOUT_CHAN_MAX ]; for( uint8_t i = 0, wg4_i = 0; i < audio_out->i_channels; i++, wg4_i++ ) { while( ( audio_out->i_physical_channels & pi_vlc_chan_order_wg4[ wg4_i ] ) == 0 ) { wg4_i++; assert( wg4_i < sizeof( pi_vlc_chan_order_wg4 )/sizeof( pi_vlc_chan_order_wg4[0] ) ); } out_ch_sorted[ i ] = wg4_i; } bool b_multiple = false; /* whether we need to add channels (multiple in mapped to an out) */ memset( p_sys->nb_in_ch, 0, sizeof( p_sys->nb_in_ch ) ); for( uint8_t i = 0; i < audio_in->i_channels; i++ ) { uint8_t wg4_out_ch = pi_map_ch[i]; uint8_t *pi_out_ch = memchr( out_ch_sorted, wg4_out_ch, audio_out->i_channels ); assert( pi_out_ch != NULL ); p_sys->map_ch[i] = pi_out_ch - out_ch_sorted; if( ++p_sys->nb_in_ch[ p_sys->map_ch[i] ] > 1 ) b_multiple = true; } msg_Dbg( p_filter, "%s '%4.4s'->'%4.4s' %d Hz->%d Hz %s->%s", "Remap filter", (char *)&audio_in->i_format, (char *)&audio_out->i_format, audio_in->i_rate, audio_out->i_rate, aout_FormatPrintChannels( audio_in ), aout_FormatPrintChannels( audio_out ) ); p_sys->pf_remap = GetRemapFun( audio_in, b_multiple ); if( !p_sys->pf_remap ) { msg_Err( p_filter, "Could not decide on %s remap function", b_multiple ? "an add" : "a copy" ); free( p_sys ); return VLC_EGENERIC; } p_filter->pf_audio_filter = Remap; return VLC_SUCCESS; }
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf ) { /* Variables initialisation */ bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL; stackCentralOldWidget= NULL; sysTray = NULL; fullscreenControls = NULL; cryptedLabel = NULL; controls = NULL; inputC = NULL; b_hideAfterCreation = false; // --qt-start-minimized playlistVisible = false; input_name = ""; b_interfaceFullScreen= false; b_hasPausedWhenMinimized = false; i_kc_offset = false; /* Ask for Privacy */ FirstRun::CheckAndRun( this, p_intf ); /** * Configuration and settings * Pre-building of interface **/ /* Main settings */ setFocusPolicy( Qt::StrongFocus ); setAcceptDrops( true ); setWindowRole( "vlc-main" ); setWindowIcon( QApplication::windowIcon() ); setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) ); #ifdef Q_OS_MAC setAttribute( Qt::WA_MacBrushedMetal ); #endif /* Is video in embedded in the UI or not */ b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" ); /* Does the interface resize to video size or the opposite */ b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" ); /* Are we in the enhanced always-video mode or not ? */ b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" ); /* Do we want anoying popups or not */ i_notificationSetting = var_InheritInteger( p_intf, "qt-notification" ); /* */ b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" ); /* Set the other interface settings */ settings = getSettings(); #ifdef _WIN32 /* Volume keys */ p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" ); #endif /* */ b_plDocked = getSettings()->value( "MainWindow/pl-dock-status", true ).toBool(); /************************** * UI and Widgets design **************************/ setVLCWindowsTitle(); /************ * Menu Bar * ************/ VLCMenuBar::createMenuBar( this, p_intf ); CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ), this, destroyPopupMenu() ); createMainWidget( settings ); /************** * Status Bar * **************/ createStatusBar(); setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() ); /******************** * Input Manager * ********************/ MainInputManager::getInstance( p_intf ); #ifdef _WIN32 himl = NULL; p_taskbl = NULL; taskbar_wmsg = RegisterWindowMessage(TEXT("TaskbarButtonCreated")); #endif /********************************* * Create the Systray Management * *********************************/ initSystray(); /************************************************************* * Connect the input manager to the GUI elements it manages * * Beware initSystray did some connects on input manager too * *************************************************************/ /** * Connects on nameChanged() * Those connects are different because options can impeach them to trigger. **/ /* Main Interface statusbar */ CONNECT( THEMIM->getIM(), nameChanged( const QString& ), this, setName( const QString& ) ); /* and title of the Main Interface*/ if( var_InheritBool( p_intf, "qt-name-in-title" ) ) { CONNECT( THEMIM->getIM(), nameChanged( const QString& ), this, setVLCWindowsTitle( const QString& ) ); }
/***************************************************************************** * OpenDecoder: probe the decoder and return score *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*) p_this; int i_cat, i_codec_id, i_result; const char *psz_namecodec; AVCodecContext *p_context = NULL; AVCodec *p_codec = NULL; /* *** determine codec type *** */ if( !GetFfmpegCodec( p_dec->fmt_in.i_codec, &i_cat, &i_codec_id, &psz_namecodec ) ) { return VLC_EGENERIC; } /* Initialization must be done before avcodec_find_decoder() */ vlc_init_avcodec(); /* *** ask ffmpeg for a decoder *** */ char *psz_decoder = var_CreateGetString( p_this, "avcodec-codec" ); if( psz_decoder && *psz_decoder ) { p_codec = avcodec_find_decoder_by_name( psz_decoder ); if( !p_codec ) msg_Err( p_this, "Decoder `%s' not found", psz_decoder ); else if( p_codec->id != i_codec_id ) { msg_Err( p_this, "Decoder `%s' can't handle %4.4s", psz_decoder, (char*)&p_dec->fmt_in.i_codec ); p_codec = NULL; } } free( psz_decoder ); if( !p_codec ) p_codec = avcodec_find_decoder( i_codec_id ); if( !p_codec ) { msg_Dbg( p_dec, "codec not found (%s)", psz_namecodec ); return VLC_EGENERIC; } /* *** get a p_context *** */ #if LIBAVCODEC_VERSION_MAJOR >= 54 p_context = avcodec_alloc_context3(p_codec); #else p_context = avcodec_alloc_context(); #endif if( !p_context ) return VLC_ENOMEM; p_context->debug = var_InheritInteger( p_dec, "avcodec-debug" ); p_context->opaque = (void *)p_this; /* set CPU capabilities */ #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT( 51, 25, 0 ) av_set_cpu_flags_mask( INT_MAX & ~GetVlcDspMask() ); #else p_context->dsp_mask = GetVlcDspMask(); #endif p_dec->b_need_packetized = true; switch( i_cat ) { case VIDEO_ES: p_dec->pf_decode_video = DecodeVideo; i_result = InitVideoDec ( p_dec, p_context, p_codec, i_codec_id, psz_namecodec ); break; case AUDIO_ES: p_dec->pf_decode_audio = DecodeAudio; i_result = InitAudioDec ( p_dec, p_context, p_codec, i_codec_id, psz_namecodec ); break; case SPU_ES: p_dec->pf_decode_sub = DecodeSubtitle; i_result = InitSubtitleDec( p_dec, p_context, p_codec, i_codec_id, psz_namecodec ); break; default: i_result = VLC_EGENERIC; } if( i_result == VLC_SUCCESS ) { p_dec->p_sys->i_cat = i_cat; if( p_context->profile != FF_PROFILE_UNKNOWN) p_dec->fmt_in.i_profile = p_context->profile; if( p_context->level != FF_LEVEL_UNKNOWN) p_dec->fmt_in.i_level = p_context->level; } return i_result; }
/***************************************************************************** * Control input stream *****************************************************************************/ static int Control( access_t *p_access, int i_query, va_list args ) { access_sys_t *p_sys = p_access->p_sys; input_title_t ***ppp_title; int i; int64_t *pi64; vlc_meta_t *p_meta; switch( i_query ) { case STREAM_CAN_SEEK: case STREAM_CAN_FASTSEEK: case STREAM_CAN_PAUSE: case STREAM_CAN_CONTROL_PACE: *va_arg( args, bool* ) = true; break; case STREAM_GET_SIZE: *va_arg( args, uint64_t* ) = p_sys->size; break; case STREAM_GET_PTS_DELAY: pi64 = va_arg( args, int64_t * ); *pi64 = INT64_C(1000) * var_InheritInteger( p_access, "file-caching" ); break; case STREAM_SET_PAUSE_STATE: /* nothing to do */ break; case STREAM_GET_TITLE_INFO: /* return a copy of our seek points */ if( !p_sys->p_marks ) return VLC_EGENERIC; ppp_title = va_arg( args, input_title_t*** ); *va_arg( args, int* ) = 1; *ppp_title = malloc( sizeof( **ppp_title ) ); if( !*ppp_title ) return VLC_ENOMEM; **ppp_title = vlc_input_title_Duplicate( p_sys->p_marks ); break; case STREAM_GET_TITLE: *va_arg( args, unsigned * ) = 0; break; case STREAM_GET_SEEKPOINT: *va_arg( args, unsigned * ) = p_sys->cur_seekpoint; break; case STREAM_GET_CONTENT_TYPE: *va_arg( args, char ** ) = strdup( p_sys->b_ts_format ? "video/MP2T" : "video/MP2P" ); break; case STREAM_SET_TITLE: /* ignore - only one title */ break; case STREAM_SET_SEEKPOINT: i = va_arg( args, int ); return Seek( p_access, p_sys->offsets[i] ); case STREAM_GET_META: p_meta = va_arg( args, vlc_meta_t* ); vlc_meta_Merge( p_meta, p_sys->p_meta ); break; default: return VLC_EGENERIC; } return VLC_SUCCESS; }
/***************************************************************************** * OpenFilter *****************************************************************************/ static int OpenFilter( vlc_object_t *p_this ) { filter_t * p_filter = (filter_t *)p_this; filter_sys_t *p_sys = NULL; if( aout_FormatNbChannels( &(p_filter->fmt_in.audio) ) == 1 ) { /*msg_Dbg( p_filter, "filter discarded (incompatible format)" );*/ return VLC_EGENERIC; } if( (p_filter->fmt_in.audio.i_format != p_filter->fmt_out.audio.i_format) || (p_filter->fmt_in.audio.i_format != VLC_CODEC_S16N) || (p_filter->fmt_out.audio.i_format != VLC_CODEC_S16N) ) { /*msg_Err( p_this, "couldn't load mono filter" );*/ return VLC_EGENERIC; } /* Allocate the memory needed to store the module's structure */ p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) ); if( p_sys == NULL ) return VLC_EGENERIC; p_sys->b_downmix = var_InheritBool( p_this, MONO_CFG "downmix" ); p_sys->i_channel_selected = var_InheritInteger( p_this, MONO_CFG "channel" ); p_sys->i_nb_channels = aout_FormatNbChannels( &(p_filter->fmt_in.audio) ); p_sys->i_bitspersample = p_filter->fmt_out.audio.i_bitspersample; p_sys->i_overflow_buffer_size = 0; p_sys->p_overflow_buffer = NULL; p_sys->i_nb_atomic_operations = 0; p_sys->p_atomic_operations = NULL; if( Init( VLC_OBJECT(p_filter), p_filter->p_sys, aout_FormatNbChannels( &p_filter->fmt_in.audio ), p_filter->fmt_in.audio.i_physical_channels, p_filter->fmt_in.audio.i_rate ) < 0 ) { free( p_sys ); return VLC_EGENERIC; } if( p_sys->b_downmix ) { msg_Dbg( p_this, "using stereo to mono downmix" ); p_filter->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER; p_filter->fmt_out.audio.i_channels = 1; } else { msg_Dbg( p_this, "using pseudo mono" ); p_filter->fmt_out.audio.i_physical_channels = AOUT_CHANS_STEREO; p_filter->fmt_out.audio.i_channels = 2; } p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate; p_filter->pf_audio_filter = Convert; msg_Dbg( p_this, "%4.4s->%4.4s, channels %d->%d, bits per sample: %i->%i", (char *)&p_filter->fmt_in.i_codec, (char *)&p_filter->fmt_out.i_codec, p_filter->fmt_in.audio.i_physical_channels, p_filter->fmt_out.audio.i_physical_channels, p_filter->fmt_in.audio.i_bitspersample, p_filter->fmt_out.audio.i_bitspersample ); return VLC_SUCCESS; }
/***************************************************************************** * Open: open the visualizer *****************************************************************************/ static int Open( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; char *psz_effects, *psz_parser; video_format_t fmt; if( ( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 && p_filter->fmt_in.audio.i_format != VLC_CODEC_FI32 ) ) { return VLC_EGENERIC; } p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) ); if( unlikely (p_sys == NULL ) ) return VLC_EGENERIC; p_sys->i_height = var_InheritInteger( p_filter , "effect-height"); p_sys->i_width = var_InheritInteger( p_filter , "effect-width"); /* No resolution under 400x532 */ if( p_sys->i_height < 400 ) p_sys->i_height = 400; if( p_sys->i_width < 532 ) p_sys->i_width = 532; /* Work on even dimensions */ if( (p_sys->i_height % 2 ) != 0 ) p_sys->i_height--; if( (p_sys->i_width % 2 ) != 0 ) p_sys->i_width--; p_sys->i_effect = 0; p_sys->effect = NULL; /* Parse the effect list */ psz_parser = psz_effects = var_CreateGetString( p_filter, "effect-list" ); while( psz_parser && *psz_parser != '\0' ) { visual_effect_t *p_effect; p_effect = malloc( sizeof( visual_effect_t ) ); if( !p_effect ) break; p_effect->i_width = p_sys->i_width; p_effect->i_height = p_sys->i_height; p_effect->i_nb_chans = aout_FormatNbChannels( &p_filter->fmt_in.audio); p_effect->i_idx_left = 0; p_effect->i_idx_right = __MIN( 1, p_effect->i_nb_chans-1 ); p_effect->psz_args = NULL; p_effect->p_data = NULL; p_effect->pf_run = NULL; p_effect->psz_name = NULL; for( int i = 0; pf_effect_run[i].psz_name != NULL; i++ ) { if( !strncasecmp( psz_parser, pf_effect_run[i].psz_name, strlen( pf_effect_run[i].psz_name ) ) ) { p_effect->pf_run = pf_effect_run[i].pf_run; p_effect->psz_name = pf_effect_run[i].psz_name; break; } } if( p_effect->psz_name ) { psz_parser += strlen( p_effect->psz_name ); if( *psz_parser == '{' ) { char *psz_eoa; psz_parser++; if( ( psz_eoa = strchr( psz_parser, '}') ) == NULL ) { msg_Err( p_filter, "unable to parse effect list. Aborting"); free( p_effect ); break; } p_effect->psz_args = strndup( psz_parser, psz_eoa - psz_parser); } TAB_APPEND( p_sys->i_effect, p_sys->effect, p_effect ); } else { msg_Err( p_filter, "unknown visual effect: %s", psz_parser ); free( p_effect ); } if( strchr( psz_parser, ',' ) ) { psz_parser = strchr( psz_parser, ',' ) + 1; } else if( strchr( psz_parser, ':' ) ) { psz_parser = strchr( psz_parser, ':' ) + 1; } else { break; } } free( psz_effects ); if( !p_sys->i_effect ) { msg_Err( p_filter, "no effects found" ); free( p_sys ); return VLC_EGENERIC; } /* Open the video output */ memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_width = fmt.i_visible_width = p_sys->i_width; fmt.i_height = fmt.i_visible_height = p_sys->i_height; fmt.i_chroma = VLC_CODEC_I420; fmt.i_sar_num = fmt.i_sar_den = 1; p_sys->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt ); if( p_sys->p_vout == NULL ) { msg_Err( p_filter, "no suitable vout module" ); for( int i = 0; i < p_sys->i_effect; i++ ) { free( p_sys->effect[i]->psz_args ); free( p_sys->effect[i] ); } free( p_sys->effect ); free( p_sys ); return VLC_EGENERIC; } p_filter->pf_audio_filter = DoWork; return VLC_SUCCESS; }
/***************************************************************************** VCDOpen: open VCD. read in meta-information about VCD: the number of tracks, segments, entries, size and starting information. Then set up state variables so that we read/seek starting at the location specified. On success we return VLC_SUCCESS, on memory exhausted VLC_ENOMEM, and VLC_EGENERIC for some other error. *****************************************************************************/ int VCDOpen ( vlc_object_t *p_this ) { access_t *p_access = (access_t *)p_this; vcdplayer_t *p_vcdplayer; char *psz_source; vcdinfo_itemid_t itemid; bool play_single_item = false; p_access->pf_read = NULL; p_access->pf_block = VCDReadBlock; p_access->pf_control = VCDControl; p_access->pf_seek = VCDSeek; p_access->info.i_update = 0; p_access->info.i_size = 0; p_access->info.i_pos = 0; p_access->info.b_eof = false; p_access->info.i_title = 0; p_access->info.i_seekpoint = 0; p_vcdplayer = malloc( sizeof(vcdplayer_t) ); if( p_vcdplayer == NULL ) return VLC_ENOMEM; p_vcdplayer->i_debug = var_InheritInteger( p_this, MODULE_STRING "-debug" ); p_access->p_sys = (access_sys_t *) p_vcdplayer; /* Set where to log errors messages from libcdio. */ p_vcd_access = p_access; cdio_log_set_handler ( cdio_log_handler ); vcd_log_set_handler ( vcd_log_handler ); psz_source = VCDParse( p_access, &itemid, &play_single_item ); if ( NULL == psz_source ) { free( p_vcdplayer ); return( VLC_EGENERIC ); } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "source: %s: mrl: %s", psz_source, p_access->psz_location ); p_vcdplayer->psz_source = strdup(psz_source); p_vcdplayer->i_blocks_per_read = var_InheritInteger( p_this, MODULE_STRING "-blocks-per-read" ); p_vcdplayer->b_track_length = var_InheritInteger( p_this, MODULE_STRING "-track-length" ); p_vcdplayer->in_still = false; p_vcdplayer->play_item.type = VCDINFO_ITEM_TYPE_NOTFOUND; p_vcdplayer->p_input = access_GetParentInput( p_access ); // p_vcdplayer->p_meta = vlc_meta_New(); p_vcdplayer->p_segments = NULL; p_vcdplayer->p_entries = NULL; /* set up input */ if( !(p_vcdplayer->vcd = vcd_Open( p_this, psz_source )) ) { goto err_exit; } p_vcdplayer->b_svd = vcdinfo_get_tracksSVD(p_vcdplayer->vcd); /* Get track information. */ p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdplayer->vcd); if( p_vcdplayer->i_tracks<1 || CDIO_INVALID_TRACK==p_vcdplayer->i_tracks ) { vcdinfo_close( p_vcdplayer->vcd ); LOG_ERR ("no movie tracks found" ); goto err_exit; } /* Build Navigation Title table for the tracks. */ VCDTitles( p_access ); /* Add into the above entry points as "Chapters". */ if( ! VCDEntryPoints( p_access ) ) { msg_Warn( p_access, "could not read entry points, will not use them" ); p_vcdplayer->b_valid_ep = false; } /* Initialize LID info and add that as a menu item */ if( ! VCDLIDs( p_access ) ) { msg_Warn( p_access, "could not read entry LIDs" ); } /* Do we set PBC (via LID) on? */ p_vcdplayer->i_lid = ( VCDINFO_ITEM_TYPE_LID == itemid.type && p_vcdplayer->i_lids > itemid.num ) ? itemid.num : VCDINFO_INVALID_ENTRY; /* Initialize segment information and add that a "Track". */ VCDSegments( p_access ); vcdplayer_play( p_access, itemid ); free( p_access->psz_demux ); p_access->psz_demux = strdup( "ps" ); #ifdef FIXED if( play_single_item ) VCDFixupPlayList(p_access,p_vcd,psz_source,&itemid,play_single_item); #endif p_vcdplayer->p_access = p_access; free( psz_source ); return VLC_SUCCESS; err_exit: if( p_vcdplayer->p_input ) vlc_object_release( p_vcdplayer->p_input ); free( psz_source ); free( p_vcdplayer->psz_source ); free( p_vcdplayer ); return VLC_EGENERIC; }
/** * 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; playlist_t *p_playlist = NULL; char *psz_val; /* System specific initialization code */ system_Init(); /* Initialize the module bank and load the configuration of the * main module. We need to do this at this stage to be able to display * a short help if required by the user. (short help == main 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; } priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" ); /* Find verbosity from VLC_VERBOSE environment variable */ { char *env = getenv( "VLC_VERBOSE" ); if( env != NULL ) priv->i_verbose = atoi( env ); } /* Announce who we are (TODO: only first instance?) */ msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE ); msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE ); msg_Dbg( p_libvlc, "revision %s", psz_vlc_changeset ); msg_Dbg( p_libvlc, "configured with %s", CONFIGURE_LINE ); 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 ) ) { #ifdef WIN32 MessageBox (NULL, TEXT("The command line options could not be parsed.\n" "Make sure they are valid."), TEXT("VLC media player"), MB_OK|MB_ICONERROR); #endif module_EndBank (true); return VLC_EGENERIC; } priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" ); /* * 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); return VLC_EEXITSUCCESS; } if( module_count <= 1 ) { msg_Err( p_libvlc, "No plugins found! Check your VLC installation."); module_EndBank (true); return VLC_ENOITEM; } #ifdef HAVE_DAEMON /* Check for daemon mode */ if( var_InheritBool( p_libvlc, "daemon" ) ) { char *psz_pidfile = NULL; if( daemon( 1, 0) != 0 ) { msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" ); module_EndBank (true); return VLC_EEXIT; } b_daemon = true; /* lets check if we need to write the pidfile */ psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" ); if( psz_pidfile != NULL ) { FILE *pidfile; pid_t i_pid = getpid (); msg_Dbg( p_libvlc, "PID is %d, writing it to %s", i_pid, psz_pidfile ); pidfile = vlc_fopen( psz_pidfile,"w" ); if( pidfile != NULL ) { utf8_fprintf( pidfile, "%d", (int)i_pid ); fclose( pidfile ); } else { msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)", psz_pidfile ); } } free( psz_pidfile ); } #endif /* 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_STRING, &after_track, DBUS_TYPE_BOOLEAN, &play, DBUS_TYPE_INVALID ) ) { dbus_message_unref( msg ); msg = NULL; } free( mrl ); if( unlikely(msg == NULL) ) continue; msg_Dbg( p_libvlc, "Adds %s to the running media player", 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( 1 ); } #undef MPRIS_APPEND #undef MPRIS_BUS_NAME #undef MPRIS_OBJECT_PATH #undef MPRIS_TRACKLIST_INTERFACE dbus_out: #endif // HAVE_DBUS /* * Message queue options */ /* Last chance to set the verbosity. Once we start interfaces and other * threads, verbosity becomes read-only. */ var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); if( var_InheritBool( p_libvlc, "quiet" ) ) { var_SetInteger( p_libvlc, "verbose", -1 ); priv->i_verbose = -1; } if( priv->b_color ) priv->b_color = var_InheritBool( p_libvlc, "color" ); vlc_CPU_dump( VLC_OBJECT(p_libvlc) ); vlc_object_set_name( p_libvlc, "main" ); priv->b_stats = var_InheritBool( p_libvlc, "stats" ); /* * Initialize hotkey handling */ priv->actions = vlc_InitActions( 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 ); var_Create( p_libvlc, "user-agent", VLC_VAR_STRING ); var_SetString( p_libvlc, "user-agent", "(LibVLC "VERSION")" ); /* Initialize playlist and get commandline files */ p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) ); if( !p_playlist ) { msg_Err( p_libvlc, "playlist initialization failed" ); module_EndBank (true); return VLC_EGENERIC; } /* System specific configuration */ system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind ); #if defined(MEDIA_LIBRARY) /* Get the ML */ if( var_GetBool( p_libvlc, "load-media-library-on-startup" ) ) { priv->p_ml = ml_Create( VLC_OBJECT( p_libvlc ), NULL ); if( !priv->p_ml ) { msg_Err( p_libvlc, "ML initialization failed" ); return VLC_EGENERIC; } } else { priv->p_ml = NULL; } #endif /* Add service discovery modules */ psz_modules = var_InheritString( p_libvlc, "services-discovery" ); if( psz_modules ) { char *p = psz_modules, *m; while( ( m = strsep( &p, " :," ) ) != NULL ) playlist_ServicesDiscoveryAdd( p_playlist, m ); free( psz_modules ); } #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) { intf_Create( p_libvlc, psz_temp ); free( psz_temp ); } } free( psz_modules ); free( psz_control ); /* * Always load the hotkeys interface if it exists */ intf_Create( p_libvlc, "hotkeys,none" ); if( var_InheritBool( p_libvlc, "file-logging" ) #ifdef HAVE_SYSLOG_H && !var_InheritBool( p_libvlc, "syslog" ) #endif ) { intf_Create( p_libvlc, "logger,none" ); } #ifdef HAVE_SYSLOG_H if( var_InheritBool( p_libvlc, "syslog" ) ) { char *logmode = var_CreateGetNonEmptyString( p_libvlc, "logmode" ); var_SetString( p_libvlc, "logmode", "syslog" ); intf_Create( p_libvlc, "logger,none" ); if( logmode ) { var_SetString( p_libvlc, "logmode", logmode ); free( logmode ); } var_Destroy( p_libvlc, "logmode" ); } #endif if( var_InheritBool( p_libvlc, "network-synchronisation") ) { intf_Create( 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 #if defined (WIN32) || defined (__OS2__) var_Create( p_libvlc, "drawable-hwnd", VLC_VAR_INTEGER ); #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 ) { playlist_AddExt( p_playlist, psz_val, NULL, PLAYLIST_INSERT, 0, -1, 0, NULL, 0, true, pl_Unlocked ); free( psz_val ); } return VLC_SUCCESS; }
/***************************************************************************** * Control: *****************************************************************************/ static int Control( stream_t *p_access, int i_query, va_list args ) { access_sys_t *p_sys = p_access->p_sys; input_title_t ***ppp_title; switch( i_query ) { /* */ case STREAM_CAN_SEEK: case STREAM_CAN_FASTSEEK: case STREAM_CAN_PAUSE: case STREAM_CAN_CONTROL_PACE: *va_arg( args, bool* ) = true; break; case STREAM_GET_SIZE: { int i = p_sys->i_current_title; *va_arg( args, uint64_t * ) = (p_sys->p_sectors[i + 2] - p_sys->p_sectors[i + 1]) * (uint64_t)VCD_DATA_SIZE; break; } /* */ case STREAM_GET_PTS_DELAY: *va_arg( args, vlc_tick_t * ) = VLC_TICK_FROM_MS( var_InheritInteger(p_access, "disc-caching") ); break; /* */ case STREAM_SET_PAUSE_STATE: break; case STREAM_GET_TITLE_INFO: ppp_title = va_arg( args, input_title_t*** ); /* Duplicate title infos */ *ppp_title = vlc_alloc( p_sys->i_titles, sizeof(input_title_t *) ); if (!*ppp_title) return VLC_ENOMEM; *va_arg( args, int* ) = p_sys->i_titles; for( int i = 0; i < p_sys->i_titles; i++ ) (*ppp_title)[i] = vlc_input_title_New(); break; case STREAM_GET_TITLE: *va_arg( args, unsigned * ) = p_sys->i_current_title; break; case STREAM_GET_SEEKPOINT: *va_arg( args, unsigned * ) = p_sys->i_current_seekpoint; break; case STREAM_GET_CONTENT_TYPE: *va_arg( args, char ** ) = strdup("video/MP2P"); break; case STREAM_SET_TITLE: { int i = va_arg( args, int ); if( i != p_sys->i_current_title ) { /* Update info */ p_sys->offset = 0; p_sys->i_current_title = i; p_sys->i_current_seekpoint = 0; /* Next sector to read */ p_sys->i_sector = p_sys->p_sectors[1+i]; } break; } case STREAM_SET_SEEKPOINT: { int i = va_arg( args, int ); unsigned i_title = p_sys->i_current_title; if( p_sys->titles[i_title].count > 0 ) { p_sys->i_current_seekpoint = i; p_sys->i_sector = p_sys->p_sectors[1 + i_title] + p_sys->titles[i_title].seekpoints[i] / VCD_DATA_SIZE; p_sys->offset = (uint64_t)(p_sys->i_sector - p_sys->p_sectors[1 + i_title]) * VCD_DATA_SIZE; } break; } default: return VLC_EGENERIC; } return VLC_SUCCESS; }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; vlc_gl_t *gl = p_sys->gl; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif if( vlc_gl_MakeCurrent( gl ) != VLC_SUCCESS ) { msg_Err( p_filter, "Can't attach gl context" ); return NULL; } /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef _WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir(); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = var_InheritInteger( p_filter, "projectm-width" ); settings.windowHeight = var_CreateGetInteger( p_filter, "projectm-height" ); settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; settings.softCutRatingsEnabled= false; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ unsigned width, height; bool quit; if( vlc_gl_surface_CheckSize( gl, &width, &height ) ) p_projectm->projectM_resetGL( width, height ); /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } quit = p_sys->b_quit; vlc_mutex_unlock( &p_sys->lock ); if( quit ) break; p_projectm->renderFrame(); /* */ mwait( i_deadline ); vlc_gl_Swap( gl ); } delete p_projectm; if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } vlc_gl_ReleaseCurrent( gl ); return NULL; }
/***************************************************************************** * Import cut marks and convert them to seekpoints (chapters). *****************************************************************************/ static void ImportMarks( access_t *p_access ) { access_sys_t *p_sys = p_access->p_sys; FILE *marksfile = OpenRelativeFile( p_access, "marks" ); if( !marksfile ) return; FILE *indexfile = OpenRelativeFile( p_access, "index" ); if( !indexfile ) { fclose( marksfile ); return; } /* get the length of this recording (index stores 8 bytes per frame) */ struct stat st; if( fstat( fileno( indexfile ), &st ) ) { fclose( marksfile ); fclose( indexfile ); return; } int64_t i_frame_count = st.st_size / 8; /* Put all cut marks in a "dummy" title */ input_title_t *p_marks = vlc_input_title_New(); if( !p_marks ) { fclose( marksfile ); fclose( indexfile ); return; } p_marks->psz_name = strdup( _("VDR Cut Marks") ); p_marks->i_length = i_frame_count * (int64_t)( CLOCK_FREQ / p_sys->fps ); uint64_t *offsetv = NULL; size_t offsetc = 0; /* offset for chapter positions */ int i_chapter_offset = p_sys->fps / 1000 * var_InheritInteger( p_access, "vdr-chapter-offset" ); /* minimum chapter size in frames */ int i_min_chapter_size = p_sys->fps * MIN_CHAPTER_SIZE; /* the last chapter started at this frame (init to 0 so * we skip useless chapters near the beginning as well) */ int64_t i_prev_chapter = 0; /* parse lines of the form "0:00:00.00 foobar" */ char *line = NULL; size_t line_len; while( ReadLine( &line, &line_len, marksfile ) ) { int64_t i_frame = ParseFrameNumber( line, p_sys->fps ); /* skip chapters which are near the end or too close to each other */ if( i_frame - i_prev_chapter < i_min_chapter_size || i_frame >= i_frame_count - i_min_chapter_size ) continue; i_prev_chapter = i_frame; /* move chapters (simple workaround for inaccurate cut marks) */ if( i_frame > -i_chapter_offset ) i_frame += i_chapter_offset; else i_frame = 0; uint64_t i_offset; uint16_t i_file_number; if( !ReadIndexRecord( indexfile, p_sys->b_ts_format, i_frame, &i_offset, &i_file_number ) ) continue; if( i_file_number < 1 || i_file_number > FILE_COUNT ) continue; /* add file sizes to get the "global" offset */ seekpoint_t *sp = vlc_seekpoint_New(); if( !sp ) continue; sp->i_time_offset = i_frame * (int64_t)( CLOCK_FREQ / p_sys->fps ); sp->psz_name = strdup( line ); TAB_APPEND( p_marks->i_seekpoint, p_marks->seekpoint, sp ); TAB_APPEND( offsetc, offsetv, i_offset ); for( int i = 0; i + 1 < i_file_number; ++i ) offsetv[offsetc - 1] += FILE_SIZE( i ); } /* add a chapter at the beginning if missing */ if( p_marks->i_seekpoint > 0 && offsetv[0] > 0 ) { seekpoint_t *sp = vlc_seekpoint_New(); if( sp ) { sp->i_time_offset = 0; sp->psz_name = strdup( _("Start") ); TAB_INSERT( p_marks->i_seekpoint, p_marks->seekpoint, sp, 0 ); TAB_INSERT( offsetc, offsetv, UINT64_C(0), 0 ); } } if( p_marks->i_seekpoint > 0 ) { p_sys->p_marks = p_marks; p_sys->offsets = offsetv; } else { vlc_input_title_Delete( p_marks ); TAB_CLEAN( offsetc, offsetv ); } fclose( marksfile ); fclose( indexfile ); }
} static void DumpDeviceStatus (vlc_object_t *obj, snd_pcm_t *pcm) { snd_pcm_status_t *status; snd_pcm_status_alloca (&status); snd_pcm_status (pcm, status); Dump (obj, "current status:\n", snd_pcm_status_dump, status); } #define DumpDeviceStatus(o, p) DumpDeviceStatus(VLC_OBJECT(o), p) static unsigned SetupChannelsUnknown (vlc_object_t *obj, uint16_t *restrict mask) { uint16_t map = var_InheritInteger (obj, "alsa-audio-channels"); uint16_t chans = *mask & map; if (unlikely(chans == 0)) /* WTH? */ chans = AOUT_CHANS_STEREO; if (popcount (chans) < popcount (*mask)) msg_Dbg (obj, "downmixing from %u to %u channels", popcount (*mask), popcount (chans)); else msg_Dbg (obj, "keeping %u channels", popcount (chans)); *mask = chans; return 0; } #if (SND_LIB_VERSION >= 0x01001B)
/***************************************************************************** * Open: allocates Wall video thread output method ***************************************************************************** * This function allocates and initializes a Wall vout method. *****************************************************************************/ static int Open( vlc_object_t *p_this ) { video_splitter_t *p_splitter = (video_splitter_t*)p_this; video_splitter_sys_t *p_sys; const panoramix_chroma_t *p_chroma; for( int i = 0; ; i++ ) { vlc_fourcc_t i_chroma = p_chroma_array[i].i_chroma; if( !i_chroma ) { msg_Err( p_splitter, "colorspace not supported by plug-in !" ); return VLC_EGENERIC; } if( i_chroma == p_splitter->fmt.i_chroma ) { p_chroma = &p_chroma_array[i]; break; } } /* Allocate structure */ p_splitter->p_sys = p_sys = malloc( sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; /* */ p_sys->p_chroma = p_chroma; /* */ config_ChainParse( p_splitter, CFG_PREFIX, ppsz_filter_options, p_splitter->p_cfg ); /* */ p_sys->i_col = var_InheritInteger( p_splitter, CFG_PREFIX "cols" ); p_sys->i_row = var_InheritInteger( p_splitter, CFG_PREFIX "rows" ); /* Autodetect number of displays */ if( p_sys->i_col < 0 || p_sys->i_row < 0 ) { #ifdef _WIN32 const int i_monitor_count = GetSystemMetrics(SM_CMONITORS); if( i_monitor_count > 1 ) { p_sys->i_col = GetSystemMetrics( SM_CXVIRTUALSCREEN ) / GetSystemMetrics( SM_CXSCREEN ); p_sys->i_row = GetSystemMetrics( SM_CYVIRTUALSCREEN ) / GetSystemMetrics( SM_CYSCREEN ); if( p_sys->i_col * p_sys->i_row != i_monitor_count ) { p_sys->i_col = i_monitor_count; p_sys->i_row = 1; } } #else const unsigned i_monitors = CountMonitors( p_this ); if( i_monitors > 1 ) /* Find closest to square */ for( unsigned w = 1; (i_monitors / w) >= w ; w++ ) { if( i_monitors % w ) continue; p_sys->i_row = w; p_sys->i_col = i_monitors / w; } #endif /* By default do 2x1 */ if( p_sys->i_row < 0 ) p_sys->i_row = 1; if( p_sys->i_col < 0 ) p_sys->i_col = 2; var_SetInteger( p_splitter, CFG_PREFIX "cols", p_sys->i_col); var_SetInteger( p_splitter, CFG_PREFIX "rows", p_sys->i_row); } /* */ p_sys->b_attenuate = var_InheritBool( p_splitter, CFG_PREFIX "attenuate"); p_sys->bz_length = var_InheritInteger( p_splitter, CFG_PREFIX "bz-length" ); p_sys->bz_height = var_InheritInteger( p_splitter, CFG_PREFIX "bz-height" ); p_sys->bz_begin = var_InheritInteger( p_splitter, CFG_PREFIX "bz-begin" ); p_sys->bz_middle = var_InheritInteger( p_splitter, CFG_PREFIX "bz-middle" ); p_sys->bz_end = var_InheritInteger( p_splitter, CFG_PREFIX "bz-end" ); p_sys->bz_middle_pos = var_InheritInteger( p_splitter, CFG_PREFIX "bz-middle-pos" ); double d_p = 100.0 / p_sys->bz_middle_pos; p_sys->a_2 = d_p * p_sys->bz_begin - (double)(d_p * d_p / (d_p - 1)) * p_sys->bz_middle + (double)(d_p / (d_p - 1)) * p_sys->bz_end; p_sys->a_1 = -(d_p + 1) * p_sys->bz_begin + (double)(d_p * d_p / (d_p - 1)) * p_sys->bz_middle - (double)(1 / (d_p - 1)) * p_sys->bz_end; p_sys->a_0 = p_sys->bz_begin; /* */ p_sys->i_col = VLC_CLIP( COL_MAX, 1, p_sys->i_col ); p_sys->i_row = VLC_CLIP( ROW_MAX, 1, p_sys->i_row ); msg_Dbg( p_splitter, "opening a %i x %i wall", p_sys->i_col, p_sys->i_row ); if( p_sys->bz_length > 0 && ( p_sys->i_row > 1 || p_sys->i_col > 1 ) ) { const int i_overlap_w2_max = p_splitter->fmt.i_width / p_sys->i_col / 2; const int i_overlap_h2_max = p_splitter->fmt.i_height / p_sys->i_row / 2; const int i_overlap2_max = __MIN( i_overlap_w2_max, i_overlap_h2_max ); if( p_sys->i_col > 1 ) p_sys->i_overlap_w2 = i_overlap2_max * p_sys->bz_length / 100; else p_sys->i_overlap_w2 = 0; if( p_sys->i_row > 1 ) p_sys->i_overlap_h2 = i_overlap2_max * p_sys->bz_height / 100; else p_sys->i_overlap_h2 = 0; /* */ int i_div_max_w = 1; int i_div_max_h = 1; for( int i = 0; i < VOUT_MAX_PLANES; i++ ) { i_div_max_w = __MAX( i_div_max_w, p_chroma->pi_div_w[i] ); i_div_max_h = __MAX( i_div_max_h, p_chroma->pi_div_h[i] ); } p_sys->i_overlap_w2 = i_div_max_w * (p_sys->i_overlap_w2 / i_div_max_w); p_sys->i_overlap_h2 = i_div_max_h * (p_sys->i_overlap_h2 / i_div_max_h); } else { p_sys->i_overlap_w2 = 0; p_sys->i_overlap_h2 = 0; } /* Compute attenuate parameters */ if( p_sys->b_attenuate ) { panoramix_gamma_t p_gamma[VOUT_MAX_PLANES]; p_gamma[0].f_gamma = var_InheritFloat( p_splitter, CFG_PREFIX "bz-gamma-red" ); p_gamma[1].f_gamma = var_InheritFloat( p_splitter, CFG_PREFIX "bz-gamma-green" ); p_gamma[2].f_gamma = var_InheritFloat( p_splitter, CFG_PREFIX "bz-gamma-blue" ); p_gamma[0].f_black_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blackcrush-red" ) / 255.0; p_gamma[1].f_black_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blackcrush-green" ) / 255.0; p_gamma[2].f_black_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blackcrush-blue" ) / 255.0; p_gamma[0].f_white_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitecrush-red" ) / 255.0; p_gamma[1].f_white_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitecrush-green" ) / 255.0; p_gamma[2].f_white_crush = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitecrush-blue" ) / 255.0; p_gamma[0].f_black_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blacklevel-red" ) / 255.0; p_gamma[1].f_black_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blacklevel-green" ) / 255.0; p_gamma[2].f_black_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-blacklevel-blue" ) / 255.0; p_gamma[0].f_white_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitelevel-red" ) / 255.0; p_gamma[1].f_white_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitelevel-green" ) / 255.0; p_gamma[2].f_white_level = var_InheritInteger( p_splitter, CFG_PREFIX "bz-whitelevel-blue" ) / 255.0; for( int i = 3; i < VOUT_MAX_PLANES; i++ ) { /* Initialize unsupported planes */ p_gamma[i].f_gamma = 1.0; p_gamma[i].f_black_crush = 140.0/255.0; p_gamma[i].f_white_crush = 200.0/255.0; p_gamma[i].f_black_level = 150.0/255.0; p_gamma[i].f_white_level = 0.0/255.0; } if( p_chroma->i_chroma == VLC_CODEC_YV12 ) { /* Exchange U and V */ panoramix_gamma_t t = p_gamma[1]; p_gamma[1] = p_gamma[2]; p_gamma[2] = t; } for( int i_index = 0; i_index < 256; i_index++ ) { for( int i_index2 = 0; i_index2 <= ACCURACY; i_index2++ ) { for( int i_plane = 0; i_plane < VOUT_MAX_PLANES; i_plane++ ) { double f_factor = GammaFactor( &p_gamma[i_plane], (float)i_index / 255.0 ); float f_lut = clip_unit( 1.0 - ((ACCURACY - (float)i_index2) * f_factor / (ACCURACY - 1)) ); p_sys->p_lut[i_plane][i_index2][i_index] = f_lut * i_index + (int)( (1.0 - f_lut) * (float)p_chroma->pi_black[i_plane] ); } } } for( int i_plane = 0; i_plane < VOUT_MAX_PLANES; i_plane++ ) { if( !p_chroma->pi_div_w[i_plane] || !p_chroma->pi_div_h[i_plane] ) continue; const int i_length_w = (2 * p_sys->i_overlap_w2) / p_chroma->pi_div_w[i_plane]; const int i_length_h = (2 * p_sys->i_overlap_h2) / p_chroma->pi_div_h[i_plane]; for( int i_dir = 0; i_dir < 2; i_dir++ ) { const int i_length = i_dir == 0 ? i_length_w : i_length_h; const int i_den = i_length * i_length; const int a_2 = p_sys->a_2 * (ACCURACY / 100); const int a_1 = p_sys->a_1 * i_length * (ACCURACY / 100); const int a_0 = p_sys->a_0 * i_den * (ACCURACY / 100); for( int i_position = 0; i_position < 2; i_position++ ) { for( int i_index = 0; i_index < i_length; i_index++ ) { const int v = i_position == 1 ? i_index : (i_length - i_index); const int i_lambda = clip_accuracy( ACCURACY - (a_2 * v*v + a_1 * v + a_0) / i_den ); if( i_dir == 0 ) p_sys->lambdav[i_plane][i_position][i_index] = i_lambda; else p_sys->lambdah[i_plane][i_position][i_index] = i_lambda; } } } } } /* */ char *psz_state = var_InheritString( p_splitter, CFG_PREFIX "active" ); /* */ bool pb_active[COL_MAX*ROW_MAX]; for( int i = 0; i < COL_MAX*ROW_MAX; i++ ) pb_active[i] = psz_state == NULL; /* Parse active list if provided */ char *psz_tmp = psz_state; while( psz_tmp && *psz_tmp ) { char *psz_next = strchr( psz_tmp, ',' ); if( psz_next ) *psz_next++ = '\0'; const int i_index = atoi( psz_tmp ); if( i_index >= 0 && i_index < COL_MAX*ROW_MAX ) pb_active[i_index] = true; psz_tmp = psz_next; } free( psz_state ); /* */ p_splitter->i_output = Configuration( p_sys->pp_output, p_sys->i_col, p_sys->i_row, p_splitter->fmt.i_width, p_splitter->fmt.i_height, p_sys->i_overlap_w2, p_sys->i_overlap_h2, p_sys->b_attenuate, pb_active ); p_splitter->p_output = calloc( p_splitter->i_output, sizeof(*p_splitter->p_output) ); if( !p_splitter->p_output ) { free( p_sys ); return VLC_ENOMEM; } for( int y = 0; y < p_sys->i_row; y++ ) { for( int x = 0; x < p_sys->i_col; x++ ) { panoramix_output_t *p_output = &p_sys->pp_output[x][y]; if( !p_output->b_active ) continue; video_splitter_output_t *p_cfg = &p_splitter->p_output[p_output->i_output]; /* */ video_format_Copy( &p_cfg->fmt, &p_splitter->fmt ); p_cfg->fmt.i_visible_width = p_cfg->fmt.i_width = p_output->i_width; p_cfg->fmt.i_visible_height = p_cfg->fmt.i_height = p_output->i_height; p_cfg->window.i_x = p_output->i_x; p_cfg->window.i_y = p_output->i_y; p_cfg->window.i_align = p_output->i_align; p_cfg->psz_module = NULL; } } /* */ p_splitter->pf_filter = Filter; p_splitter->pf_mouse = Mouse; return VLC_SUCCESS; }
/** * Probes and initializes. */ static int Open (vlc_object_t *obj) { demux_t *demux = (demux_t *)obj; demux_sys_t *p_sys = malloc (sizeof (*p_sys)); if (p_sys == NULL) return VLC_ENOMEM; demux->p_sys = p_sys; /* Connect to X server */ char *display = var_InheritString (obj, "x11-display"); int snum; xcb_connection_t *conn = xcb_connect (display, &snum); free (display); if (xcb_connection_has_error (conn)) { free (p_sys); return VLC_EGENERIC; } p_sys->conn = conn; /* Find configured screen */ if (!strcmp (demux->psz_access, "screen")) { const xcb_setup_t *setup = xcb_get_setup (conn); const xcb_screen_t *scr = NULL; for (xcb_screen_iterator_t i = xcb_setup_roots_iterator (setup); i.rem > 0; xcb_screen_next (&i)) { if (snum == 0) { scr = i.data; break; } snum--; } if (scr == NULL) { msg_Err (obj, "bad X11 screen number"); goto error; } p_sys->window = scr->root; } else /* Determine capture window */ if (!strcmp (demux->psz_access, "window")) { char *end; unsigned long ul = strtoul (demux->psz_location, &end, 0); if (*end || ul > 0xffffffff) { msg_Err (obj, "bad X11 drawable %s", demux->psz_location); goto error; } p_sys->window = ul; xcb_composite_query_version_reply_t *r = xcb_composite_query_version_reply (conn, xcb_composite_query_version (conn, 0, 4), NULL); if (r == NULL || r->minor_version < 2) { msg_Err (obj, "X Composite extension not available"); free (r); goto error; } msg_Dbg (obj, "using Composite extension v%"PRIu32".%"PRIu32, r->major_version, r->minor_version); free (r); xcb_composite_redirect_window (conn, p_sys->window, XCB_COMPOSITE_REDIRECT_AUTOMATIC); } else goto error; /* Window properties */ p_sys->pixmap = xcb_generate_id (conn); p_sys->segment = xcb_generate_id (conn); p_sys->shm = CheckSHM (conn); p_sys->w = var_InheritInteger (obj, "screen-width"); p_sys->h = var_InheritInteger (obj, "screen-height"); if (p_sys->w != 0 || p_sys->h != 0) p_sys->follow_mouse = var_InheritBool (obj, "screen-follow-mouse"); else /* Following mouse is meaningless if width&height are dynamic. */ p_sys->follow_mouse = false; if (!p_sys->follow_mouse) /* X and Y are meaningless if following mouse */ { p_sys->x = var_InheritInteger (obj, "screen-left"); p_sys->y = var_InheritInteger (obj, "screen-top"); } /* Initializes format */ p_sys->rate = var_InheritFloat (obj, "screen-fps"); if (!p_sys->rate) goto error; mtime_t interval = (float)CLOCK_FREQ / p_sys->rate; if (!interval) goto error; p_sys->cur_w = 0; p_sys->cur_h = 0; p_sys->bpp = 0; p_sys->es = NULL; if (vlc_timer_create (&p_sys->timer, Demux, demux)) goto error; vlc_timer_schedule (p_sys->timer, false, 1, interval); /* Initializes demux */ demux->pf_demux = NULL; demux->pf_control = Control; return VLC_SUCCESS; error: xcb_disconnect (p_sys->conn); free (p_sys); return VLC_EGENERIC; }
SoundWidget::SoundWidget( QWidget *_parent, intf_thread_t * _p_intf, bool b_shiny, bool b_special ) : QWidget( _parent ), p_intf( _p_intf), b_is_muted( false ), b_ignore_valuechanged( false ) { /* We need a layout for this widget */ QHBoxLayout *layout = new QHBoxLayout( this ); layout->setSpacing( 0 ); layout->setMargin( 0 ); /* We need a Label for the pix */ volMuteLabel = new QLabel; volMuteLabel->setPixmap( QPixmap( ":/toolbar/volume-medium" ) ); /* We might need a subLayout too */ QVBoxLayout *subLayout; volMuteLabel->installEventFilter( this ); /* Normal View, click on icon mutes */ if( !b_special ) { volumeMenu = NULL; subLayout = NULL; volumeControlWidget = NULL; /* And add the label */ layout->addWidget( volMuteLabel, 0, b_shiny? Qt::AlignBottom : Qt::AlignCenter ); } else { /* Special view, click on button shows the slider */ b_shiny = false; volumeControlWidget = new QFrame( this ); subLayout = new QVBoxLayout( volumeControlWidget ); subLayout->setContentsMargins( 4, 4, 4, 4 ); volumeMenu = new QMenu( this ); QWidgetAction *widgetAction = new QWidgetAction( volumeControlWidget ); widgetAction->setDefaultWidget( volumeControlWidget ); volumeMenu->addAction( widgetAction ); /* And add the label */ layout->addWidget( volMuteLabel ); } /* Slider creation: shiny or clean */ if( b_shiny ) { volumeSlider = new SoundSlider( this, config_GetFloat( p_intf, "volume-step" ), var_InheritString( p_intf, "qt-slider-colours" ), var_InheritInteger( p_intf, "qt-max-volume") ); } else { volumeSlider = new QSlider( NULL ); volumeSlider->setAttribute( Qt::WA_MacSmallSize); volumeSlider->setOrientation( b_special ? Qt::Vertical : Qt::Horizontal ); volumeSlider->setMaximum( 200 ); } volumeSlider->setFocusPolicy( Qt::NoFocus ); if( b_special ) subLayout->addWidget( volumeSlider ); else layout->addWidget( volumeSlider, 0, b_shiny? Qt::AlignBottom : Qt::AlignCenter ); /* Set the volume from the config */ float volume = playlist_VolumeGet( THEPL ); libUpdateVolume( (volume >= 0.f) ? volume : 1.f ); /* Sync mute status */ if( playlist_MuteGet( THEPL ) > 0 ) updateMuteStatus( true ); /* Volume control connection */ volumeSlider->setTracking( true ); CONNECT( volumeSlider, valueChanged( int ), this, valueChangedFilter( int ) ); CONNECT( this, valueReallyChanged( int ), this, userUpdateVolume( int ) ); CONNECT( THEMIM, volumeChanged( float ), this, libUpdateVolume( float ) ); CONNECT( THEMIM, soundMuteChanged( bool ), this, updateMuteStatus( bool ) ); }
/***************************************************************************** * Open: open a scope effect plugin *****************************************************************************/ static int Open( vlc_object_t *p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; goom_thread_t *p_thread; video_format_t fmt; if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ) { msg_Warn( p_filter, "bad input format" ); return VLC_EGENERIC; } /* Allocate structure */ p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) ); /* Create goom thread */ p_sys->p_thread = p_thread = calloc( 1, sizeof(*p_thread) ); const int width = p_thread->i_width = var_InheritInteger( p_filter, "goom-width" ); const int height = p_thread->i_height = var_InheritInteger( p_filter, "goom-height" ); memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_width = fmt.i_visible_width = width; fmt.i_height = fmt.i_visible_height = height; fmt.i_chroma = VLC_CODEC_RGB32; fmt.i_sar_num = fmt.i_sar_den = 1; p_thread->p_vout = aout_filter_RequestVout( p_filter, NULL, &fmt ); if( p_thread->p_vout == NULL ) { msg_Err( p_filter, "no suitable vout module" ); free( p_thread ); free( p_sys ); return VLC_EGENERIC; } p_thread->i_speed = MAX_SPEED - var_InheritInteger( p_filter, "goom-speed" ); if( p_thread->i_speed < 0 ) p_thread->i_speed = 0; vlc_mutex_init( &p_thread->lock ); vlc_cond_init( &p_thread->wait ); p_thread->i_blocks = 0; date_Init( &p_thread->date, p_filter->fmt_in.audio.i_rate, 1 ); date_Set( &p_thread->date, 0 ); p_thread->i_channels = aout_FormatNbChannels( &p_filter->fmt_in.audio ); if( vlc_clone( &p_thread->thread, Thread, p_thread, VLC_THREAD_PRIORITY_LOW ) ) { msg_Err( p_filter, "cannot lauch goom thread" ); vlc_object_release( p_thread->p_vout ); vlc_mutex_destroy( &p_thread->lock ); vlc_cond_destroy( &p_thread->wait ); free( p_thread ); free( p_sys ); return VLC_EGENERIC; } p_filter->fmt_out.audio = p_filter->fmt_in.audio; p_filter->pf_audio_filter = DoWork; return VLC_SUCCESS; }
/***************************************************************************** * InitVideo: initialize the video decoder ***************************************************************************** * the ffmpeg codec will be opened, some memory allocated. The vout is not yet * opened (done after the first decoded frame). *****************************************************************************/ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, AVCodec *p_codec, int i_codec_id, const char *psz_namecodec ) { decoder_sys_t *p_sys; int i_val; /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL ) return VLC_ENOMEM; p_codec->type = AVMEDIA_TYPE_VIDEO; p_context->codec_type = AVMEDIA_TYPE_VIDEO; p_context->codec_id = i_codec_id; p_sys->p_context = p_context; p_sys->p_codec = p_codec; p_sys->i_codec_id = i_codec_id; p_sys->psz_namecodec = psz_namecodec; p_sys->p_ff_pic = avcodec_alloc_frame(); p_sys->b_delayed_open = true; p_sys->p_va = NULL; vlc_sem_init( &p_sys->sem_mt, 0 ); /* ***** Fill p_context with init values ***** */ p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec ); /* ***** Get configuration of ffmpeg plugin ***** */ p_sys->p_context->workaround_bugs = var_InheritInteger( p_dec, "ffmpeg-workaround-bugs" ); #if LIBAVCODEC_VERSION_MAJOR < 54 p_sys->p_context->error_recognition = #else p_sys->p_context->err_recognition = #endif var_InheritInteger( p_dec, "ffmpeg-error-resilience" ); if( var_CreateGetBool( p_dec, "grayscale" ) ) p_sys->p_context->flags |= CODEC_FLAG_GRAY; i_val = var_CreateGetInteger( p_dec, "ffmpeg-vismv" ); if( i_val ) p_sys->p_context->debug_mv = i_val; i_val = var_CreateGetInteger( p_dec, "ffmpeg-lowres" ); if( i_val > 0 && i_val <= 2 ) p_sys->p_context->lowres = i_val; i_val = var_CreateGetInteger( p_dec, "ffmpeg-skiploopfilter" ); if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL; else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY; else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR; else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF; if( var_CreateGetBool( p_dec, "ffmpeg-fast" ) ) p_sys->p_context->flags2 |= CODEC_FLAG2_FAST; /* ***** ffmpeg frame skipping ***** */ p_sys->b_hurry_up = var_CreateGetBool( p_dec, "ffmpeg-hurry-up" ); switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-frame" ) ) { case -1: p_sys->p_context->skip_frame = AVDISCARD_NONE; break; case 0: p_sys->p_context->skip_frame = AVDISCARD_DEFAULT; break; case 1: p_sys->p_context->skip_frame = AVDISCARD_NONREF; break; case 2: p_sys->p_context->skip_frame = AVDISCARD_NONKEY; break; case 3: p_sys->p_context->skip_frame = AVDISCARD_ALL; break; default: p_sys->p_context->skip_frame = AVDISCARD_NONE; break; } p_sys->i_skip_frame = p_sys->p_context->skip_frame; switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-idct" ) ) { case -1: p_sys->p_context->skip_idct = AVDISCARD_NONE; break; case 0: p_sys->p_context->skip_idct = AVDISCARD_DEFAULT; break; case 1: p_sys->p_context->skip_idct = AVDISCARD_NONREF; break; case 2: p_sys->p_context->skip_idct = AVDISCARD_NONKEY; break; case 3: p_sys->p_context->skip_idct = AVDISCARD_ALL; break; default: p_sys->p_context->skip_idct = AVDISCARD_NONE; break; } p_sys->i_skip_idct = p_sys->p_context->skip_idct; /* ***** ffmpeg direct rendering ***** */ p_sys->b_direct_rendering = false; p_sys->i_direct_rendering_used = -1; if( var_CreateGetBool( p_dec, "ffmpeg-dr" ) && (p_sys->p_codec->capabilities & CODEC_CAP_DR1) && /* No idea why ... but this fixes flickering on some TSCC streams */ p_sys->i_codec_id != CODEC_ID_TSCC && p_sys->i_codec_id != CODEC_ID_CSCD && p_sys->i_codec_id != CODEC_ID_CINEPAK && #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 68, 2 ) ) && (LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 100, 1 ) ) /* avcodec native vp8 decode doesn't handle EMU_EDGE flag, and I don't have idea howto implement fallback to libvpx decoder */ p_sys->i_codec_id != CODEC_ID_VP8 && #endif !p_sys->p_context->debug_mv ) { /* Some codecs set pix_fmt only after the 1st frame has been decoded, * so we need to do another check in ffmpeg_GetFrameBuf() */ p_sys->b_direct_rendering = true; } /* ffmpeg doesn't properly release old pictures when frames are skipped */ //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false; if( p_sys->b_direct_rendering ) { msg_Dbg( p_dec, "trying to use direct rendering" ); p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE; } else { msg_Dbg( p_dec, "direct rendering is disabled" ); } /* Always use our get_buffer wrapper so we can calculate the * PTS correctly */ p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf; p_sys->p_context->reget_buffer = ffmpeg_ReGetFrameBuf; p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf; p_sys->p_context->opaque = p_dec; #ifdef HAVE_AVCODEC_MT int i_thread_count = var_InheritInteger( p_dec, "ffmpeg-threads" ); if( i_thread_count <= 0 ) { i_thread_count = vlc_GetCPUCount(); if( i_thread_count > 1 ) i_thread_count++; //FIXME: take in count the decoding time i_thread_count = __MIN( i_thread_count, 4 ); } i_thread_count = __MIN( i_thread_count, 16 ); msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count ); p_sys->p_context->thread_count = i_thread_count; #endif #ifdef HAVE_AVCODEC_VA const bool b_use_hw = var_CreateGetBool( p_dec, "ffmpeg-hw" ); if( b_use_hw && (i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO || i_codec_id == CODEC_ID_MPEG4 || i_codec_id == CODEC_ID_H264 || i_codec_id == CODEC_ID_VC1 || i_codec_id == CODEC_ID_WMV3) ) { #ifdef HAVE_AVCODEC_MT if( p_sys->p_context->thread_type & FF_THREAD_FRAME ) { msg_Warn( p_dec, "threaded frame decoding is not compatible with ffmpeg-hw, disabled" ); p_sys->p_context->thread_type &= ~FF_THREAD_FRAME; } if( ( p_sys->p_context->thread_type & FF_THREAD_SLICE ) && ( i_codec_id == CODEC_ID_MPEG1VIDEO || i_codec_id == CODEC_ID_MPEG2VIDEO ) ) { msg_Warn( p_dec, "threaded slice decoding is not compatible with ffmpeg-hw, disabled" ); p_sys->p_context->thread_type &= ~FF_THREAD_SLICE; } #endif p_sys->p_context->get_format = ffmpeg_GetFormat; } #endif #ifdef HAVE_AVCODEC_MT if( p_sys->p_context->thread_type & FF_THREAD_FRAME ) p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count; #endif /* ***** misc init ***** */ p_sys->i_pts = VLC_TS_INVALID; p_sys->b_has_b_frames = false; p_sys->b_first_frame = true; p_sys->b_flush = false; p_sys->i_late_frames = 0; /* Set output properties */ p_dec->fmt_out.i_cat = VIDEO_ES; if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ) { /* we are doomed. but not really, because most codecs set their pix_fmt later on */ p_dec->fmt_out.i_codec = VLC_CODEC_I420; } p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; #if LIBAVCODEC_VERSION_MAJOR < 54 /* Setup palette */ memset( &p_sys->palette, 0, sizeof(p_sys->palette) ); if( p_dec->fmt_in.video.p_palette ) { p_sys->palette.palette_changed = 1; for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ ) { union { uint32_t u; uint8_t a[4]; } c; c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0]; c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1]; c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2]; c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3]; p_sys->palette.palette[i] = c.u; } p_sys->p_context->palctrl = &p_sys->palette; p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) ); if( p_dec->fmt_out.video.p_palette ) *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette; } else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK ) { p_sys->p_context->palctrl = &p_sys->palette; } #else # warning FIXME #endif /* ***** init this codec with special data ***** */ ffmpeg_InitCodec( p_dec ); /* ***** Open the codec ***** */ if( ffmpeg_OpenCodec( p_dec ) < 0 ) { msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec ); av_free( p_sys->p_ff_pic ); vlc_sem_destroy( &p_sys->sem_mt ); free( p_sys ); return VLC_EGENERIC; } return VLC_SUCCESS; }
static int Init( vlc_object_t *p_this, struct filter_sys_t * p_data , unsigned int i_nb_channels, uint32_t i_physical_channels , unsigned int i_rate ) { double d_x = var_InheritInteger( p_this, "headphone-dim" ); double d_z = d_x; double d_z_rear = -d_x/3; double d_min = 0; unsigned int i_next_atomic_operation; int i_source_channel_offset; unsigned int i; if( var_InheritBool( p_this, "headphone-compensate" ) ) { /* minimal distance to any speaker */ if( i_physical_channels & AOUT_CHAN_REARCENTER ) { d_min = d_z_rear; } else { d_min = d_z; } } /* Number of elementary operations */ p_data->i_nb_atomic_operations = i_nb_channels * 2; if( i_physical_channels & AOUT_CHAN_CENTER ) { p_data->i_nb_atomic_operations += 2; } p_data->p_atomic_operations = malloc( sizeof(struct atomic_operation_t) * p_data->i_nb_atomic_operations ); if( p_data->p_atomic_operations == NULL ) return -1; /* For each virtual speaker, computes elementary wave propagation time * to each ear */ i_next_atomic_operation = 0; i_source_channel_offset = 0; if( i_physical_channels & AOUT_CHAN_LEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z , d_min , 2.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_RIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , d_z , d_min , 2.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_MIDDLELEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , 0 , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_MIDDLERIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , 0 , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARLEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARRIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARCENTER ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , 0 , -d_z , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_CENTER ) { /* having two center channels increases the spatialization effect */ ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); i_next_atomic_operation += 2; ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_LFE ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , 0 , d_z_rear , d_min , 5.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } /* Initialize the overflow buffer * we need it because the process induce a delay in the samples */ p_data->i_overflow_buffer_size = 0; for( i = 0 ; i < p_data->i_nb_atomic_operations ; i++ ) { if( p_data->i_overflow_buffer_size < p_data->p_atomic_operations[i].i_delay * 2 * sizeof (float) ) { p_data->i_overflow_buffer_size = p_data->p_atomic_operations[i].i_delay * 2 * sizeof (float); } } p_data->p_overflow_buffer = malloc( p_data->i_overflow_buffer_size ); if( p_data->p_overflow_buffer == NULL ) { free( p_data->p_atomic_operations ); return -1; } memset( p_data->p_overflow_buffer, 0 , p_data->i_overflow_buffer_size ); return 0; }
/** * ProjectM update thread which do the rendering * @param p_this: the p_thread object */ static void *Thread( void *p_data ) { filter_t *p_filter = (filter_t*)p_data; filter_sys_t *p_sys = p_filter->p_sys; video_format_t fmt; vlc_gl_t *gl; unsigned int i_last_width = 0; unsigned int i_last_height = 0; locale_t loc; locale_t oldloc; projectM *p_projectm; #ifndef HAVE_PROJECTM2 char *psz_config; #else char *psz_preset_path; char *psz_title_font; char *psz_menu_font; projectM::Settings settings; #endif vlc_savecancel(); /* Create the openGL provider */ p_sys->p_vout = (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) ); if( !p_sys->p_vout ) goto error; /* */ video_format_Init( &fmt, 0 ); video_format_Setup( &fmt, VLC_CODEC_RGB32, p_sys->i_width, p_sys->i_height, 0, 1 ); fmt.i_sar_num = 1; fmt.i_sar_den = 1; vout_display_state_t state; memset( &state, 0, sizeof(state) ); state.cfg.display.sar.num = 1; state.cfg.display.sar.den = 1; state.cfg.is_display_filled = true; state.cfg.zoom.num = 1; state.cfg.zoom.den = 1; state.sar.num = 1; state.sar.den = 1; p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl", 300000, 1000000 ); if( !p_sys->p_vd ) { vlc_object_release( p_sys->p_vout ); goto error; } var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL ); var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); gl = vout_GetDisplayOpengl( p_sys->p_vd ); if( !gl ) { var_DelCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); goto error; } /* Work-around the projectM locale bug */ loc = newlocale (LC_NUMERIC_MASK, "C", NULL); oldloc = uselocale (loc); /* Create the projectM object */ #ifndef HAVE_PROJECTM2 psz_config = var_InheritString( p_filter, "projectm-config" ); p_projectm = new projectM( psz_config ); free( psz_config ); #else psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" ); #ifdef _WIN32 if ( psz_preset_path == NULL ) { char *psz_data_path = config_GetDataDir(); asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path ); free( psz_data_path ); } #endif psz_title_font = var_InheritString( p_filter, "projectm-title-font" ); psz_menu_font = var_InheritString( p_filter, "projectm-menu-font" ); settings.meshX = var_InheritInteger( p_filter, "projectm-meshx" ); settings.meshY = var_InheritInteger( p_filter, "projectm-meshy" ); settings.fps = 35; settings.textureSize = var_InheritInteger( p_filter, "projectm-texture-size" ); settings.windowWidth = p_sys->i_width; settings.windowHeight = p_sys->i_height; settings.presetURL = psz_preset_path; settings.titleFontURL = psz_title_font; settings.menuFontURL = psz_menu_font; settings.smoothPresetDuration = 5; settings.presetDuration = 30; settings.beatSensitivity = 10; settings.aspectCorrection = 1; settings.easterEgg = 1; settings.shuffleEnabled = 1; p_projectm = new projectM( settings ); free( psz_menu_font ); free( psz_title_font ); free( psz_preset_path ); #endif /* HAVE_PROJECTM2 */ p_sys->i_buffer_size = p_projectm->pcm()->maxsamples; p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size, sizeof( float ) ); vlc_sem_post( &p_sys->ready ); /* Choose a preset randomly or projectM will always show the first one */ if ( p_projectm->getPlaylistSize() > 0 ) p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() ); /* */ for( ;; ) { const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */ /* Manage the events */ vout_ManageDisplay( p_sys->p_vd, true ); if( p_sys->p_vd->cfg->display.width != i_last_width || p_sys->p_vd->cfg->display.height != i_last_height ) { /* FIXME it is not perfect as we will have black bands */ vout_display_place_t place; vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false ); p_projectm->projectM_resetGL( place.width, place.height ); i_last_width = p_sys->p_vd->cfg->display.width; i_last_height = p_sys->p_vd->cfg->display.height; } /* Render the image and swap the buffers */ vlc_mutex_lock( &p_sys->lock ); if( p_sys->i_nb_samples > 0 ) { p_projectm->pcm()->addPCMfloat( p_sys->p_buffer, p_sys->i_nb_samples ); p_sys->i_nb_samples = 0; } if( p_sys->b_quit ) { vlc_mutex_unlock( &p_sys->lock ); delete p_projectm; var_DelCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd ); vout_DeleteDisplay( p_sys->p_vd, NULL ); vlc_object_release( p_sys->p_vout ); if (loc != (locale_t)0) { uselocale (oldloc); freelocale (loc); } return NULL; } vlc_mutex_unlock( &p_sys->lock ); p_projectm->renderFrame(); /* */ mwait( i_deadline ); if( !vlc_gl_Lock(gl) ) { vlc_gl_Swap( gl ); vlc_gl_Unlock( gl ); } } abort(); error: p_sys->b_error = true; vlc_sem_post( &p_sys->ready ); return NULL; }
/** * 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_InheritBool(vd, "fb-hw-accel"); /* Set tty and fb devices */ sys->tty = 0; /* 0 == /dev/tty0 == current console */ sys->is_tty = var_InheritBool(vd, "fb-tty"); #if !defined(_WIN32) && defined(HAVE_ISATTY) /* Check that stdin is a TTY */ if (sys->is_tty && !isatty(0)) { msg_Warn(vd, "standard input 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_InheritInteger(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; } char *chroma = var_InheritString(vd, "fb-chroma"); if (chroma) { sys->chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma); if (sys->chroma) msg_Dbg(vd, "forcing chroma '%s'", chroma); else msg_Warn(vd, "chroma %s invalid, using default", chroma); free(chroma); } else sys->chroma = 0; /* 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; } vout_display_DeleteWindow(vd, NULL); /* */ video_format_t fmt; video_format_ApplyRotation(&fmt, &vd->fmt); if (sys->chroma) { fmt.i_chroma = sys->chroma; } else { /* Assume RGB */ msg_Dbg(vd, "%d bppd", 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 screendepth %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_visible_width = sys->width; fmt.i_visible_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 = NULL; /* */ vout_display_SendEventFullscreen(vd, true); vout_display_SendEventDisplaySize(vd, fmt.i_visible_width, fmt.i_visible_height, true); return VLC_SUCCESS; }
static void *Thread( void *obj ) { intf_thread_t *p_intf = (intf_thread_t *)obj; MainInterface *p_mi; char dummy[] = "vlc"; /* for WM_CLASS */ char *argv[4] = { dummy, NULL, }; int argc = 1; Q_INIT_RESOURCE( vlc ); /* Start the QApplication here */ #ifdef Q_WS_X11 if( x11_display != NULL ) { argv[argc++] = const_cast<char *>("-display"); argv[argc++] = x11_display; argv[argc] = NULL; } #endif QVLCApp app( argc, argv ); p_intf->p_sys->p_app = &app; /* All the settings are in the .conf/.ini style */ p_intf->p_sys->mainSettings = new QSettings( #ifdef WIN32 QSettings::IniFormat, #else QSettings::NativeFormat, #endif QSettings::UserScope, "vlc", "vlc-qt-interface" ); /* Icon setting */ if( QDate::currentDate().dayOfYear() >= 352 ) /* One Week before Xmas */ app.setWindowIcon( QIcon(vlc_christmas_xpm) ); else app.setWindowIcon( QIcon(vlc_xpm) ); /* Initialize timers and the Dialog Provider */ DialogsProvider::getInstance( p_intf ); /* Detect screensize for small screens like TV or EEEpc*/ p_intf->p_sys->i_screenHeight = app.QApplication::desktop()->availableGeometry().height(); #ifdef UPDATE_CHECK /* Checking for VLC updates */ if( var_InheritBool( p_intf, "qt-updates-notif" ) && !var_InheritBool( p_intf, "qt-privacy-ask" ) ) { int interval = var_InheritInteger( p_intf, "qt-updates-days" ); if( QDate::currentDate() > getSettings()->value( "updatedate" ).toDate().addDays( interval ) ) { /* The constructor of the update Dialog will do the 1st request */ UpdateDialog::getInstance( p_intf ); getSettings()->setValue( "updatedate", QDate::currentDate() ); } } #endif /* Create the normal interface in non-DP mode */ if( !p_intf->p_sys->b_isDialogProvider ) { p_mi = new MainInterface( p_intf ); p_intf->p_sys->p_mi = p_mi; } else p_mi = NULL; /* Explain how to show a dialog :D */ p_intf->pf_show_dialog = ShowDialog; /* Tell the main LibVLC thread we are ready */ vlc_sem_post (&ready); /* Last settings */ if( p_intf->p_sys->b_isDialogProvider ) app.setQuitOnLastWindowClosed( false ); else app.setQuitOnLastWindowClosed( true ); /* Retrieve last known path used in file browsing */ p_intf->p_sys->filepath = getSettings()->value( "filedialog-path", QVLCUserDir( VLC_HOME_DIR ) ).toString(); /* Loads and tries to apply the preferred QStyle */ QString s_style = getSettings()->value( "MainWindow/QtStyle", "" ).toString(); if( s_style.compare("") != 0 ) QApplication::setStyle( s_style ); /* Launch */ app.exec(); msg_Dbg( p_intf, "Exec finished()" ); if (p_mi != NULL) { QMutexLocker locker (&lock); active = false; p_intf->p_sys->p_mi = NULL; /* Destroy first the main interface because it is connected to some slots in the MainInputManager */ delete p_mi; } /* Destroy all remaining windows, because some are connected to some slots in the MainInputManager Settings must be destroyed after that. */ DialogsProvider::killInstance(); /* Delete the recentsMRL object before the configuration */ RecentsMRL::killInstance(); /* Save the path or delete if recent play are disabled */ if( var_InheritBool( p_intf, "qt-recentplay" ) ) getSettings()->setValue( "filedialog-path", p_intf->p_sys->filepath ); else getSettings()->remove( "filedialog-path" ); /* Delete the configuration. Application has to be deleted after that. */ delete p_intf->p_sys->mainSettings; /* Destroy the MainInputManager */ MainInputManager::killInstance(); /* Delete the application automatically */ return NULL; }
static int spectrum_Run(visual_effect_t * p_effect, vlc_object_t *p_aout, const block_t * p_buffer , picture_t * p_picture) { spectrum_data *p_data = p_effect->p_data; float p_output[FFT_BUFFER_SIZE]; /* Raw FFT Result */ int *height; /* Bar heights */ int *peaks; /* Peaks */ int *prev_heights; /* Previous bar heights */ int i_80_bands; /* number of bands : 80 if true else 20 */ int i_nb_bands; /* number of bands : 80 or 20 */ int i_band_width; /* width of bands */ int i_start; /* first band horizontal position */ int i_peak; /* Should we draw peaks ? */ /* Horizontal scale for 20-band equalizer */ const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27, 36,47,62,82,107,141,184,255}; /* Horizontal scale for 80-band equalizer */ const int xscale2[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51, 52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105, 110,115,121,130,141,152,163,174,185,200,255}; const int *xscale; fft_state *p_state; /* internal FFT data */ int i , j , y , k; int i_line; int16_t p_dest[FFT_BUFFER_SIZE]; /* Adapted FFT result */ int16_t p_buffer1[FFT_BUFFER_SIZE]; /* Buffer on which we perform the FFT (first channel) */ float *p_buffl = /* Original buffer */ (float*)p_buffer->p_buffer; int16_t *p_buffs; /* int16_t converted buffer */ int16_t *p_s16_buff; /* int16_t converted buffer */ /* Create p_data if needed */ if( !p_data ) { p_effect->p_data = p_data = malloc( sizeof( spectrum_data ) ); if( !p_data ) return -1; p_data->peaks = calloc( 80, sizeof(int) ); p_data->prev_heights = calloc( 80, sizeof(int) ); p_data->i_prev_nb_samples = 0; p_data->p_prev_s16_buff = NULL; } peaks = (int *)p_data->peaks; prev_heights = (int *)p_data->prev_heights; /* Allocate the buffer only if the number of samples change */ if( p_buffer->i_nb_samples != p_data->i_prev_nb_samples ) { free( p_data->p_prev_s16_buff ); p_data->p_prev_s16_buff = malloc( p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t)); p_data->i_prev_nb_samples = p_buffer->i_nb_samples; if( !p_data->p_prev_s16_buff ) return -1; } p_buffs = p_s16_buff = p_data->p_prev_s16_buff; i_80_bands = var_InheritInteger( p_aout, "visual-80-bands" ); i_peak = var_InheritInteger( p_aout, "visual-peaks" ); if( i_80_bands != 0) { xscale = xscale2; i_nb_bands = 80; } else { xscale = xscale1; i_nb_bands = 20; } height = malloc( i_nb_bands * sizeof(int) ); if( !height ) { return -1; } /* Convert the buffer to int16_t */ /* Pasted from float32tos16.c */ for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; ) { union { float f; int32_t i; } u; u.f = *p_buffl + 384.0; if(u.i > 0x43c07fff ) * p_buffs = 32767; else if ( u.i < 0x43bf8000 ) *p_buffs = -32768; else *p_buffs = u.i - 0x43c00000; p_buffl++ ; p_buffs++ ; } p_state = visual_fft_init(); if( !p_state) { free( height ); msg_Err(p_aout,"unable to initialize FFT transform"); return -1; } p_buffs = p_s16_buff; for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++) { p_output[i] = 0; p_buffer1[i] = *p_buffs; p_buffs += p_effect->i_nb_chans; if( p_buffs >= &p_s16_buff[p_buffer->i_nb_samples * p_effect->i_nb_chans] ) p_buffs = p_s16_buff; } fft_perform( p_buffer1, p_output, p_state); for( i = 0; i< FFT_BUFFER_SIZE ; i++ ) p_dest[i] = p_output[i] * ( 2 ^ 16 ) / ( ( FFT_BUFFER_SIZE / 2 * 32768 ) ^ 2 ); /* Compute the horizontal position of the first band */ i_band_width = floor( p_effect->i_width / i_nb_bands); i_start = ( p_effect->i_width - i_band_width * i_nb_bands ) / 2; for ( i = 0 ; i < i_nb_bands ;i++) { /* We search the maximum on one scale */ for( j = xscale[i], y = 0; j< xscale[ i + 1 ]; j++ ) { if ( p_dest[j] > y ) y = p_dest[j]; } /* Calculate the height of the bar */ if( y != 0 ) { height[i] = log( y ) * 30; if( height[i] > 380 ) height[i] = 380; } else height[ i ] = 0; /* Draw the bar now */ if( height[i] > peaks[i] ) { peaks[i] = height[i]; } else if( peaks[i] > 0 ) { peaks[i] -= PEAK_SPEED; if( peaks[i] < height[i] ) { peaks[i] = height[i]; } if( peaks[i] < 0 ) { peaks[i] = 0; } } /* Decrease the bars if needed */ if( height[i] <= prev_heights[i] - BAR_DECREASE_SPEED ) { height[i] = prev_heights[i]; height[i] -= BAR_DECREASE_SPEED; } prev_heights[i] = height[i]; if( peaks[i] > 0 && i_peak ) { if( peaks[i] >= p_effect->i_height ) peaks[i] = p_effect->i_height - 2; i_line = peaks[i]; for( j = 0; j < i_band_width - 1; j++ ) { for( k = 0; k < 3; k ++ ) { /* Draw the peak */ *(p_picture->p[0].p_pixels + ( p_effect->i_height - i_line -1 -k ) * p_picture->p[0].i_pitch + ( i_start + i_band_width*i + j ) ) = 0xff; *(p_picture->p[1].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[1].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0x00; if( i_line + k - 0x0f > 0 ) { if ( i_line + k - 0x0f < 0xff ) *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = ( i_line + k ) - 0x0f; else *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0xff; } else { *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1 -k/2 ) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0x10 ; } } } } if(height[i] > p_effect->i_height) height[i] = floor(p_effect->i_height ); for( i_line = 0; i_line < height[i]; i_line++ ) { for( j = 0 ; j < i_band_width - 1; j++) { *(p_picture->p[0].p_pixels + (p_effect->i_height - i_line - 1) * p_picture->p[0].i_pitch + ( i_start + i_band_width*i + j ) ) = 0xff; *(p_picture->p[1].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[1].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0x00; if( i_line - 0x0f > 0 ) { if( i_line - 0x0f < 0xff ) *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = i_line - 0x0f; else *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0xff; } else { *(p_picture->p[2].p_pixels + ( ( p_effect->i_height - i_line ) / 2 - 1) * p_picture->p[2].i_pitch + ( ( i_start + i_band_width * i + j ) /2 ) ) = 0x10; } } } } fft_close( p_state ); free( height ); return 0; }
/********************************************************************** * Fullscrenn control widget **********************************************************************/ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i, QWidget *_parent ) : AbstractController( _p_i, _parent ) { RTL_UNAFFECTED_WIDGET i_mouse_last_x = -1; i_mouse_last_y = -1; b_mouse_over = false; i_mouse_last_move_x = -1; i_mouse_last_move_y = -1; #if HAVE_TRANSPARENCY b_slow_hide_begin = false; i_slow_hide_timeout = 1; #endif b_fullscreen = false; i_hide_timeout = 1; i_screennumber = -1; vout.clear(); setWindowFlags( Qt::ToolTip ); setMinimumWidth( FSC_WIDTH ); isWideFSC = false; setFrameShape( QFrame::StyledPanel ); setFrameStyle( QFrame::Sunken ); setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); QVBoxLayout *controlLayout2 = new QVBoxLayout( this ); controlLayout2->setContentsMargins( 4, 6, 4, 2 ); /* First line */ InputControlsWidget *inputC = new InputControlsWidget( p_intf, this ); controlLayout2->addWidget( inputC ); controlLayout = new QHBoxLayout; QString line = getSettings()->value( "MainWindow/FSCtoolbar", FSC_TB_DEFAULT ).toString(); parseAndCreate( line, controlLayout ); controlLayout2->addLayout( controlLayout ); /* hiding timer */ p_hideTimer = new QTimer( this ); p_hideTimer->setSingleShot( true ); CONNECT( p_hideTimer, timeout(), this, hideFSC() ); /* slow hiding timer */ #if HAVE_TRANSPARENCY p_slowHideTimer = new QTimer( this ); CONNECT( p_slowHideTimer, timeout(), this, slowHideFSC() ); f_opacity = var_InheritFloat( p_intf, "qt-fs-opacity" ); #endif i_sensitivity = var_InheritInteger( p_intf, "qt-fs-sensitivity" ); vlc_mutex_init_recursive( &lock ); DCONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ), this, setVoutList( vout_thread_t **, int ) ); /* First Move */ previousPosition = getSettings()->value( "FullScreen/pos" ).toPoint(); screenRes = getSettings()->value( "FullScreen/screen" ).toRect(); isWideFSC = getSettings()->value( "FullScreen/wide" ).toBool(); i_screennumber = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" ); }
/***************************************************************************** * Open: connect to the Chromecast and initialize the sout *****************************************************************************/ static int Open(vlc_object_t *p_this) { sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; p_sys = new(std::nothrow) sout_stream_sys_t; if (p_sys == NULL) return VLC_ENOMEM; p_stream->p_sys = p_sys; config_ChainParse(p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg); char *psz_ipChromecast = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "ip"); if (psz_ipChromecast == NULL) { msg_Err(p_stream, "No Chromecast receiver IP provided"); Clean(p_stream); return VLC_EGENERIC; } p_sys->i_sock_fd = connectChromecast(p_stream, psz_ipChromecast); free(psz_ipChromecast); if (p_sys->i_sock_fd < 0) { msg_Err(p_stream, "Could not connect the Chromecast"); Clean(p_stream); return VLC_EGENERIC; } p_sys->i_status = CHROMECAST_TLS_CONNECTED; char psz_localIP[NI_MAXNUMERICHOST]; if (net_GetSockAddress(p_sys->i_sock_fd, psz_localIP, NULL)) { msg_Err(p_this, "Cannot get local IP address"); Clean(p_stream); return VLC_EGENERIC; } p_sys->serverIP = psz_localIP; char *psz_mux = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "mux"); if (psz_mux == NULL) { Clean(p_stream); return VLC_EGENERIC; } char *psz_chain = NULL; int i_bytes = asprintf(&psz_chain, "http{dst=:%u/stream,mux=%s}", (unsigned)var_InheritInteger(p_stream, SOUT_CFG_PREFIX"http-port"), psz_mux); free(psz_mux); if (i_bytes < 0) { Clean(p_stream); return VLC_EGENERIC; } p_sys->p_out = sout_StreamChainNew(p_stream->p_sout, psz_chain, NULL, NULL); free(psz_chain); if (p_sys->p_out == NULL) { Clean(p_stream); return VLC_EGENERIC; } vlc_mutex_init(&p_sys->lock); vlc_cond_init(&p_sys->loadCommandCond); // Start the Chromecast event thread. if (vlc_clone(&p_sys->chromecastThread, chromecastThread, p_stream, VLC_THREAD_PRIORITY_LOW)) { msg_Err(p_stream, "Could not start the Chromecast talking thread"); Clean(p_stream); return VLC_EGENERIC; } /* Ugly part: * We want to be sure that the Chromecast receives the first data packet sent by * the HTTP server. */ // Lock the sout thread until we have sent the media loading command to the Chromecast. int i_ret = 0; const mtime_t deadline = mdate() + 6 * CLOCK_FREQ; vlc_mutex_lock(&p_sys->lock); while (p_sys->i_status != CHROMECAST_MEDIA_LOAD_SENT) { i_ret = vlc_cond_timedwait(&p_sys->loadCommandCond, &p_sys->lock, deadline); if (i_ret == ETIMEDOUT) { msg_Err(p_stream, "Timeout reached before sending the media loading command"); vlc_mutex_unlock(&p_sys->lock); vlc_cancel(p_sys->chromecastThread); Clean(p_stream); return VLC_EGENERIC; } } vlc_mutex_unlock(&p_sys->lock); /* Even uglier: sleep more to let to the Chromecast initiate the connection * to the http server. */ msleep(2 * CLOCK_FREQ); // Set the sout callbacks. p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; return VLC_SUCCESS; }
/** * Opens the DVB tuner */ dvb_device_t *dvb_open (vlc_object_t *obj) { dvb_device_t *d = malloc (sizeof (*d)); if (unlikely(d == NULL)) return NULL; d->obj = obj; uint8_t adapter = var_InheritInteger (obj, "dvb-adapter"); d->device = var_InheritInteger (obj, "dvb-device"); d->dir = dvb_open_adapter (adapter); if (d->dir == -1) { msg_Err (obj, "cannot access adapter %"PRIu8": %m", adapter); free (d); return NULL; } d->frontend = -1; #ifdef HAVE_DVBPSI d->cam = NULL; #endif d->budget = var_InheritBool (obj, "dvb-budget-mode"); #ifndef USE_DMX if (d->budget) #endif { d->demux = dvb_open_node (d, "demux", O_RDONLY); if (d->demux == -1) { msg_Err (obj, "cannot access demultiplexer: %m"); close (d->dir); free (d); return NULL; } if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0) msg_Warn (obj, "cannot expand demultiplexing buffer: %m"); /* We need to filter at least one PID. The tap for TS demultiplexing * cannot be configured otherwise. So add the PAT. */ struct dmx_pes_filter_params param; param.pid = d->budget ? 0x2000 : 0x000; param.input = DMX_IN_FRONTEND; param.output = DMX_OUT_TSDEMUX_TAP; param.pes_type = DMX_PES_OTHER; param.flags = DMX_IMMEDIATE_START; if (ioctl (d->demux, DMX_SET_PES_FILTER, ¶m) < 0) { msg_Err (obj, "cannot setup TS demultiplexer: %m"); goto error; } #ifndef USE_DMX } else { for (size_t i = 0; i < MAX_PIDS; i++) d->pids[i].pid = d->pids[i].fd = -1; d->demux = dvb_open_node (d, "dvr", O_RDONLY); if (d->demux == -1) { msg_Err (obj, "cannot access DVR: %m"); close (d->dir); free (d); return NULL; } #endif } #ifdef HAVE_DVBPSI int ca = dvb_open_node (d, "ca", O_RDWR); if (ca != -1) { d->cam = en50221_Init (obj, ca); if (d->cam == NULL) close (ca); } else msg_Dbg (obj, "conditional access module not available (%m)"); #endif return d; error: dvb_close (d); return NULL; }