📄 idirectfbvideoprovider_openquicktime.c
字号:
/* store video playback information */ data->dest_rect = dest_rect; data->dest_clip = dest_clip; data->callback = callback; data->ctx = ctx; data->video.yuv = yuv_mode; data->video.playing = 1; /* start audio playback thread */ if (data->audio.thread == -1 && data->audio.available) { if (OpenSound( data ) == DFB_OK) { pthread_mutex_lock( &data->audio.lock ); data->audio.playing = 1; pthread_create( &data->audio.thread, NULL, AudioThread, data ); pthread_mutex_unlock( &data->audio.lock ); } } /* start video playback thread */ if (data->video.thread == -1) pthread_create( &data->video.thread, NULL, VideoThread, data ); pthread_mutex_unlock( &data->video.lock ); return DFB_OK;}static DFBResultIDirectFBVideoProvider_OpenQuicktime_Stop( IDirectFBVideoProvider *thiz ){ INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) pthread_mutex_lock( &data->video.lock ); pthread_mutex_lock( &data->audio.lock ); /* stop audio thread and close device */ if (data->audio.thread != -1) { data->audio.playing = 0; pthread_mutex_unlock( &data->audio.lock ); pthread_join( data->audio.thread, NULL ); pthread_mutex_lock( &data->audio.lock ); data->audio.thread = -1; CloseSound( data ); } /* stop video thread */ if (data->video.thread != -1) { data->video.playing = 0; pthread_mutex_unlock( &data->video.lock ); pthread_join( data->video.thread, NULL ); pthread_mutex_lock( &data->video.lock ); data->video.thread = -1; } /* release destination surface */ if (data->destination) { data->destination->Release( data->destination ); data->destination = NULL; /* FIXME: remove listener */ } pthread_mutex_unlock( &data->audio.lock ); pthread_mutex_unlock( &data->video.lock ); return DFB_OK;}static DFBResult IDirectFBVideoProvider_OpenQuicktime_SeekTo( IDirectFBVideoProvider *thiz, double seconds ){ long new_pos, old_pos, audio_pos; INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) pthread_mutex_lock( &data->video.lock ); pthread_mutex_lock( &data->audio.lock ); /* calculate new and old video position */ new_pos = (long) (data->video.rate * seconds); old_pos = quicktime_video_position( data->file, 0 ); /* nothing to do? */ if (new_pos == old_pos) { pthread_mutex_unlock( &data->audio.lock ); pthread_mutex_unlock( &data->video.lock ); return DFB_OK; } /* find next/prev keyframe */ if (new_pos < old_pos) new_pos = quicktime_get_keyframe_before( data->file, new_pos, 0 ); else new_pos = quicktime_get_keyframe_after( data->file, new_pos, 0 ); if (new_pos >= data->video.length) { new_pos = 0; } /* calculate new audio position */ audio_pos = (long) ((double)new_pos * (double)data->audio.rate / (double)data->video.rate); /* seek audio */ quicktime_set_audio_position( data->file, audio_pos, 0 ); data->audio.seeked = 1; pthread_mutex_unlock( &data->audio.lock ); /* seek video */ quicktime_set_video_position( data->file, new_pos, 0 ); data->video.seeked = 1; pthread_mutex_unlock( &data->video.lock ); return DFB_OK;}static DFBResult IDirectFBVideoProvider_OpenQuicktime_GetPos( IDirectFBVideoProvider *thiz, double *seconds ){ INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) pthread_mutex_lock( &data->video.lock ); *seconds = quicktime_video_position( data->file, 0 ) / data->video.rate; pthread_mutex_unlock( &data->video.lock ); return DFB_OK;}static DFBResult IDirectFBVideoProvider_OpenQuicktime_GetLength( IDirectFBVideoProvider *thiz, double *seconds ){ INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) *seconds = data->video.length / data->video.rate; return DFB_OK;}static DFBResult IDirectFBVideoProvider_OpenQuicktime_GetColorAdjustment( IDirectFBVideoProvider *thiz, DFBColorAdjustment *adj ){ INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) return DFB_UNSUPPORTED;}static DFBResult IDirectFBVideoProvider_OpenQuicktime_SetColorAdjustment( IDirectFBVideoProvider *thiz, DFBColorAdjustment *adj ){ INTERFACE_GET_DATA (IDirectFBVideoProvider_OpenQuicktime) return DFB_UNSUPPORTED;}/* exported symbols */static DFBResultProbe( const char *filename ){ quicktime_t *q;#ifdef SEGFAULTS_IN_OPENQUICKTIME if (!quicktime_check_sig( (char *) filename )) return DFB_UNSUPPORTED;#endif q = quicktime_open( (char*) filename, 1, 0 ); if (!q) return DFB_UNSUPPORTED; if (!quicktime_has_video( q )) { ERRORMSG( "OpenQuicktime Provider: " "File doesn't contain a video track!\n" ); quicktime_close( q ); return DFB_UNSUPPORTED; } if (!quicktime_supported_video( q, 0 )) { ERRORMSG( "OpenQuicktime Provider: " "Video Codec not supported by OpenQuicktime!\n" ); quicktime_close( q ); return DFB_UNSUPPORTED; } if (!quicktime_reads_cmodel( q, BC_RGB888, 0 ) && !quicktime_reads_cmodel( q, BC_YUV420P, 0 )) { ERRORMSG( "OpenQuicktime Provider: Only codecs reading " "RGB888 and/or YUV420P are supported yet!\n" ); quicktime_close( q ); return DFB_UNSUPPORTED; } quicktime_close( q ); return DFB_OK;}static DFBResultConstruct( IDirectFBVideoProvider *thiz, const char *filename ){ int i; IDirectFBVideoProvider_OpenQuicktime_data *data; /* allocate private data */ data = (IDirectFBVideoProvider_OpenQuicktime_data *) DFBCALLOC( 1, sizeof(IDirectFBVideoProvider_OpenQuicktime_data) ); thiz->priv = data; /* initialize private data */ data->ref = 1; data->filename = DFBSTRDUP( filename ); data->video.thread = -1; data->audio.thread = -1; pthread_mutex_init( &data->video.lock, NULL ); pthread_mutex_init( &data->audio.lock, NULL ); /* open quicktime file */ data->file = quicktime_open( data->filename, 1, 0 ); /* fetch information about video */ data->video.width = quicktime_video_width( data->file, 0 ); data->video.height = quicktime_video_height( data->file, 0 ); data->video.rate = quicktime_frame_rate( data->file, 0 ); data->video.length = quicktime_video_length( data->file, 0 ); /* check codec format support */ data->yuv.supported = quicktime_reads_cmodel( data->file, BC_YUV420P, 0 ); data->rgb.supported = quicktime_reads_cmodel( data->file, BC_RGB888, 0 ); /* allocate video decoding buffer */ data->video.buffer = DFBMALLOC( data->video.height * data->video.width * 4 ); data->rgb.lines = DFBMALLOC( data->video.height * sizeof(unsigned char*) ); for (i=0; i<data->video.height; i++) data->rgb.lines[i] = data->video.buffer + data->video.width * 4 * i; data->yuv.lines[0] = data->video.buffer; data->yuv.lines[1] = data->video.buffer + data->video.width * data->video.height; data->yuv.lines[2] = data->video.buffer + data->video.width * data->video.height * 5 / 4; /* setup audio playback */ if (quicktime_has_audio( data->file )) { data->audio.available = 1; data->audio.bits = quicktime_audio_bits( data->file, 0 ); data->audio.channels = quicktime_track_channels( data->file, 0 ); data->audio.rate = quicktime_sample_rate( data->file, 0 ); data->audio.length = quicktime_audio_length( data->file, 0 ); } /* initialize function pointers */ thiz->AddRef = IDirectFBVideoProvider_OpenQuicktime_AddRef; thiz->Release = IDirectFBVideoProvider_OpenQuicktime_Release; thiz->GetCapabilities = IDirectFBVideoProvider_OpenQuicktime_GetCapabilities; thiz->GetSurfaceDescription = IDirectFBVideoProvider_OpenQuicktime_GetSurfaceDescription; thiz->PlayTo = IDirectFBVideoProvider_OpenQuicktime_PlayTo; thiz->Stop = IDirectFBVideoProvider_OpenQuicktime_Stop; thiz->SeekTo = IDirectFBVideoProvider_OpenQuicktime_SeekTo; thiz->GetPos = IDirectFBVideoProvider_OpenQuicktime_GetPos; thiz->GetLength = IDirectFBVideoProvider_OpenQuicktime_GetLength; thiz->GetColorAdjustment = IDirectFBVideoProvider_OpenQuicktime_GetColorAdjustment; thiz->SetColorAdjustment = IDirectFBVideoProvider_OpenQuicktime_SetColorAdjustment; return DFB_OK;}/* OSS sound support */static DFBResultOpenSound( IDirectFBVideoProvider_OpenQuicktime_data *data ){ int fd; int prof = APF_NORMAL; int bits = data->audio.bits; int bytes = (bits + 7) / 8; int stereo = (data->audio.channels > 1) ? 1 : 0; int rate = data->audio.rate; /* open audio device */ fd = open( "/dev/dsp", O_WRONLY ); if (fd < 0) { PERRORMSG( "OpenQuicktime Provider: Opening '/dev/dsp' failed!\n" ); return DFB_IO; } /* set application profile */ ioctl( fd, SNDCTL_DSP_PROFILE, &prof ); /* set bits per sample */ ioctl( fd, SNDCTL_DSP_SAMPLESIZE, &bits ); if (bits != data->audio.bits) { ERRORMSG( "OpenQuicktime Provider: " "Unable to set audio bits to '%d'!\n", data->audio.bits ); close( fd ); return DFB_UNSUPPORTED; } /* set mono/stereo */ if (ioctl( fd, SNDCTL_DSP_STEREO, &stereo ) == -1) { ERRORMSG( "OpenQuicktime Provider: Unable to set '%s' mode!\n", (data->audio.channels > 1) ? "stereo" : "mono"); close( fd ); return DFB_UNSUPPORTED; } /* set sample rate */ if (ioctl( fd, SNDCTL_DSP_SPEED, &rate ) == -1) { ERRORMSG( "OpenQuicktime Provider: " "Unable to set sample rate to '%ld'!\n", data->audio.rate ); close( fd ); return DFB_UNSUPPORTED; } /* query block size */ ioctl( fd, SNDCTL_DSP_GETBLKSIZE, &data->audio.block_size ); if (data->audio.block_size < 1) { ERRORMSG( "OpenQuicktime Provider: " "Unable to query block size of '/dev/dsp'!\n" ); close( fd ); return DFB_UNSUPPORTED; } /* calculate number of samples fitting into block for each channel */ data->audio.samples_per_block = data->audio.block_size / bytes / data->audio.channels; /* store file descriptor */ data->audio.fd = fd; return DFB_OK;}static DFBResultCloseSound( IDirectFBVideoProvider_OpenQuicktime_data *data ){ /* flush pending sound data so we don't have to wait */ ioctl( data->audio.fd, SNDCTL_DSP_RESET, 0 ); /* close audio device */ close( data->audio.fd ); return DFB_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -