root/platform/generic/filewrite.c

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

DEFINITIONS

This source file includes following definitions.
  1. filewrite_get_file_chunk
  2. filewrite_set_discard_file
  3. filewrite_main_hook
  4. filewrite_file_complete
  5. remotecap_fwt_chunks_done
  6. fwt_open
  7. fwt_write
  8. fwt_lseek
  9. fwt_close
  10. fwt_after_close

   1 #include "stdlib.h" // for NULL
   2 
   3 #include "remotecap_core.h"
   4 static int ignore_current_write=0; //used by the platform routine to check whether to write the current file
   5 #ifdef CAM_DRYOS
   6 static long fwt_bytes_written = 0; // need to track this independently of ptp
   7 volatile int current_write_ignored=0; //needed to prevent nasty surprises with the current override code
   8 #endif //CAM_DRYOS
   9 
  10 /*
  11 handle camera specific MAX_CHUNKS_FOR_FWT, camp_ptp_data_chunk
  12 get address and size of chunk N
  13 returns NULL addr and zero size when max chunks reached
  14 */
  15 static cam_ptp_data_chunk *file_chunks;
  16 #ifdef CAM_FILEWRITETASK_MULTIPASS
  17 static int file_curr_session_chunk;
  18 #ifdef CAM_FILEWRITETASK_SEEKS
  19 static int file_bytes_left;
  20 static int fwt_file_offset;
  21 static int file_full_size;
  22 #else
  23 static int file_last_session;
  24 #endif
  25 #endif
  26 
  27 /*
  28 called by ptp task (via remotecap.c code) to fetch chunks of file data
  29 */
  30 int filewrite_get_file_chunk(char **addr,int *size,unsigned n,int *pos) {
  31     *pos=-1;
  32 #if !defined(CAM_FILEWRITETASK_MULTIPASS)
  33     // TODO null should probably be an error
  34     if (n >= MAX_CHUNKS_FOR_FWT || file_chunks == NULL) {
  35         *addr=(char *)0xFFFFFFFF; // signals last chunk
  36         *size=0;
  37         return REMOTECAP_FWT_CHUNK_STATUS_LAST; // last chunk
  38     }
  39     *addr=(char *)file_chunks[n].address;
  40     *size=file_chunks[n].length;
  41     if (n < MAX_CHUNKS_FOR_FWT-1) {
  42         if (file_chunks[n+1].length==0) {
  43             return REMOTECAP_FWT_CHUNK_STATUS_LAST; // last chunk
  44         }
  45         return REMOTECAP_FWT_CHUNK_STATUS_MORE; // not last chunk
  46     }
  47     return REMOTECAP_FWT_CHUNK_STATUS_LAST; // last chunk
  48 #else
  49     if ( file_chunks == NULL ) { //do we have a valid queue?
  50         int m=50;
  51         while (m>0) { //wait for at most 500ms
  52             _SleepTask(10);
  53             m--;
  54             if ( file_chunks != NULL ) break;
  55         }
  56         if ( file_chunks == NULL ) { //timeout, error
  57             *addr=(char *)0;
  58             *size=0;
  59             return REMOTECAP_FWT_CHUNK_STATUS_LAST;
  60         }
  61     }
  62     *addr=(char *)file_chunks[file_curr_session_chunk].address;
  63     *size=file_chunks[file_curr_session_chunk].length;
  64 #ifdef CAM_FILEWRITETASK_SEEKS
  65     if ( n == 0 ) { // first chunk for this shot
  66         file_bytes_left = file_full_size;
  67     }
  68     file_bytes_left -= *size;
  69     if (file_curr_session_chunk == 0) {
  70         *pos=fwt_file_offset; //only post file offset for the first chunk in the current queue
  71     }
  72 #else
  73     (void)n;
  74     if ((file_curr_session_chunk==0) && (file_last_session)) {
  75         *pos=0; //only post file offset for the first chunk in the last queue
  76     }
  77 #endif
  78     file_curr_session_chunk++;
  79 #ifdef CAM_FILEWRITETASK_SEEKS
  80     if (file_bytes_left>0) {
  81         if ( file_curr_session_chunk < MAX_CHUNKS_FOR_FWT ) {
  82             if (file_chunks[file_curr_session_chunk].length==0) { //last chunk of the current queue
  83                 return REMOTECAP_FWT_CHUNK_STATUS_SESS_LAST;
  84             }
  85             return REMOTECAP_FWT_CHUNK_STATUS_MORE; //not last
  86         }
  87         else {
  88             return REMOTECAP_FWT_CHUNK_STATUS_SESS_LAST;
  89         }
  90     }
  91 #else
  92     if ( file_curr_session_chunk < MAX_CHUNKS_FOR_FWT ) {
  93         if (file_chunks[file_curr_session_chunk].length==0) { //last chunk of the current queue
  94             if (file_last_session) {
  95                 return REMOTECAP_FWT_CHUNK_STATUS_LAST;
  96             }
  97             else {
  98                 return REMOTECAP_FWT_CHUNK_STATUS_SESS_LAST;
  99             }
 100         }
 101         return REMOTECAP_FWT_CHUNK_STATUS_MORE; //not last
 102     }
 103     else {
 104         if (file_last_session) {
 105             return REMOTECAP_FWT_CHUNK_STATUS_LAST;
 106         }
 107         else {
 108             return REMOTECAP_FWT_CHUNK_STATUS_SESS_LAST;
 109         }
 110     }
 111 #endif
 112     return REMOTECAP_FWT_CHUNK_STATUS_LAST; //last
 113 #endif //CAM_FILEWRITETASK_MULTIPASS
 114 }
 115 
 116 void filewrite_set_discard_file(int state) {
 117     ignore_current_write = state;
 118 }
 119 
 120 void filewrite_main_hook(fwt_data_struct *fwt_data)
 121 {
 122 #ifdef CAM_FILEWRITETASK_MULTIPASS
 123     file_curr_session_chunk = 0;
 124 #ifdef CAM_FILEWRITETASK_SEEKS
 125     // don't forget to #define FWT_SEEKMASK, FWT_MUSTSEEK
 126     /*
 127      * below information is only valid when this routine is called
 128      *
 129      * seek flag is at offset 0x50 for DryOS r50
 130      * 2: seek is needed
 131      * if not 2, seek is only performed when file_offset is not 0
 132      *
 133      * seek flag is at offset 0x4c for DryOS r51
 134      * if (seek_flag & 0x40) == 0x40 then seek is needed
 135      * otherwise, seek is only performed when file_offset is not 0
 136      */
 137     if ( ((fwt_data->seek_flag & FWT_SEEKMASK) == FWT_MUSTSEEK) || (fwt_data->file_offset != 0) ) {
 138         fwt_file_offset = fwt_data->file_offset;
 139     }
 140     else {
 141         fwt_file_offset = -1; // no seek needed
 142     }
 143     file_full_size = fwt_data->full_size;
 144 #else
 145     /*
 146      * below information is only valid when this routine is called
 147      *
 148      * we need to watch the file open flags to determine whether the file data arrives in multiple passes
 149      * if the flag isn't there, it's the last (or only) pass
 150      */
 151     if (fwt_data->oflags & OFLAG_NOFLUSH) {
 152         file_last_session = 0;
 153     }
 154     else {
 155         file_last_session = 1;
 156     }
 157 #endif // CAM_FILEWRITETASK_SEEKS
 158 #endif // CAM_FILEWRITETASK_MULTIPASS
 159 
 160     file_chunks = &(fwt_data->pdc[0]);
 161 #ifdef CAM_HAS_CANON_RAW
 162     // for raw enabled cameras, get format from extension
 163     // A/DCIM/100CANON/IMG_1234.CR2
 164     if(strcmp(".CR2",&(fwt_data->name[24])) == 0) {
 165         remotecap_fwt_craw_available();
 166     } else {
 167         remotecap_fwt_jpeg_available();
 168     }
 169 #else
 170     remotecap_fwt_jpeg_available();
 171 #endif
 172     file_chunks=NULL;
 173 }
 174 
 175 // called from filewrite when the hook has returned for the last time for a given file
 176 // to clear ignored write and tell remotecap raw hook it's ok to proceed to next shot
 177 // returns whether the write was ignored, for simpler asm code on the cams that need to switch filename
 178 int filewrite_file_complete(void) {
 179     if(ignore_current_write) {
 180 #ifdef CAM_DRYOS
 181 #ifdef CAM_FILEWRITETASK_SEEKS
 182         if (fwt_bytes_written < file_full_size) {
 183             return 1;
 184         }
 185 #elif defined(CAM_FILEWRITETASK_MULTIPASS)
 186         if (!file_last_session) {
 187             return 1;
 188         }
 189 #endif // CAM_FILEWRITETASK_SEEKS, CAM_FILEWRITETASK_MULTIPASS
 190         current_write_ignored=0;
 191         fwt_bytes_written = 0;
 192 #endif // CAM_DRYOS
 193         remotecap_fwt_file_complete();
 194         return 1;
 195     }
 196     return 0;
 197 }
 198 
 199 #ifdef CAM_FILEWRITETASK_MULTIPASS
 200 void remotecap_fwt_chunks_done() {
 201     file_chunks=NULL;
 202 }
 203 #endif // CAM_FILEWRITETASK_MULTIPASS
 204 
 205 // wrapper functions for use in filewritetask
 206 #ifdef CAM_DRYOS
 207 int fwt_open(const char *name, int flags, int mode) {
 208     if (!ignore_current_write) {
 209         return _Open(name, flags, mode);
 210     }
 211     current_write_ignored=1;
 212     return 255; // fake, invalid file descriptor
 213 }
 214 
 215 int fwt_write(int fd, const void *buffer, long nbytes) {
 216     if (!current_write_ignored) {
 217         return _Write(fd, buffer, nbytes);
 218     }
 219     fwt_bytes_written += nbytes;
 220     return (int)nbytes; // "everything's written"
 221 }
 222 
 223 #ifdef CAM_FILEWRITETASK_SEEKS
 224 int fwt_lseek(int fd, long offset, int whence) {
 225     if (!current_write_ignored) {
 226         return _lseek(fd, offset, whence);
 227     }
 228     return (int)offset; // "file position set to the requested value"
 229 }
 230 #endif // CAM_FILEWRITETASK_SEEKS
 231 
 232 int fwt_close (int fd) {
 233     if (!filewrite_file_complete()) {
 234         int ret = _Close(fd);
 235         //imagesavecomplete=1;
 236         fwt_bytes_written = 0;
 237         return ret;
 238     }
 239     return 0;
 240 }
 241 #else // ifdef CAM_DRYOS
 242 /*
 243  * helper function for VxWorks camera
 244  * to be used when imagesavecomplete handling is needed
 245  */
 246 int fwt_after_close (int param) {
 247 //    imagesavecomplete=1;
 248     return param;
 249 }
 250 #endif //CAM_DRYOS

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