diff options
-rw-r--r-- | libhb/hb.c | 27 | ||||
-rw-r--r-- | libhb/internal.h | 4 | ||||
-rw-r--r-- | libhb/ports.c | 71 | ||||
-rw-r--r-- | libhb/ports.h | 8 | ||||
-rw-r--r-- | libhb/work.c | 22 |
5 files changed, 122 insertions, 10 deletions
diff --git a/libhb/hb.c b/libhb/hb.c index 43c5baa3c..5d96f0b82 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -64,7 +64,10 @@ struct hb_handle_s on multi-pass encodes where frames get dropped. */ hb_interjob_t * interjob; -}; + // Power Management opaque pointer + // For OSX, it's an IOPMAssertionID* + void * hb_system_sleep_opaque; +} ; hb_work_object_t * hb_objects = NULL; int hb_instance_counter = 0; @@ -407,6 +410,9 @@ hb_handle_t * hb_init( int verbose, int update_check ) /* Check for an update on the website if asked to */ h->build = -1; + /* Initialize opaque for PowerManagement purposes */ + h->hb_system_sleep_opaque = hb_system_sleep_opaque_init(); + if( update_check ) { hb_log( "hb_init: checking for updates" ); @@ -511,6 +517,9 @@ hb_handle_t * hb_init_dl( int verbose, int update_check ) /* Check for an update on the website if asked to */ h->build = -1; + /* Initialize opaque for PowerManagement purposes */ + h->hb_system_sleep_opaque = hb_system_sleep_opaque_init(); + if( update_check ) { hb_log( "hb_init: checking for updates" ); @@ -1542,7 +1551,7 @@ void hb_start( hb_handle_t * h ) h->paused = 0; h->work_die = 0; - h->work_thread = hb_work_init( h->jobs, &h->work_die, &h->work_error, &h->current_job ); + h->work_thread = hb_work_init( h, h->jobs, &h->work_die, &h->work_error, &h->current_job ); } /** @@ -1561,6 +1570,8 @@ void hb_pause( hb_handle_t * h ) hb_lock( h->state_lock ); h->state.state = HB_STATE_PAUSED; hb_unlock( h->state_lock ); + + hb_allow_sleep( h ); } } @@ -1572,6 +1583,8 @@ void hb_resume( hb_handle_t * h ) { if( h->paused ) { + hb_prevent_sleep( h ); + #define job hb_current_job( h ) if( job->st_pause_date != -1 ) { @@ -1877,6 +1890,16 @@ void hb_set_state( hb_handle_t * h, hb_state_t * s ) hb_unlock( h->pause_lock ); } +void hb_prevent_sleep( hb_handle_t * h ) +{ + hb_system_sleep_prevent( h->hb_system_sleep_opaque ); +} + +void hb_allow_sleep( hb_handle_t * h ) +{ + hb_system_sleep_allow( h->hb_system_sleep_opaque ); +} + /* Passes a pointer to persistent data */ hb_interjob_t * hb_interjob_get( hb_handle_t * h ) { diff --git a/libhb/internal.h b/libhb/internal.h index 81cc8680f..8bf9fa533 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -39,6 +39,8 @@ void hb_title_close( hb_title_t ** ); **********************************************************************/ int hb_get_pid( hb_handle_t * ); void hb_set_state( hb_handle_t *, hb_state_t * ); +void hb_prevent_sleep( hb_handle_t * ); +void hb_allow_sleep( hb_handle_t * ); /*********************************************************************** * fifo.c @@ -229,7 +231,7 @@ hb_thread_t * hb_scan_init( hb_handle_t *, volatile int * die, const char * path, int title_index, hb_title_set_t * title_set, int preview_count, int store_previews, uint64_t min_duration ); -hb_thread_t * hb_work_init( hb_list_t * jobs, +hb_thread_t * hb_work_init( hb_handle_t * handle, hb_list_t * jobs, volatile int * die, int * error, hb_job_t ** job ); void ReadLoop( void * _w ); hb_work_object_t * hb_muxer_init( hb_job_t * ); diff --git a/libhb/ports.c b/libhb/ports.c index f10c9d96c..11952c052 100644 --- a/libhb/ports.c +++ b/libhb/ports.c @@ -66,6 +66,10 @@ #include <sys/ioctl.h> #endif +#ifdef __APPLE__ +#include <IOKit/pwr_mgt/IOPMLib.h> +#endif + #include <stddef.h> #include <unistd.h> @@ -781,3 +785,70 @@ char *strtok_r(char *s, const char *delim, char **save_ptr) return token; } #endif + +/************************************************************************ +* OS Sleep Allow / Prevent +***********************************************************************/ + +#ifdef __APPLE__ +// 128 chars limit for IOPMAssertionCreateWithName +static CFStringRef reasonForActivity= CFSTR("HandBrake is currently scanning and/or encoding"); +#endif + +void* hb_system_sleep_opaque_init() +{ + void* opaque; +#ifdef __APPLE__ + opaque = calloc( sizeof( IOPMAssertionID ), 1); + IOPMAssertionID * assertionID = (IOPMAssertionID *)opaque; + *assertionID = -1; +#endif + + return opaque; +} + +void hb_system_sleep_opaque_close(void **_opaque) +{ +#ifdef __APPLE__ + IOPMAssertionID * assertionID = (IOPMAssertionID *) *_opaque; + free( assertionID ); +#endif + *_opaque = NULL; +} + +void hb_system_sleep_allow(void *opaque) +{ +#ifdef __APPLE__ + IOPMAssertionID * assertionID = (IOPMAssertionID *)opaque; + + if (*assertionID == -1) + return; + + IOReturn success = IOPMAssertionRelease(*assertionID); + + if (success == kIOReturnSuccess) { + hb_deep_log( 3, "osxsleep: IOPM assertion %d successfully released, sleep allowed", *assertionID ); + *assertionID = -1; + } else { + hb_log( "osxsleep: error while trying to unset power management assertion" ); + } +#endif +} + +void hb_system_sleep_prevent(void *opaque) +{ +#ifdef __APPLE__ + IOPMAssertionID * assertionID = (IOPMAssertionID *)opaque; + + if (*assertionID != -1) + return; + + IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, + kIOPMAssertionLevelOn, reasonForActivity, assertionID); + if (success == kIOReturnSuccess) { + hb_deep_log( 3, "IOPM assertion %d successfully created, prevent sleep", *assertionID); + } else { + hb_log( "osxsleep: error while trying to set power management assertion" ); + } +#endif +} diff --git a/libhb/ports.h b/libhb/ports.h index 23879fcb1..9f7da2b14 100644 --- a/libhb/ports.h +++ b/libhb/ports.h @@ -102,6 +102,14 @@ int hb_net_send( hb_net_t *, char * ); int hb_net_recv( hb_net_t *, char *, int ); void hb_net_close( hb_net_t ** ); +/************************************************************************ +* OS Sleep Allow / Prevent +***********************************************************************/ +void * hb_system_sleep_opaque_init(); +void hb_system_sleep_opaque_close( void ** opaque ); +void hb_system_sleep_allow( void * opaque ); +void hb_system_sleep_prevent( void * opaque ); + #endif /* __LIBHB__ */ #endif diff --git a/libhb/work.c b/libhb/work.c index 19389bf11..9ee2b0593 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -13,9 +13,10 @@ typedef struct { - hb_list_t * jobs; - hb_job_t ** current_job; - int * error; + hb_handle_t * handle; + hb_list_t * jobs; + hb_job_t ** current_job; + int * error; volatile int * die; } hb_work_t; @@ -40,14 +41,15 @@ static void filter_loop( void * ); * @param die Handle to user inititated exit indicator. * @param error Handle to error indicator. */ -hb_thread_t * hb_work_init( hb_list_t * jobs, volatile int * die, int * error, hb_job_t ** job ) +hb_thread_t * hb_work_init( hb_handle_t * handle, hb_list_t * jobs, volatile int * die, int * error, hb_job_t ** job ) { hb_work_t * work = calloc( sizeof( hb_work_t ), 1 ); - work->jobs = jobs; + work->handle = handle; + work->jobs = jobs; work->current_job = job; - work->die = die; - work->error = error; + work->die = die; + work->error = error; return hb_thread_init( "work", work_func, work, HB_LOW_PRIORITY ); } @@ -81,16 +83,22 @@ static void work_func( void * _work ) hb_log( "%d job(s) to process", hb_list_count( work->jobs ) ); + hb_prevent_sleep( work->handle ); + while( !*work->die && ( job = hb_list_item( work->jobs, 0 ) ) ) { hb_list_rem( work->jobs, job ); job->die = work->die; *(work->current_job) = job; + InitWorkState( job->h ); do_job( job ); + *(work->current_job) = NULL; } + hb_allow_sleep( work->handle ); + *(work->error) = HB_ERROR_NONE; free( work ); |