/* Open Interface */ static int Open( vlc_object_t *p_this, bool isDialogProvider ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; #ifdef Q_WS_X11 if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; char *display = var_CreateGetNonEmptyString( p_intf, "x11-display" ); Display *p_display = XOpenDisplay( x11_display ); if( !p_display ) { msg_Err( p_intf, "Could not connect to X server" ); free (display); return VLC_EGENERIC; } XCloseDisplay( p_display ); #else char *display = NULL; #endif QMutexLocker locker (&lock); if (busy) { msg_Err (p_this, "cannot start Qt4 multiple times"); free (display); return VLC_EGENERIC; } /* Allocations of p_sys */ intf_sys_t *p_sys = p_intf->p_sys = new intf_sys_t; p_intf->p_sys->b_isDialogProvider = isDialogProvider; p_sys->p_mi = NULL; p_sys->p_playlist = pl_Get( p_intf ); /* */ #ifdef Q_WS_X11 x11_display = display; #endif vlc_sem_init (&ready, 0); if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { delete p_sys; free (display); return VLC_ENOMEM; } /* */ vlc_sem_wait (&ready); vlc_sem_destroy (&ready); busy = active = true; if( !p_sys->b_isDialogProvider ) { playlist_t *pl = pl_Get(p_this); var_Create (pl, "qt4-iface", VLC_VAR_ADDRESS); var_SetAddress (pl, "qt4-iface", p_this); } return VLC_SUCCESS; }
Upnp_i11e_cb::Upnp_i11e_cb( Upnp_FunPtr callback, void *cookie ) : m_refCount( 2 ) /* 2: owned by the caller, and the Upnp Async function */ , m_callback( callback ) , m_cookie( cookie ) { vlc_mutex_init( &m_lock ); vlc_sem_init( &m_sem, 0 ); }
void libvlc_wait( libvlc_instance_t *p_i ) { vlc_sem_t sem; vlc_sem_init( &sem, 0 ); libvlc_set_exit_handler( p_i, libvlc_wait_wakeup, &sem ); vlc_sem_wait( &sem ); libvlc_set_exit_handler( p_i, NULL, NULL ); vlc_sem_destroy( &sem ); }
/** * Open the module * @param p_this: the filter object * @return VLC_SUCCESS or vlc error codes */ static int Open( vlc_object_t * p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; /* Test the audio format */ if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 || p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 ) { msg_Warn( p_filter, "bad input or output format" ); return VLC_EGENERIC; } if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) ) { msg_Warn( p_filter, "input and outut are not similar" ); return VLC_EGENERIC; } p_filter->pf_audio_filter = DoWork; p_sys = p_filter->p_sys = (filter_sys_t*)malloc( sizeof( *p_sys ) ); if( !p_sys ) return VLC_ENOMEM; /* Create the object for the thread */ vlc_sem_init( &p_sys->ready, 0 ); p_sys->b_error = false; p_sys->b_quit = false; p_sys->i_width = var_InheritInteger( p_filter, "projectm-width" ); p_sys->i_height = var_InheritInteger( p_filter, "projectm-height" ); p_sys->i_channels = aout_FormatNbChannels( &p_filter->fmt_in.audio ); vlc_mutex_init( &p_sys->lock ); p_sys->p_buffer = NULL; p_sys->i_buffer_size = 0; p_sys->i_nb_samples = 0; /* Create the thread */ if( vlc_clone( &p_sys->thread, Thread, p_filter, VLC_THREAD_PRIORITY_LOW ) ) goto error; vlc_sem_wait( &p_sys->ready ); if( p_sys->b_error ) { vlc_join( p_sys->thread, NULL ); goto error; } return VLC_SUCCESS; error: vlc_sem_destroy( &p_sys->ready ); free (p_sys ); return VLC_EGENERIC; }
/** * Open the module. * @param p_this: the filter object * @return VLC_SUCCESS or vlc error codes */ static int Open(vlc_object_t * p_this) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; p_sys = p_filter->p_sys = (filter_sys_t*)malloc(sizeof(*p_sys)); if (p_sys == NULL) return VLC_ENOMEM; /* Create the object for the thread */ vlc_sem_init(&p_sys->ready, 0); p_sys->b_error = false; p_sys->i_width = var_InheritInteger(p_filter, "glspectrum-width"); p_sys->i_height = var_InheritInteger(p_filter, "glspectrum-height"); p_sys->i_channels = aout_FormatNbChannels(&p_filter->fmt_in.audio); p_sys->i_prev_nb_samples = 0; p_sys->p_prev_s16_buff = NULL; p_sys->f_rotationAngle = 0; p_sys->f_rotationIncrement = ROTATION_INCREMENT; /* Fetch the FFT window parameters */ window_get_param( VLC_OBJECT( p_filter ), &p_sys->wind_param ); /* Create the FIFO for the audio data. */ p_sys->fifo = block_FifoNew(); if (p_sys->fifo == NULL) goto error; /* Create the thread */ if (vlc_clone(&p_sys->thread, Thread, p_filter, VLC_THREAD_PRIORITY_VIDEO)) goto error; /* Wait for the displaying thread to be ready. */ vlc_sem_wait(&p_sys->ready); if (p_sys->b_error) { vlc_join(p_sys->thread, NULL); goto error; } p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32; p_filter->fmt_out.audio = p_filter->fmt_in.audio; p_filter->pf_audio_filter = DoWork; return VLC_SUCCESS; error: vlc_sem_destroy(&p_sys->ready); free(p_sys); return VLC_EGENERIC; }
/** * Open the module * @param p_this: the filter object * @return VLC_SUCCESS or vlc error codes */ static int Open( vlc_object_t * p_this ) { filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys; /* Test the audio format */ if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ) { msg_Warn( p_filter, "bad input format" ); return VLC_EGENERIC; } p_sys = p_filter->p_sys = (filter_sys_t*)malloc( sizeof( *p_sys ) ); if( unlikely( !p_sys ) ) { return VLC_ENOMEM; } /* Create the object for the thread */ vlc_sem_init( &p_sys->ready, 0 ); p_sys->b_error = false; p_sys->b_quit = false; p_sys->i_width = var_InheritInteger( p_filter, "vsxu-width" ); p_sys->i_height = var_InheritInteger( p_filter, "vsxu-height" ); p_sys->i_channels = aout_FormatNbChannels( &p_filter->fmt_in.audio ); vlc_mutex_init( &p_sys->lock ); vlc_mutex_init( &p_sys->cyclic_block_mutex ); p_sys->vsxu_cyclic_buffer = new cyclic_block_queue(); /* Create the thread */ if( vlc_clone( &p_sys->thread, Thread, p_filter, VLC_THREAD_PRIORITY_LOW ) ) goto error; vlc_sem_wait( &p_sys->ready ); if( p_sys->b_error ) { vlc_join( p_sys->thread, NULL ); goto error; } p_filter->fmt_out.audio = p_filter->fmt_in.audio; p_filter->pf_audio_filter = DoWork; return VLC_SUCCESS; error: vlc_sem_destroy( &p_sys->ready ); free (p_sys ); return VLC_EGENERIC; }
static void media_parse_sync(libvlc_media_t *p_m) { vlc_sem_t sem; vlc_sem_init(&sem, 0); libvlc_event_manager_t *p_em = libvlc_media_event_manager(p_m); libvlc_event_attach(p_em, libvlc_MediaParsedChanged, finished_event, &sem); int i_ret = libvlc_media_parse_with_options(p_m, libvlc_media_parse_local); assert(i_ret == 0); vlc_sem_wait (&sem); libvlc_event_detach(p_em, libvlc_MediaParsedChanged, finished_event, &sem); vlc_sem_destroy (&sem); }
static int vlc_clone_attr (vlc_thread_t *th, void *(*entry) (void *), void *data, bool detach) { vlc_thread_t thread = malloc (sizeof (*thread)); if (unlikely(thread == NULL)) return ENOMEM; int ret; sigset_t oldset; { sigset_t set; sigemptyset (&set); sigdelset (&set, SIGHUP); sigaddset (&set, SIGINT); sigaddset (&set, SIGQUIT); sigaddset (&set, SIGTERM); sigaddset (&set, SIGPIPE); /* We don't want this one, really! */ pthread_sigmask (SIG_BLOCK, &set, &oldset); } if (!detach) vlc_sem_init(&thread->finished, 0); atomic_store(&thread->killed, false); thread->killable = true; thread->entry = entry; thread->data = data; thread->wait.addr = NULL; vlc_mutex_init(&thread->wait.lock); pthread_attr_t attr; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE); ret = pthread_create (&thread->thread, &attr, detach ? detached_thread : joinable_thread, thread); pthread_attr_destroy (&attr); pthread_sigmask (SIG_SETMASK, &oldset, NULL); *th = thread; return ret; }
/***************************************************************************** * Module callbacks *****************************************************************************/ static int Open( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; intf_sys_t *p_sys; vlc_value_t val; if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; /* Allocate instance and initialize some members */ p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) ); if( p_intf->p_sys == NULL ) return VLC_ENOMEM; p_sys->p_playlist = pl_Get( p_intf ); p_sys->p_input = NULL; p_sys->p_main_window = NULL; p_sys->p_video_window = NULL; p_sys->p_control_window = NULL; p_sys->b_fullscreen = false; p_sys->i_event = 0; vlc_spin_init( &p_sys->event_lock ); /* Create separate thread for main interface */ vlc_sem_init (&p_sys->ready, 0); if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { free (p_sys); return VLC_ENOMEM; } /* Wait for interface thread to be fully initialised */ vlc_sem_wait (&p_sys->ready); vlc_sem_destroy (&p_sys->ready); var_Create (p_this->p_libvlc, "hildon-iface", VLC_VAR_ADDRESS); val.p_address = p_this; var_Set (p_this->p_libvlc, "hildon-iface", val); return VLC_SUCCESS; }
/***************************************************************************** * Public functions *****************************************************************************/ playlist_preparser_t *playlist_preparser_New( vlc_object_t *parent ) { playlist_preparser_t *p_preparser = malloc( sizeof(*p_preparser) ); if( !p_preparser ) return NULL; p_preparser->object = parent; p_preparser->p_fetcher = playlist_fetcher_New( parent ); if( unlikely(p_preparser->p_fetcher == NULL) ) msg_Err( parent, "cannot create fetcher" ); vlc_mutex_init( &p_preparser->lock ); vlc_cond_init( &p_preparser->wait ); vlc_sem_init( &p_preparser->item_done, 0 ); p_preparser->b_live = false; p_preparser->i_waiting = 0; p_preparser->pp_waiting = NULL; return p_preparser; }
static void test_media_subitems_media(libvlc_media_t *media, bool play) { libvlc_media_add_option(media, ":ignore-filetypes= "); bool subitems_found[TEST_SUBITEMS_COUNT] = { 0 }; vlc_sem_t sem; vlc_sem_init (&sem, 0); libvlc_event_manager_t *em = libvlc_media_event_manager (media); libvlc_event_attach (em, libvlc_MediaSubItemTreeAdded, subitem_tree_added, &sem); libvlc_event_attach (em, libvlc_MediaSubItemAdded, subitem_added, subitems_found); if (play) { /* XXX: libvlc_media_parse_async won't work with fd, since it won't be * preparsed because fd:// is an unknown type, so play the file to * force parsing. */ libvlc_media_player_t *mp = libvlc_media_player_new_from_media (media); assert (mp); assert (libvlc_media_player_play (mp) != -1); vlc_sem_wait (&sem); libvlc_media_player_release (mp); } else { libvlc_media_parse_async (media); vlc_sem_wait (&sem); } vlc_sem_destroy (&sem); for (unsigned i = 0; i < TEST_SUBITEMS_COUNT; ++i) { log ("test if %s was added\n", test_media_subitems_list[i].file); assert (subitems_found[i]); } }
static void test_media_preparsed(const char** argv, int argc) { // We use this image file because "empty.voc" has no track. const char * file = SRCDIR"/samples/image.jpg"; log ("Testing set_media\n"); libvlc_instance_t *vlc = libvlc_new (argc, argv); assert (vlc != NULL); libvlc_media_t *media = libvlc_media_new_path (vlc, file); assert (media != NULL); vlc_sem_t sem; vlc_sem_init (&sem, 0); // Check to see if we are properly receiving the event. libvlc_event_manager_t *em = libvlc_media_event_manager (media); libvlc_event_attach (em, libvlc_MediaParsedChanged, preparsed_changed, &sem); // Parse the media. This is synchronous. libvlc_media_parse_async(media); // Wait for preparsed event vlc_sem_wait (&sem); vlc_sem_destroy (&sem); // We are good, now check Elementary Stream info. libvlc_media_track_t **tracks; unsigned nb_tracks = libvlc_media_tracks_get (media, &tracks); assert (nb_tracks == 1); assert (tracks[0]->i_type == libvlc_track_video); libvlc_media_tracks_release (tracks, nb_tracks); libvlc_media_release (media); libvlc_release (vlc); }
static void mediaplayer_play_sync(libvlc_media_player_t *p_mp) { vlc_sem_t sem; vlc_sem_init(&sem, 0); libvlc_event_manager_t *p_em = libvlc_media_player_event_manager(p_mp); libvlc_event_attach(p_em, libvlc_MediaPlayerPlaying, finished_event, &sem); libvlc_event_attach(p_em, libvlc_MediaPlayerEndReached, finished_event, &sem); libvlc_event_attach(p_em, libvlc_MediaPlayerEncounteredError, finished_event, &sem); int i_ret = libvlc_media_player_play(p_mp); assert(i_ret == 0); vlc_sem_wait (&sem); libvlc_event_detach(p_em, libvlc_MediaPlayerPlaying, finished_event, &sem); libvlc_event_detach(p_em, libvlc_MediaPlayerEndReached, finished_event, &sem); libvlc_event_detach(p_em, libvlc_MediaPlayerEncounteredError, finished_event, &sem); libvlc_media_player_stop(p_mp); vlc_sem_destroy (&sem); }
/***************************************************************************** * 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; }
static int OpenDecoder(decoder_t *dec) { int ret = VLC_SUCCESS; decoder_sys_t *sys; MMAL_PARAMETER_UINT32_T extra_buffers; MMAL_STATUS_T status; if (dec->fmt_in.i_cat != VIDEO_ES) return VLC_EGENERIC; if (dec->fmt_in.i_codec != VLC_CODEC_MPGV && dec->fmt_in.i_codec != VLC_CODEC_H264) return VLC_EGENERIC; sys = calloc(1, sizeof(decoder_sys_t)); if (!sys) { ret = VLC_ENOMEM; goto out; } dec->p_sys = sys; dec->b_need_packetized = true; sys->opaque = var_InheritBool(dec, MMAL_OPAQUE_NAME); bcm_host_init(); status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &sys->component); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to create MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)dec; status = mmal_port_enable(sys->component->control, control_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable control port %s (status=%"PRIx32" %s)", sys->component->control->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input = sys->component->input[0]; sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)dec; if (dec->fmt_in.i_codec == VLC_CODEC_MPGV) sys->input->format->encoding = MMAL_ENCODING_MP2V; else sys->input->format->encoding = MMAL_ENCODING_H264; if (dec->fmt_in.i_codec == VLC_CODEC_H264) { if (dec->fmt_in.i_extra > 0) { status = mmal_format_extradata_alloc(sys->input->format, dec->fmt_in.i_extra); if (status == MMAL_SUCCESS) { memcpy(sys->input->format->extradata, dec->fmt_in.p_extra, dec->fmt_in.i_extra); sys->input->format->extradata_size = dec->fmt_in.i_extra; } else { msg_Err(dec, "Failed to allocate extra format data on input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); } } } status = mmal_port_format_commit(sys->input); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to commit format for input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input->buffer_size = sys->input->buffer_size_recommended; sys->input->buffer_num = sys->input->buffer_num_recommended; status = mmal_port_enable(sys->input, input_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output = sys->component->output[0]; sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)dec; if (sys->opaque) { extra_buffers.hdr.id = MMAL_PARAMETER_EXTRA_BUFFERS; extra_buffers.hdr.size = sizeof(MMAL_PARAMETER_UINT32_T); extra_buffers.value = NUM_EXTRA_BUFFERS; status = mmal_port_parameter_set(sys->output, &extra_buffers.hdr); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to set MMAL_PARAMETER_EXTRA_BUFFERS on output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } msg_Dbg(dec, "Activate zero-copy for output port"); MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->output, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->output, output_port_cb); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable output port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_component_enable(sys->component); if (status != MMAL_SUCCESS) { msg_Err(dec, "Failed to enable component %s (status=%"PRIx32" %s)", sys->component->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input_pool = mmal_pool_create(sys->input->buffer_num, 0); sys->decoded_pictures = mmal_queue_create(); if (sys->opaque) { dec->fmt_out.i_codec = VLC_CODEC_MMAL_OPAQUE; dec->fmt_out.video.i_chroma = VLC_CODEC_MMAL_OPAQUE; } else { dec->fmt_out.i_codec = VLC_CODEC_I420; dec->fmt_out.video.i_chroma = VLC_CODEC_I420; } dec->fmt_out.i_cat = VIDEO_ES; dec->pf_decode_video = decode; vlc_mutex_init_recursive(&sys->mutex); vlc_sem_init(&sys->sem, 0); out: if (ret != VLC_SUCCESS) CloseDecoder(dec); return ret; }
static int Open(filter_t *filter) { int32_t frame_duration = filter->fmt_in.video.i_frame_rate != 0 ? (int64_t)1000000 * filter->fmt_in.video.i_frame_rate_base / filter->fmt_in.video.i_frame_rate : 0; bool use_qpu = var_InheritBool(filter, MMAL_DEINTERLACE_QPU); MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = { { MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param) }, MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV, 4, { 3, frame_duration, 0, use_qpu } }; int ret = VLC_SUCCESS; MMAL_STATUS_T status; filter_sys_t *sys; msg_Dbg(filter, "Try to open mmal_deinterlace filter. frame_duration: %d, QPU %s!", frame_duration, use_qpu ? "used" : "unused"); if (filter->fmt_in.video.i_chroma != VLC_CODEC_MMAL_OPAQUE) return VLC_EGENERIC; if (filter->fmt_out.video.i_chroma != VLC_CODEC_MMAL_OPAQUE) return VLC_EGENERIC; sys = calloc(1, sizeof(filter_sys_t)); if (!sys) return VLC_ENOMEM; filter->p_sys = sys; bcm_host_init(); status = mmal_component_create(MMAL_COMPONENT_DEFAULT_DEINTERLACE, &sys->component); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to create MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_port_parameter_set(sys->component->output[0], &imfx_param.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to configure MMAL component %s (status=%"PRIx32" %s)", MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)filter; status = mmal_port_enable(sys->component->control, control_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable control port %s (status=%"PRIx32" %s)", sys->component->control->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input = sys->component->input[0]; sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)filter; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) sys->input->format->encoding = MMAL_ENCODING_OPAQUE; sys->input->format->es->video.width = filter->fmt_in.video.i_width; sys->input->format->es->video.height = filter->fmt_in.video.i_height; sys->input->format->es->video.crop.x = 0; sys->input->format->es->video.crop.y = 0; sys->input->format->es->video.crop.width = filter->fmt_in.video.i_width; sys->input->format->es->video.crop.height = filter->fmt_in.video.i_height; sys->input->format->es->video.par.num = filter->fmt_in.video.i_sar_num; sys->input->format->es->video.par.den = filter->fmt_in.video.i_sar_den; es_format_Copy(&filter->fmt_out, &filter->fmt_in); filter->fmt_out.video.i_frame_rate *= 2; status = mmal_port_format_commit(sys->input); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to commit format for input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->input->buffer_size = sys->input->buffer_size_recommended; sys->input->buffer_num = sys->input->buffer_num_recommended; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) { MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->input, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->input, input_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable input port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output = sys->component->output[0]; sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)filter; mmal_format_full_copy(sys->output->format, sys->input->format); status = mmal_port_format_commit(sys->output); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to commit format for output port %s (status=%"PRIx32" %s)", sys->input->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->output->buffer_num = 3; if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) { MMAL_PARAMETER_UINT32_T extra_buffers = { { MMAL_PARAMETER_EXTRA_BUFFERS, sizeof(MMAL_PARAMETER_UINT32_T) }, 5 }; status = mmal_port_parameter_set(sys->output, &extra_buffers.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to set MMAL_PARAMETER_EXTRA_BUFFERS on output port (status=%"PRIx32" %s)", status, mmal_status_to_string(status)); goto out; } MMAL_PARAMETER_BOOLEAN_T zero_copy = { { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) }, 1 }; status = mmal_port_parameter_set(sys->output, &zero_copy.hdr); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); goto out; } } status = mmal_port_enable(sys->output, output_port_cb); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable output port %s (status=%"PRIx32" %s)", sys->output->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } status = mmal_component_enable(sys->component); if (status != MMAL_SUCCESS) { msg_Err(filter, "Failed to enable component %s (status=%"PRIx32" %s)", sys->component->name, status, mmal_status_to_string(status)); ret = VLC_EGENERIC; goto out; } sys->filtered_pictures = mmal_queue_create(); filter->pf_video_filter = deinterlace; filter->pf_flush = flush; vlc_sem_init(&sys->sem, 0); out: if (ret != VLC_SUCCESS) Close(filter); return ret; }
/* Open Interface */ static int Open( vlc_object_t *p_this, bool isDialogProvider ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; #if defined (QT5_HAS_X11) || defined (Q_WS_X11) if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; Display *p_display = XOpenDisplay( NULL ); if( !p_display ) { msg_Err( p_intf, "Could not connect to X server" ); return VLC_EGENERIC; } XCloseDisplay( p_display ); #endif QMutexLocker locker (&lock); if (busy) { msg_Err (p_this, "cannot start Qt multiple times"); return VLC_EGENERIC; } /* Allocations of p_sys */ intf_sys_t *p_sys = p_intf->p_sys = new intf_sys_t; p_intf->p_sys->b_isDialogProvider = isDialogProvider; p_sys->p_mi = NULL; p_sys->pl_model = NULL; /* set up the playlist to work on */ if( isDialogProvider ) p_intf->p_sys->p_playlist = pl_Get( (intf_thread_t *)p_intf->p_parent ); else p_intf->p_sys->p_playlist = pl_Get( p_intf ); /* */ vlc_sem_init (&ready, 0); #ifdef Q_OS_MAC /* Run mainloop on the main thread as Cocoa requires */ libvlc_SetExitHandler( p_intf->p_libvlc, Abort, p_intf ); Thread( (void *)p_intf ); #else if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { delete p_sys; return VLC_ENOMEM; } #endif /* Wait for the interface to be ready. This prevents the main * LibVLC thread from starting video playback before we can create * an embedded video window. */ vlc_sem_wait (&ready); vlc_sem_destroy (&ready); busy = active = true; #ifndef Q_OS_MAC if( !isDialogProvider ) RegisterIntf( p_intf ); #endif return VLC_SUCCESS; }
/***************************************************************************** * Open: create a handle and open an alsa device ***************************************************************************** * This function opens an alsa device, through the alsa API. * * Note: the only heap-allocated string is psz_device. All the other pointers * are references to psz_device or to stack-allocated data. *****************************************************************************/ static int Open( vlc_object_t *p_this ) { aout_instance_t * p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys; vlc_value_t val; char psz_default_iec_device[128]; /* Buffer used to store the default S/PDIF device */ char * psz_device, * psz_iec_device; /* device names for PCM and S/PDIF output */ int i_vlc_pcm_format; /* Audio format for VLC's data */ int i_snd_pcm_format; /* Audio format for ALSA's data */ snd_pcm_uframes_t i_buffer_size = 0; snd_pcm_uframes_t i_period_size = 0; int i_channels = 0; snd_pcm_hw_params_t *p_hw; snd_pcm_sw_params_t *p_sw; int i_snd_rc = -1; unsigned int i_old_rate; bool b_retry = true; /* Allocate structures */ p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) ); if( p_sys == NULL ) return VLC_ENOMEM; /* Get device name */ if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL ) { msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" ); dialog_Fatal( p_aout, _("No Audio Device"), "%s", _("No audio device name was given. You might want to " \ "enter \"default\".") ); free( p_sys ); return VLC_EGENERIC; } /* Choose the IEC device for S/PDIF output: if the device is overriden by the user then it will be the one otherwise we compute the default device based on the output format. */ if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) && !strcmp( psz_device, DEFAULT_ALSA_DEVICE ) ) { snprintf( psz_default_iec_device, sizeof(psz_default_iec_device), "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO, IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, 0, ( p_aout->output.output.i_rate == 48000 ? IEC958_AES3_CON_FS_48000 : ( p_aout->output.output.i_rate == 44100 ? IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000 ) ) ); psz_iec_device = psz_default_iec_device; } else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) ) { psz_iec_device = psz_device; } else { psz_iec_device = NULL; } /* Choose the linear PCM format (read the comment above about FPU and float32) */ if( HAVE_FPU ) { i_vlc_pcm_format = VLC_CODEC_FL32; i_snd_pcm_format = SND_PCM_FORMAT_FLOAT; } else { i_vlc_pcm_format = VLC_CODEC_S16N; i_snd_pcm_format = SND_PCM_FORMAT_S16; } /* If the variable doesn't exist then it's the first time we're called and we have to probe the available audio formats and channels */ if ( var_Type( p_aout, "audio-device" ) == 0 ) { Probe( p_aout, psz_device, psz_iec_device, &i_snd_pcm_format ); } if ( var_Get( p_aout, "audio-device", &val ) < 0 ) { free( p_sys ); free( psz_device ); return VLC_EGENERIC; } p_aout->output.output.i_format = i_vlc_pcm_format; if ( val.i_int == AOUT_VAR_5_1 ) { p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE; free( psz_device ); psz_device = strdup( "surround51" ); } else if ( val.i_int == AOUT_VAR_2F2R ) { p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; free( psz_device ); psz_device = strdup( "surround40" ); } else if ( val.i_int == AOUT_VAR_STEREO ) { p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } else if ( val.i_int == AOUT_VAR_MONO ) { p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER; } else if( val.i_int != AOUT_VAR_SPDIF ) { /* This should not happen ! */ msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int ); free( p_sys ); free( psz_device ); return VLC_EGENERIC; } #ifdef ALSA_DEBUG snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 ); #endif /* Open the device */ if ( val.i_int == AOUT_VAR_SPDIF ) { if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iec_device, SND_PCM_STREAM_PLAYBACK, 0 ) ) < 0 ) { msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", psz_iec_device, snd_strerror( i_snd_rc ) ); dialog_Fatal( p_aout, _("Audio output failed"), _("VLC could not open the ALSA device \"%s\" (%s)."), psz_iec_device, snd_strerror( i_snd_rc ) ); free( p_sys ); free( psz_device ); return VLC_EGENERIC; } i_buffer_size = ALSA_SPDIF_BUFFER_SIZE; i_snd_pcm_format = SND_PCM_FORMAT_S16; i_channels = 2; i_vlc_pcm_format = VLC_CODEC_SPDIFL; p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE; p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->output.output.i_frame_length = A52_FRAME_NB; aout_VolumeNoneInit( p_aout ); } else { int i; msg_Dbg( p_aout, "opening ALSA device `%s'", psz_device ); /* Since it seems snd_pcm_close hasn't really released the device at the time it returns, probe if the device is available in loop for 1s. We cannot use blocking mode since the we would wait indefinitely when switching from a dmx device to surround51. */ for( i = 10; i >= 0; i-- ) { if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY ) { if( i ) msleep( 100000 /* 100ms */ ); else { msg_Err( p_aout, "audio device: %s is already in use", psz_device ); dialog_Fatal( p_aout, _("Audio output failed"), _("The audio device \"%s\" is already in use."), psz_device ); } continue; } break; } if( i_snd_rc < 0 ) { msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", psz_device, snd_strerror( i_snd_rc ) ); dialog_Fatal( p_aout, _("Audio output failed"), _("VLC could not open the ALSA device \"%s\" (%s)."), psz_device, snd_strerror( i_snd_rc ) ); free( p_sys ); free( psz_device ); return VLC_EGENERIC; } /* We want blocking mode */ snd_pcm_nonblock( p_sys->p_snd_pcm, 0 ); i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE; i_channels = aout_FormatNbChannels( &p_aout->output.output ); p_aout->output.i_nb_samples = i_period_size = ALSA_DEFAULT_PERIOD_SIZE; aout_VolumeSoftInit( p_aout ); } /* Free psz_device so that all the remaining data is stack-allocated */ free( psz_device ); p_aout->output.pf_play = Play; snd_pcm_hw_params_alloca(&p_hw); snd_pcm_sw_params_alloca(&p_sw); /* Due to some bugs in alsa with some drivers, we need to retry in s16l if snd_pcm_hw_params fails in fl32 */ while ( b_retry ) { b_retry = false; /* Get Initial hardware parameters */ if ( ( i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) ) < 0 ) { msg_Err( p_aout, "unable to retrieve initial hardware parameters (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Set format. */ if ( ( i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw, i_snd_pcm_format ) ) < 0 ) { if( i_snd_pcm_format != SND_PCM_FORMAT_S16 ) { i_snd_pcm_format = SND_PCM_FORMAT_S16; i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw, i_snd_pcm_format ); } if ( i_snd_rc < 0 ) { msg_Err( p_aout, "unable to set stream sample size and " "word order (%s)", snd_strerror( i_snd_rc ) ); goto error; } } if( i_vlc_pcm_format != VLC_CODEC_SPDIFL ) switch( i_snd_pcm_format ) { case SND_PCM_FORMAT_FLOAT: i_vlc_pcm_format = VLC_CODEC_FL32; break; case SND_PCM_FORMAT_S16: i_vlc_pcm_format = VLC_CODEC_S16N; break; } p_aout->output.output.i_format = i_vlc_pcm_format; if ( ( i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 ) { msg_Err( p_aout, "unable to set interleaved stream format (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Set channels. */ if ( ( i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw, i_channels ) ) < 0 ) { msg_Err( p_aout, "unable to set number of output channels (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Set rate. */ i_old_rate = p_aout->output.output.i_rate; i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw, &p_aout->output.output.i_rate, NULL ); if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate ) { msg_Warn( p_aout, "The rate %d Hz is not supported by your " \ "hardware. Using %d Hz instead.\n", i_old_rate, \ p_aout->output.output.i_rate ); } /* Set period size. */ if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm, p_hw, &i_period_size, NULL ) ) < 0 ) { msg_Err( p_aout, "unable to set period size (%s)", snd_strerror( i_snd_rc ) ); goto error; } p_aout->output.i_nb_samples = i_period_size; /* Set buffer size. */ if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, p_hw, &i_buffer_size ) ) < 0 ) { msg_Err( p_aout, "unable to set buffer size (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Commit hardware parameters. */ if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 ) { if ( b_retry == false && i_snd_pcm_format == SND_PCM_FORMAT_FLOAT) { b_retry = true; i_snd_pcm_format = SND_PCM_FORMAT_S16; p_aout->output.output.i_format = VLC_CODEC_S16N; msg_Warn( p_aout, "unable to commit hardware configuration " "with fl32 samples. Retrying with s16l (%s)", snd_strerror( i_snd_rc ) ); } else { msg_Err( p_aout, "unable to commit hardware configuration (%s)", snd_strerror( i_snd_rc ) ); goto error; } } } if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw, &p_sys->i_period_time, NULL ) ) < 0 ) { msg_Err( p_aout, "unable to get period time (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Get Initial software parameters */ snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw ); i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 ); i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw, p_aout->output.i_nb_samples ); /* start playing when one period has been written */ i_snd_rc = snd_pcm_sw_params_set_start_threshold( p_sys->p_snd_pcm, p_sw, ALSA_DEFAULT_PERIOD_SIZE); if( i_snd_rc < 0 ) { msg_Err( p_aout, "unable to set start threshold (%s)", snd_strerror( i_snd_rc ) ); goto error; } /* Commit software parameters. */ if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 ) { msg_Err( p_aout, "unable to set software configuration" ); goto error; } #ifdef ALSA_DEBUG snd_output_printf( p_sys->p_snd_stderr, "\nALSA hardware setup:\n\n" ); snd_pcm_dump_hw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr ); snd_output_printf( p_sys->p_snd_stderr, "\nALSA software setup:\n\n" ); snd_pcm_dump_sw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr ); snd_output_printf( p_sys->p_snd_stderr, "\n" ); #endif p_sys->start_date = 0; vlc_sem_init( &p_sys->wait, 0 ); /* Create ALSA thread and wait for its readiness. */ if( vlc_clone( &p_sys->thread, ALSAThread, p_aout, VLC_THREAD_PRIORITY_OUTPUT ) ) { msg_Err( p_aout, "cannot create ALSA thread (%m)" ); vlc_sem_destroy( &p_sys->wait ); goto error; } return 0; error: snd_pcm_close( p_sys->p_snd_pcm ); #ifdef ALSA_DEBUG snd_output_close( p_sys->p_snd_stderr ); #endif free( p_sys ); 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 = CODEC_TYPE_VIDEO; p_context->codec_type = CODEC_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" ); p_sys->p_context->error_recognition = 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_BIDIR; 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_BIDIR; 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->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(); 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 ) { #ifdef HAVE_AVCODEC_MT msg_Err( p_dec, "ffmpeg-hw is not compatible with ffmpeg-mt" ); #else p_sys->p_context->get_format = ffmpeg_GetFormat; #endif } #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; /* 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; } /* ***** 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; }
int main(void) { struct vlc_h2_output *out; /* Dummy */ out = vlc_h2_output_create(NULL, false); assert(out != NULL); vlc_h2_output_destroy(out); vlc_sem_init(&rx, 0); out = vlc_h2_output_create(NULL, expect_hello = true); assert(out != NULL); vlc_h2_output_destroy(out); vlc_sem_destroy(&rx); /* Success */ vlc_sem_init(&rx, 0); out = vlc_h2_output_create(NULL, false); assert(out != NULL); assert(vlc_h2_output_send_prio(out, NULL) == -1); assert(vlc_h2_output_send_prio(out, frame(0)) == 0); assert(vlc_h2_output_send_prio(out, frame(1)) == 0); assert(vlc_h2_output_send(out, NULL) == -1); assert(vlc_h2_output_send(out, frame(2)) == 0); assert(vlc_h2_output_send(out, frame(3)) == 0); assert(vlc_h2_output_send(out, frame_list(frame(4), frame(5), frame(6), NULL)) == 0); assert(vlc_h2_output_send(out, frame(7)) == 0); for (unsigned i = 0; i < 8; i++) vlc_sem_wait(&rx); assert(vlc_h2_output_send_prio(out, frame(8)) == 0); assert(vlc_h2_output_send(out, frame(9)) == 0); vlc_h2_output_destroy(out); vlc_sem_destroy(&rx); /* Failure */ send_failure = true; vlc_sem_init(&rx, 0); counter = 10; out = vlc_h2_output_create(NULL, false); assert(out != NULL); assert(vlc_h2_output_send(out, frame(10)) == 0); for (unsigned char i = 11; vlc_h2_output_send(out, frame(i)) == 0; i++) msleep(CLOCK_FREQ/10); /* eventually, it should start failing */ assert(vlc_h2_output_send(out, frame(0)) == -1); assert(vlc_h2_output_send_prio(out, frame(0)) == -1); vlc_h2_output_destroy(out); vlc_sem_destroy(&rx); /* Failure during hello */ vlc_sem_init(&rx, 0); counter = 0; out = vlc_h2_output_create(NULL, expect_hello = true); assert(out != NULL); vlc_sem_wait(&rx); for (unsigned char i = 1; vlc_h2_output_send_prio(out, frame(i)) == 0; i++) msleep(CLOCK_FREQ/10); assert(vlc_h2_output_send(out, frame(0)) == -1); assert(vlc_h2_output_send_prio(out, frame(0)) == -1); vlc_h2_output_destroy(out); vlc_sem_destroy(&rx); return 0; }