Commit 697be65d authored by Mikhail Karpenko's avatar Mikhail Karpenko

Load appropriate QuickTime template

This commit also fixes a bug with 'exit' command processing
parent df1c1959
...@@ -63,10 +63,6 @@ ...@@ -63,10 +63,6 @@
#define ALL_CHN_INACTIVE 0x00 #define ALL_CHN_INACTIVE 0x00
/** @brief This is a basic helper macro for processing all sensor ports at a time */ /** @brief This is a basic helper macro for processing all sensor ports at a time */
#define FOR_EACH_PORT(indtype, indvar) for (indtype indvar = 0; indvar < SENSOR_PORTS; indvar++) #define FOR_EACH_PORT(indtype, indvar) for (indtype indvar = 0; indvar < SENSOR_PORTS; indvar++)
/** @brief container_of macro as in the kernel */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
char trailer[TRAILER_SIZE] = { 0xff, 0xd9 }; char trailer[TRAILER_SIZE] = { 0xff, 0xd9 };
...@@ -1551,7 +1547,7 @@ int parse_cmd(camogm_state *state, FILE* npipe) ...@@ -1551,7 +1547,7 @@ int parse_cmd(camogm_state *state, FILE* npipe)
return 11; return 11;
} else if (strcmp(cmd, "format") == 0) { } else if (strcmp(cmd, "format") == 0) {
if (args) { if (args) {
if (strcmp(args, "none") == 0) camogm_set_format(state, 0); if (strcmp(args, "none") == 0) camogm_set_format(state, CAMOGM_FORMAT_NONE);
else if ((strcmp(args, "ogm" ) == 0) || (strcmp(args, "ogg") == 0)) camogm_set_format(state, CAMOGM_FORMAT_OGM); else if ((strcmp(args, "ogm" ) == 0) || (strcmp(args, "ogg") == 0)) camogm_set_format(state, CAMOGM_FORMAT_OGM);
else if ((strcmp(args, "jpeg") == 0) || (strcmp(args, "jpg") == 0)) camogm_set_format(state, CAMOGM_FORMAT_JPEG); else if ((strcmp(args, "jpeg") == 0) || (strcmp(args, "jpg") == 0)) camogm_set_format(state, CAMOGM_FORMAT_JPEG);
else if (strcmp(args, "mov" ) == 0) camogm_set_format(state, CAMOGM_FORMAT_MOV); else if (strcmp(args, "mov" ) == 0) camogm_set_format(state, CAMOGM_FORMAT_MOV);
...@@ -1641,8 +1637,19 @@ int parse_cmd(camogm_state *state, FILE* npipe) ...@@ -1641,8 +1637,19 @@ int parse_cmd(camogm_state *state, FILE* npipe)
if ((args) && ((d = strtol(args, NULL, 10)) > 0)) camogm_set_dummy_read(state, d); if ((args) && ((d = strtol(args, NULL, 10)) > 0)) camogm_set_dummy_read(state, d);
return 30; return 30;
} else if (strcmp(cmd, "audio") == 0) { } else if (strcmp(cmd, "audio") == 0) {
if (args) if (args) {
camogm_set_audio_state(state, args); camogm_set_audio_state(state, args);
if (state->format != CAMOGM_FORMAT_NONE) {
/* Some file format initialization functions may depend on the state of audio recording, i.e.
* MOV will load different header template when audio is enabled; thus we need to trigger
* format selector in case the state of audio processing has changed. Here, format is reset
* regardless of its previous state which will trigger format selector when file recording
* starts.
*/
camogm_free(state);
state->format = CAMOGM_FORMAT_NONE;
}
}
return 31; return 31;
} else if (strcmp(cmd, "audio_volume") == 0) { } else if (strcmp(cmd, "audio_volume") == 0) {
if (args) if (args)
......
...@@ -70,6 +70,10 @@ ...@@ -70,6 +70,10 @@
#define COMMAND_LOOP_DELAY 500000 #define COMMAND_LOOP_DELAY 500000
/** @brief File can be split up to this number of chunks */ /** @brief File can be split up to this number of chunks */
#define FILE_CHUNKS_NUM 8 #define FILE_CHUNKS_NUM 8
/** @brief container_of macro as in the kernel */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/** /**
* @enum state_flags * @enum state_flags
......
...@@ -78,7 +78,7 @@ struct audio { ...@@ -78,7 +78,7 @@ struct audio {
int frame_period; ///< video frame period, used to calculate time stamps for audio samples int frame_period; ///< video frame period, used to calculate time stamps for audio samples
void (*get_fpga_time)(const struct audio *audio, struct timeval *tv);//< callback function which can get FPGA time void (*get_fpga_time)(const struct audio *audio, struct timeval *tv);//< callback function which can get FPGA time
int (*write_samples)(void *buff, int len, int slen); ///< callback function which actually write data to file, this must set int (*write_samples)(void *buff, int len, int slen); ///< callback function which actually write data to file, this must be set
///< in the camogm_init_* function when appropriate format is selected ///< in the camogm_init_* function when appropriate format is selected
}; };
......
...@@ -153,7 +153,7 @@ static int save_state_file(const camogm_state *state) ...@@ -153,7 +153,7 @@ static int save_state_file(const camogm_state *state)
/** /**
* @brief Initialize synchronization resources for disk writing thread and then start this thread. This function * @brief Initialize synchronization resources for disk writing thread and then start this thread. This function
* is call each time JPEG format is set or changed, thus we need to check the state of writing thread before * is called each time JPEG format is set or changed, thus we need to check the state of writing thread before
* initialization to prevent spawning multiple threads. * initialization to prevent spawning multiple threads.
* @param[in] state a pointer to a structure containing current state * @param[in] state a pointer to a structure containing current state
* @return 0 if initialization was successful and negative value otherwise * @return 0 if initialization was successful and negative value otherwise
...@@ -202,6 +202,7 @@ int camogm_init_jpeg(camogm_state *state) ...@@ -202,6 +202,7 @@ int camogm_init_jpeg(camogm_state *state)
*/ */
void camogm_free_jpeg(camogm_state *state) void camogm_free_jpeg(camogm_state *state)
{ {
if (state->writer_params.state == STATE_RUNNING) {
pthread_cond_destroy(&state->writer_params.main_cond); pthread_cond_destroy(&state->writer_params.main_cond);
pthread_cond_destroy(&state->writer_params.writer_cond); pthread_cond_destroy(&state->writer_params.writer_cond);
pthread_mutex_destroy(&state->writer_params.writer_mutex); pthread_mutex_destroy(&state->writer_params.writer_mutex);
...@@ -215,6 +216,7 @@ void camogm_free_jpeg(camogm_state *state) ...@@ -215,6 +216,7 @@ void camogm_free_jpeg(camogm_state *state)
state->writer_params.exit_thread = false; state->writer_params.exit_thread = false;
deinit_align_buffers(state); deinit_align_buffers(state);
}
} }
/** Calculate the total length of current frame */ /** Calculate the total length of current frame */
......
...@@ -27,12 +27,13 @@ ...@@ -27,12 +27,13 @@
#include "camogm_mov.h" #include "camogm_mov.h"
/** @brief Quicktime header length (w/o index tables) enough to accommodate static data */ /** @brief QuickTime header length (w/o index tables) enough to accommodate static data */
#define QUICKTIME_MIN_HEADER 0x300 #define QUICKTIME_MIN_HEADER 0x300
// for the parser // for the parser
const char hexStr[] = "0123456789abcdef"; const char hexStr[] = "0123456789abcdef";
const char qtSourceFileName[] = "/etc/qt_source"; const char qt_template_v[] = "/etc/qt_source"; // QuickTime template for video files
const char qt_template_av[] = "/etc/qt_audio"; // QuickTime template for video + audio files
char comStr[1024]; char comStr[1024];
int width = 1280; int width = 1280;
int height = 1024; int height = 1024;
...@@ -78,21 +79,26 @@ int camogm_init_mov(camogm_state *state) ...@@ -78,21 +79,26 @@ int camogm_init_mov(camogm_state *state)
{ {
FILE* qt_header; FILE* qt_header;
int size; int size;
char *qt_template = qt_template_v;
if ((qt_header = fopen(qtSourceFileName, "r")) == NULL) { if (state->audio.audio_enable)
D0(fprintf(debug_file, "Error opening Quicktime header template %s for reading\n", qtSourceFileName)); qt_template = qt_template_av;
if ((qt_header = fopen(qt_template, "r")) == NULL) {
D0(fprintf(debug_file, "Error opening QuickTime header template %s for reading\n", qt_template));
return -CAMOGM_FRAME_FILE_ERR; return -CAMOGM_FRAME_FILE_ERR;
} else {
D5(fprintf(debug_file, "Template file: %s\n", qt_template));
} }
fseek(qt_header, 0, SEEK_END); fseek(qt_header, 0, SEEK_END);
size = ftell(qt_header); size = ftell(qt_header);
if (!((q_template = malloc(size + 1)))) { if (!((q_template = malloc(size + 1)))) {
D0(fprintf(debug_file, "Could not allocate %d bytes of memory for Quicktime header template\n", (size + 1))); D0(fprintf(debug_file, "Could not allocate %d bytes of memory for QuickTime header template\n", (size + 1)));
fclose(qt_header); fclose(qt_header);
return -CAMOGM_FRAME_MALLOC; return -CAMOGM_FRAME_MALLOC;
} }
fseek(qt_header, 0, SEEK_SET); //rewind fseek(qt_header, 0, SEEK_SET); //rewind
if (fread(q_template, size, 1, qt_header) < 1) { if (fread(q_template, size, 1, qt_header) < 1) {
D0(fprintf(debug_file, "Could not read %d bytes of Quicktime header template from %s\n", (size + 1), qtSourceFileName)); D0(fprintf(debug_file, "Could not read %d bytes of QuickTime header template from %s\n", (size + 1), qt_template));
free(q_template); free(q_template);
q_template = NULL; q_template = NULL;
fclose(qt_header); fclose(qt_header);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment