root/core/remotecap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. remotecap_get_target_support
  2. remotecap_get_target
  3. remotecap_set_timeout
  4. remotecap_is_ready
  5. remotecap_set_available_data_type
  6. remotecap_reset
  7. remotecap_set_target
  8. remotecap_using_dng_module
  9. remotecap_wait
  10. remotecap_type_complete
  11. remotecap_raw_available
  12. remotecap_jpeg_available
  13. remotecap_get_data_chunk
  14. remotecap_send_complete

   1 #include "ptp.h"
   2 #include "stdlib.h"
   3 #include "platform.h"
   4 #include "conf.h"
   5 #include "remotecap_core.h"
   6 #include "module_load.h"
   7 #include "modules.h"
   8 #include "raw.h"
   9 #include "cachebit.h"
  10 
  11 #define HOOK_WAIT_MAX_DEFAULT 3000 // timeout for remotecap hooks, in 10ms sleeps = 30 sec
  12 static int hook_wait_max=HOOK_WAIT_MAX_DEFAULT; 
  13 
  14 static int available_image_data=0; // type of data available
  15 
  16 static int pending_image_data=0; // data types requested but not yet transferred in current shot
  17 
  18 static int remote_file_target=0; // requested data types
  19 
  20 static int target_file_num; // file number captured in raw hook
  21 
  22 static ptp_data_chunk raw_chunk;
  23 static ptp_data_chunk dng_hdr_chunk;
  24 
  25 // raw subimage range
  26 static int startline=0;
  27 static int linecount=0;
  28 
  29 #ifdef CAM_HAS_FILEWRITETASK_HOOK
  30 static int jpeg_curr_chunk;
  31 static int jpeg_last_status;
  32 #ifdef CAM_FILEWRITETASK_MULTIPASS
  33 static int jpeg_session_wait; // should the current invocation of the jpeg hook block
  34 #endif //CAM_FILEWRITETASK_MULTIPASS
  35 #endif //CAM_HAS_FILEWRITETASK_HOOK
  36 
  37 
  38 int remotecap_get_target_support(void) {
  39     int ret = (PTP_CHDK_CAPTURE_RAW | PTP_CHDK_CAPTURE_DNGHDR);
  40 #ifdef CAM_HAS_FILEWRITETASK_HOOK
  41     ret |= PTP_CHDK_CAPTURE_JPG;
  42 #endif
  43     return ret;
  44 }
  45 
  46 int remotecap_get_target(void) {
  47     return remote_file_target;
  48 }
  49 
  50 /*
  51 set hook timeout in ms
  52 */
  53 void remotecap_set_timeout(int timeout) 
  54 {
  55     if(timeout <= 0) {
  56         hook_wait_max = HOOK_WAIT_MAX_DEFAULT;
  57     } else {
  58         hook_wait_max = timeout/10;
  59     }
  60 }
  61 
  62 void remotecap_is_ready(int *available_type,int *file_num) {
  63     if ( remotecap_get_target() ) {
  64         *available_type = available_image_data;
  65         if(available_image_data) {
  66             *file_num = target_file_num;
  67         } else {
  68             *file_num = 0;
  69         }
  70     }
  71     else {
  72         *available_type = PTP_CHDK_CAPTURE_NOTSET;
  73         *file_num = 0;
  74     }
  75 }
  76 
  77 // could | in if we supported multiple types available at the same time
  78 static void remotecap_set_available_data_type(int type)
  79 {
  80     available_image_data = type;
  81 }
  82 
  83 // free hooks, reset target and available
  84 static void remotecap_reset(void) {
  85     remote_file_target=0;
  86     remotecap_set_available_data_type(0);
  87     pending_image_data=0;
  88     // TODO do we need remotecap_jpeg_chunks_done() ?
  89 }
  90 
  91 //called to activate or deactive hooks
  92 int remotecap_set_target( int type, int lstart, int lcount )
  93 {
  94     // fail if invalid / unsupported type requested,
  95     // or current mode cannot support requested types
  96     if ((type & ~remotecap_get_target_support()) 
  97         || !camera_info.state.mode_rec
  98         || ((type & PTP_CHDK_CAPTURE_RAW) && !is_raw_possible())
  99 #if defined(CAM_FILEWRITETASK_MULTIPASS) && !defined(CAM_FILEWRITETASK_SEEKS)
 100     // other drive modes do not work on these cams currently
 101         || (shooting_get_drive_mode() != 0)
 102 #endif
 103         ) {
 104         remotecap_reset();
 105         return 0;
 106     }
 107     // clear requested
 108     if(type==0) {
 109         remotecap_reset();
 110         return 1;
 111     }
 112     // invalid range, return error
 113     if(lstart<0 || lstart>CAM_RAW_ROWS-1 || lcount<0 || lcount+lstart>CAM_RAW_ROWS) {
 114         remotecap_reset();
 115         return 0;
 116     }
 117     // default lcount = to end of buffer
 118     if(lcount == 0) {
 119         lcount = CAM_RAW_ROWS - lstart;
 120     }
 121     remote_file_target=type;
 122     startline=lstart;
 123     linecount=lcount;
 124     return 1;
 125 }
 126 
 127 /*
 128 don't allow unloading DNG module if target is DNG
 129 not optimal since it could lead to loading/unloading every shot
 130 could make logic more sophisticated later
 131 */
 132 int remotecap_using_dng_module(void) {
 133     return (remote_file_target & PTP_CHDK_CAPTURE_DNGHDR) != 0;
 134 }
 135 
 136 /*
 137 return 0 if timed out, otherwise non-zero
 138 called from tasks that need to wait for data to be read
 139 */
 140 static int remotecap_wait(int datatype) {
 141     int wait = hook_wait_max;
 142 
 143     remotecap_set_available_data_type(datatype);
 144 
 145     while (wait && (available_image_data & datatype)) {
 146         msleep(10);
 147         wait--;
 148     }
 149     return wait;
 150 }
 151 
 152 // called from filewrite or spytask when type is fully completed
 153 void remotecap_type_complete(int type) {
 154     pending_image_data = (pending_image_data & ~type);
 155 }
 156 
 157 void filewrite_set_discard_jpeg(int state);
 158 int filewrite_get_jpeg_chunk(char **addr,unsigned *size, unsigned n, int *pos);
 159 
 160 void remotecap_raw_available(char *rawadr) {
 161     // get file number as early as possible, before blocking
 162     // but don't set until after so it doesn't change value for remotecap_is_ready
 163     int next_file_num = get_target_file_num(); 
 164 /*
 165 ensure raw hook is blocked until any prevous remotecap shot is finished or times out
 166 if prevous times out, remotecap settings will be cleared due to the time out, so no
 167 remotecap will be done, althouth writes will still be skipped
 168 wait == 0 timeout shouldn't get hit here unless the script is fiddling with the
 169 timeout value, but it ensures that we don't block indefinitely.
 170 */
 171     int wait = hook_wait_max;
 172     while (wait && pending_image_data) {
 173         msleep(10);
 174         wait--;
 175     }
 176     if(wait == 0) {
 177         remotecap_reset();
 178     }
 179     pending_image_data = remote_file_target;
 180     target_file_num = next_file_num;
 181 // TODO technically this could probably wait until after the raw stuff is done,
 182 // provided the actual chunks are transmitted
 183 // TODO this should probably just be noop if hook doesn't exist
 184 #ifdef CAM_HAS_FILEWRITETASK_HOOK
 185     filewrite_set_discard_jpeg(1);
 186     jpeg_curr_chunk=0; //needs to be done here
 187 #endif //CAM_HAS_FILEWRITETASK_HOOK
 188     if (remote_file_target & PTP_CHDK_CAPTURE_DNGHDR) {
 189         started();
 190         libdng->create_dng_header_for_ptp(&dng_hdr_chunk);
 191 
 192         if(!remotecap_wait(PTP_CHDK_CAPTURE_DNGHDR)) {
 193             remotecap_reset();
 194         }
 195         libdng->free_dng_header_for_ptp();
 196         remotecap_type_complete(PTP_CHDK_CAPTURE_DNGHDR);
 197         finished();
 198     }
 199 
 200     if(!(remote_file_target & PTP_CHDK_CAPTURE_RAW)) {
 201         return;
 202     }
 203 
 204     started();
 205     
 206     raw_chunk.address=(unsigned int)ADR_TO_UNCACHED(rawadr+startline*CAM_RAW_ROWPIX*CAM_SENSOR_BITS_PER_PIXEL/8);
 207     raw_chunk.length=linecount*CAM_RAW_ROWPIX*CAM_SENSOR_BITS_PER_PIXEL/8;
 208   
 209     if(!remotecap_wait(PTP_CHDK_CAPTURE_RAW)) {
 210         remotecap_reset();
 211     }
 212     remotecap_type_complete(PTP_CHDK_CAPTURE_RAW);
 213     
 214     finished();
 215 }
 216 
 217 #ifdef CAM_HAS_FILEWRITETASK_HOOK
 218 /*
 219 called from filewrite hook to notify code that jpeg data is available
 220 */
 221 void remotecap_jpeg_available() {
 222     if(!(remote_file_target & PTP_CHDK_CAPTURE_JPG)) {
 223         return;
 224     }
 225 #ifdef CAM_FILEWRITETASK_MULTIPASS
 226     // need custom wait code here to resume if jpeg queue is done
 227     int wait = hook_wait_max;
 228 
 229     jpeg_session_wait = 1;
 230     remotecap_set_available_data_type(PTP_CHDK_CAPTURE_JPG);
 231 
 232     while (wait && jpeg_session_wait && (available_image_data & PTP_CHDK_CAPTURE_JPG)) {
 233         msleep(10);
 234         wait--;
 235     }
 236     if(wait==0) {
 237         remotecap_reset();
 238     }
 239 
 240 #else
 241     if(!remotecap_wait(PTP_CHDK_CAPTURE_JPG)) {
 242         remotecap_reset();
 243     }
 244 #endif
 245 }
 246 #endif
 247 
 248 // called by ptp code to get next chunk address/size for the format (fmt) that is being currently worked on
 249 // returns REMOTECAP_CHUNK_STATUS MORE, ERROR or LAST
 250 int remotecap_get_data_chunk( int fmt, char **addr, unsigned int *size, int *pos )
 251 {
 252     int status = REMOTECAP_CHUNK_STATUS_LAST; // default = no more chunks
 253     *pos = -1; // default = sequential
 254     
 255     switch (fmt & remotecap_get_target() & available_image_data)
 256     {
 257         case PTP_CHDK_CAPTURE_RAW: //raw
 258             *addr=(char*)raw_chunk.address;
 259             *size=raw_chunk.length;
 260             break;
 261 #ifdef CAM_HAS_FILEWRITETASK_HOOK
 262         case PTP_CHDK_CAPTURE_JPG: //jpeg
 263             jpeg_last_status = filewrite_get_jpeg_chunk(addr,size,jpeg_curr_chunk,pos);
 264             jpeg_curr_chunk+=1;
 265             if(jpeg_last_status != REMOTECAP_JPEG_CHUNK_STATUS_LAST) {
 266                 status = REMOTECAP_CHUNK_STATUS_MORE;
 267             }
 268             break;
 269 #endif
 270         case PTP_CHDK_CAPTURE_DNGHDR: // dng header
 271             *addr=(char*)dng_hdr_chunk.address;
 272             *size=dng_hdr_chunk.length;
 273             break;
 274         default:
 275             /*
 276              * attempting to get an unsupported, unavailable or not requested format
 277              * will free all hooks, deactiveate remotecap, and return error status
 278              */
 279             *addr=NULL;
 280             *size=0;
 281     }
 282     if(*addr == NULL) {
 283         remotecap_reset();
 284         status = REMOTECAP_CHUNK_STATUS_ERROR;
 285     }
 286 
 287     return status;
 288 }
 289 
 290 int remotecap_send_complete(int rcgd_status, int type) {
 291     // timeout or canceled: the data type we were sending is no longer available
 292     int timeout_flag = (available_image_data != type);
 293     if(rcgd_status == REMOTECAP_CHUNK_STATUS_LAST) {
 294         // currently only one data type can be available at a time
 295         remotecap_set_available_data_type(0);
 296     }
 297 #ifdef CAM_FILEWRITETASK_MULTIPASS
 298     else if(type == PTP_CHDK_CAPTURE_JPG && jpeg_last_status == REMOTECAP_JPEG_CHUNK_STATUS_SESS_LAST) {
 299         remotecap_jpeg_chunks_done(); // make jpeg_chunks NULL, immediately
 300         jpeg_session_wait = 0;
 301     }
 302 #endif
 303     if((rcgd_status == REMOTECAP_CHUNK_STATUS_ERROR) || timeout_flag) {
 304         return 0;
 305     }
 306     // else more chunks of current type, no action needed
 307     return 1;
 308 }

/* [<][>][^][v][top][bottom][index][help] */