Commit c4ada33f authored by Mikhail Karpenko's avatar Mikhail Karpenko

Update doxygen documentation

parent cb60ae2d
/** @file camogm_jpeg.c /** @file camogm_jpeg.c
* @brief Provides writing to series of individual JPEG files for camogm * @brief Provides writing to series of individual JPEG files for @e camogm
* @copyright Copyright (C) 2016 Elphel, Inc. * @copyright Copyright (C) 2016 Elphel, Inc.
* *
* @par <b>License</b> * @par <b>License</b>
......
/** @file camogm_jpeg.h /** @file camogm_jpeg.h
* @brief Provides writing to series of individual JPEG files for camogm * @brief Provides writing to series of individual JPEG files for @e camogm
* @copyright Copyright (C) 2016 Elphel, Inc. * @copyright Copyright (C) 2016 Elphel, Inc.
* *
* @par <b>License</b> * @par <b>License</b>
......
This diff is collapsed.
/** @file camogm_kml.h
* @brief Provides writing to series of individual KML files for @e camogm
* @copyright Copyright (C) 2016 Elphel, Inc.
*
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CAMOGM_KML_H #ifndef _CAMOGM_KML_H
#define _CAMOGM_KML_H #define _CAMOGM_KML_H
......
This diff is collapsed.
/** @file camogm_mov.h
* @brief Provides writing to file compatible with Apple Quicktime(R) for @e camogm
* @copyright Copyright (C) 2016 Elphel, Inc.
*
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CAMOGM_MOV_H #ifndef _CAMOGM_MOV_H
#define _CAMOG_MOV_H #define _CAMOG_MOV_H
......
/*!*************************************************************************** /** @file camogm_ogm.c
*! FILE NAME : camogm_ogm.c * @brief Provides writing to OGM files for @e camogm
*! DESCRIPTION: Provides writing to ogm files for camogm * @copyright Copyright (C) 2016 Elphel, Inc.
*! Copyright (C) 2007 Elphel, Inc. *
*! -----------------------------------------------------------------------------** * @par <b>License</b>
*! This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version. * (at your option) any later version.
*! * This program is distributed in the hope that it will be useful,
*! This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
*! but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
*! GNU General Public License for more details. * You should have received a copy of the GNU General Public License
*! * along with this program. If not, see <http://www.gnu.org/licenses/>.
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*!
*! $Log: camogm_ogm.c,v $
*! Revision 1.2 2009/02/25 17:50:02 spectr_rain
*! removed deprecated dependency
*!
*! Revision 1.1.1.1 2008/11/27 20:04:01 elphel
*!
*!
*! Revision 1.2 2007/11/19 03:23:21 elphel
*! 7.1.5.5 Added support for *.mov files in camogm.
*!
*! Revision 1.1 2007/11/16 08:49:58 elphel
*! Initial release of camogm - program to record video/image to the camera hard drive (or other storage)
*!
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -40,15 +24,23 @@ ...@@ -40,15 +24,23 @@
#include "camogm_ogm.h" #include "camogm_ogm.h"
//! may add something - called first time format is changed to this one (only once) recording is stopped /**
* @brief Called when format is changed to OGM (only once) and recording is stopped
*/
int camogm_init_ogm(void) int camogm_init_ogm(void)
{ {
return 0; return 0;
} }
void camogm_free_ogm(void) void camogm_free_ogm(void)
{ {
} }
/**
* @brief Start OGM recording
* @param[in] state a pointer to a structure containing current state
* @return 0 if recording started successfully and negative error code otherwise
*/
int camogm_start_ogm(camogm_state *state) int camogm_start_ogm(camogm_state *state)
{ {
char vendor[] = "ElphelOgm v 0.1"; char vendor[] = "ElphelOgm v 0.1";
...@@ -68,19 +60,16 @@ int camogm_start_ogm(camogm_state *state) ...@@ -68,19 +60,16 @@ int camogm_start_ogm(camogm_state *state)
memcpy(sh.streamtype, "video", 5); memcpy(sh.streamtype, "video", 5);
memcpy(sh.subtype, "MJPG", 4); memcpy(sh.subtype, "MJPG", 4);
put_uint32(&sh.size, sizeof(sh)); put_uint32(&sh.size, sizeof(sh));
// put_uint64(&sh.time_unit, (ogg_int64_t) 10*state->frame_period);
put_uint64(&sh.time_unit, state->time_unit); put_uint64(&sh.time_unit, state->time_unit);
// put_uint64(&sh.samples_per_unit, 1);
put_uint64(&sh.samples_per_unit, (ogg_int64_t)state->timescale); put_uint64(&sh.samples_per_unit, (ogg_int64_t)state->timescale);
put_uint32(&sh.default_len, 1); put_uint32(&sh.default_len, 1);
put_uint32(&sh.buffersize, state->width * state->height); put_uint32(&sh.buffersize, state->width * state->height);
// put_uint16(&sh.bits_per_sample, 24); //? put_uint16(&sh.bits_per_sample, 0);
put_uint16(&sh.bits_per_sample, 0); //?
put_uint32(&sh.sh.video.width, state->width); put_uint32(&sh.sh.video.width, state->width);
put_uint32(&sh.sh.video.height, state->height); put_uint32(&sh.sh.video.height, state->height);
memcpy(&hdbuf[1], &sh, sizeof(sh)); memcpy(&hdbuf[1], &sh, sizeof(sh));
hdbuf[0] = 1; hdbuf[0] = 1;
//! put it into Ogg stream // put it into Ogg stream
ogg_header.packet = hdbuf; ogg_header.packet = hdbuf;
ogg_header.bytes = sizeof(sh) + 1; ogg_header.bytes = sizeof(sh) + 1;
ogg_header.b_o_s = 1; ogg_header.b_o_s = 1;
...@@ -89,7 +78,7 @@ int camogm_start_ogm(camogm_state *state) ...@@ -89,7 +78,7 @@ int camogm_start_ogm(camogm_state *state)
ogg_header.granulepos = 0; ogg_header.granulepos = 0;
ogg_stream_packetin(&(state->os), &ogg_header); ogg_stream_packetin(&(state->os), &ogg_header);
// while(ogg_stream_pageout(&(state->os), &(state->og))) { // while(ogg_stream_pageout(&(state->os), &(state->og))) {
while (ogg_stream_flush(&(state->os), &(state->og))) { while (ogg_stream_flush(&(state->os), &(state->og))) {
int i, j; int i, j;
if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) || if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
...@@ -100,8 +89,8 @@ int camogm_start_ogm(camogm_state *state) ...@@ -100,8 +89,8 @@ int camogm_start_ogm(camogm_state *state)
} }
} }
//!create comment // create comment
//!use fixed minimal one - hdbuf will be enough for that // use fixed minimal one - hdbuf will be enough for that
memset(hdbuf, 0, sizeof(hdbuf)); memset(hdbuf, 0, sizeof(hdbuf));
hdbuf[0] = PACKET_TYPE_COMMENT; hdbuf[0] = PACKET_TYPE_COMMENT;
memcpy(&hdbuf[1], "vorbis", 6); memcpy(&hdbuf[1], "vorbis", 6);
...@@ -113,7 +102,7 @@ int camogm_start_ogm(camogm_state *state) ...@@ -113,7 +102,7 @@ int camogm_start_ogm(camogm_state *state)
put_uint32(&hdbuf[pos], 0); put_uint32(&hdbuf[pos], 0);
pos += 4; pos += 4;
hdbuf[pos++] = 1; hdbuf[pos++] = 1;
//! put it into Ogg stream // put it into Ogg stream
ogg_header.packet = (unsigned char *)hdbuf; ogg_header.packet = (unsigned char *)hdbuf;
ogg_header.bytes = pos; ogg_header.bytes = pos;
ogg_header.b_o_s = 0; ogg_header.b_o_s = 0;
...@@ -121,35 +110,25 @@ int camogm_start_ogm(camogm_state *state) ...@@ -121,35 +110,25 @@ int camogm_start_ogm(camogm_state *state)
ogg_header.packetno = state->packetno++;; ogg_header.packetno = state->packetno++;;
ogg_header.granulepos = 0; ogg_header.granulepos = 0;
ogg_stream_packetin(&(state->os), &ogg_header); ogg_stream_packetin(&(state->os), &ogg_header);
/* // calculate initial absolute granulepos (from 1970), then increment with each frame. Later try calculating granulepos of each frame
while(ogg_stream_pageout(&(state->os), &(state->og))) { // from the absolute time (actual timestamp)
int i, j;
if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
(state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
j=errno;
D(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
return -CAMOGM_FRAME_FILE_ERR;
}
}
*/
//! calculate initial absolute granulepos (from 1970), then increment with each frame. Later try calculating granulepos of each frame
//! from the absolute time (actual timestamp)
state->granulepos = (ogg_int64_t)( (((double)state->frame_params[state->port_num].timestamp_usec) + state->granulepos = (ogg_int64_t)( (((double)state->frame_params[state->port_num].timestamp_usec) +
(((double)1000000) * ((double)state->frame_params[state->port_num].timestamp_sec))) * (((double)1000000) * ((double)state->frame_params[state->port_num].timestamp_sec))) *
((double)10) / ((double)10) /
((double)state->time_unit) * ((double)state->time_unit) *
((double)state->timescale)); ((double)state->timescale));
// state->frame_period=(state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec)+ // temporarily setting granulepos to 0 (suspect they do not process correctly 64 bits)
// 1000000*(state->this_frame_params.timestamp_sec - state->frame_params.timestamp_sec);
// put_uint64(&sh.time_unit, (ogg_int64_t)((double)10000000.0 / (double)fps));
//!Temporarily setting granulepos to 0 (suspect they do not process correctly 64 bits)
state->granulepos = 0; state->granulepos = 0;
//! Here - Ogg stream started, both header and comment packets are sent out, next should be just data packets // Here - Ogg stream started, both header and comment packets are sent out, next should be just data packets
return 0; return 0;
} }
/**
* @brief Write a frame to file
* @param[in] state a pointer to a structure containing current state
* @return 0 if frame was saved successfully and negative error code otherwise
*/
int camogm_frame_ogm(camogm_state *state) int camogm_frame_ogm(camogm_state *state)
{ {
int indx; int indx;
...@@ -158,8 +137,8 @@ int camogm_frame_ogm(camogm_state *state) ...@@ -158,8 +137,8 @@ int camogm_frame_ogm(camogm_state *state)
elp_packet.bytes = 0; elp_packet.bytes = 0;
for (indx = 0; indx < state->chunk_index; indx++) elp_packet.bytes += state->packetchunks[indx].bytes; for (indx = 0; indx < state->chunk_index; indx++) elp_packet.bytes += state->packetchunks[indx].bytes;
elp_packet.packet = state->packetchunks; elp_packet.packet = state->packetchunks;
//D(fprintf (debug_file,"elp_packet.bytes=0x%lx: elp_packet.packet=%p\n",elp_packet.bytes, elp_packet.packet)); //D(fprintf (debug_file,"elp_packet.bytes=0x%lx: elp_packet.packet=%p\n",elp_packet.bytes, elp_packet.packet));
/*D(fprintf (debug_file,"0:0x%lx: %p\n" \ /*D(fprintf (debug_file,"0:0x%lx: %p\n" \
"1:0x%lx: %p\n" \ "1:0x%lx: %p\n" \
"2:0x%lx: %p\n" \ "2:0x%lx: %p\n" \
"3:0x%lx: %p\n" \ "3:0x%lx: %p\n" \
...@@ -177,15 +156,13 @@ int camogm_frame_ogm(camogm_state *state) ...@@ -177,15 +156,13 @@ int camogm_frame_ogm(camogm_state *state)
elp_packet.b_o_s = 0; elp_packet.b_o_s = 0;
elp_packet.e_o_s = 0; elp_packet.e_o_s = 0;
elp_packet.packetno = state->packetno++;; elp_packet.packetno = state->packetno++;;
// tts[0]=state->frame_params.timestamp_usec;
// tts[1]=state->frame_params.timestamp_sec;
elp_packet.granulepos = state->granulepos; elp_packet.granulepos = state->granulepos;
//!TODO: If that works, calculate granulepos from timestamp for each frame /// @todo If that works, calculate granulepos from timestamp for each frame
state->granulepos += (ogg_int64_t)state->timescale; state->granulepos += (ogg_int64_t)state->timescale;
//D3(fprintf (debug_file,"_121_")); //D3(fprintf (debug_file,"_121_"));
ogg_stream_packetin_elph(&(state->os), &elp_packet); ogg_stream_packetin_elph(&(state->os), &elp_packet);
//D3(fprintf (debug_file,"_13_")); //D3(fprintf (debug_file,"_13_"));
while (ogg_stream_pageout(&(state->os), &(state->og))) { while (ogg_stream_pageout(&(state->os), &(state->og))) {
int i, j; int i, j;
if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) || if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
...@@ -198,11 +175,15 @@ int camogm_frame_ogm(camogm_state *state) ...@@ -198,11 +175,15 @@ int camogm_frame_ogm(camogm_state *state)
return 0; return 0;
} }
//!Zero packets are OK, use them to end file with "last" turned on /**
* @brief Finish OGM file operation
* @param[in] state a pointer to a structure containing current state
* @return 0 if file was saved successfully and negative error code otherwise
* @note: zero packets are OK, use them to end file with "last" turned on
*/
int camogm_end_ogm(camogm_state *state) int camogm_end_ogm(camogm_state *state)
{ {
//! put zero-packet it into stream // put zero-packet it into stream
ogg_packet ogg_header; ogg_packet ogg_header;
ogg_header.packet = NULL; ogg_header.packet = NULL;
...@@ -211,7 +192,7 @@ int camogm_end_ogm(camogm_state *state) ...@@ -211,7 +192,7 @@ int camogm_end_ogm(camogm_state *state)
ogg_header.e_o_s = 1; ogg_header.e_o_s = 1;
ogg_header.packetno = state->packetno++; ogg_header.packetno = state->packetno++;
ogg_header.granulepos = ++(state->granulepos); ogg_header.granulepos = ++(state->granulepos);
ogg_stream_packetin(&(state->os), &ogg_header); //!+++++++++++++++++++++++++++++++++++++++++++++++++++++ ogg_stream_packetin(&(state->os), &ogg_header); // +++++++++++++++++++++++++++++++++++++++++++++++++++++
while (ogg_stream_flush(&(state->os), &(state->og))) { while (ogg_stream_flush(&(state->os), &(state->og))) {
int i, j; int i, j;
if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) || if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
......
/** @file camogm_ogm.h
* @brief Provides writing to OGM files for @e camogm
* @copyright Copyright (C) 2016 Elphel, Inc.
*
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CAMOGM_OGM_H #ifndef _CAMOGM_OGM_H
#define _CAMOGM_OGM_H #define _CAMOGM_OGM_H
......
...@@ -305,6 +305,18 @@ static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, ...@@ -305,6 +305,18 @@ static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz,
return ret; return ret;
} }
/**
* @brief Find pattern in a data buffer in reverse order
*
* This function searches for the first occurrence of pattern in a data buffer and returns a pointer to
* the position of this pattern in the buffer.
* @param[in] buff_ptr pointer to an array of char values where the pattern should be found
* @param[in] buff_sz size of the data array
* @param[in] pattern pointer to an array of char values containing pattern
* @param[in] pt_sz size of the pattern array
* @param[in] add_pattern include or exclude marker from resulting buffer offset
* @return The index in data buffer where pattern matches or error code from #match_result if it was not found
*/
static int find_marker_backward(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz, static int find_marker_backward(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz,
int add_pattern) int add_pattern)
{ {
......
...@@ -63,6 +63,12 @@ int add_node(struct disk_idir *idir, struct disk_index *index) ...@@ -63,6 +63,12 @@ int add_node(struct disk_idir *idir, struct disk_index *index)
return idir->size; return idir->size;
} }
/**
* @brief Insert new node in chronological order
* @param[in,out] idir index directory to which a new node should be added
* @param[in] indx a pointer to new node
* @return The number of nodes in the directory
*/
int insert_node(struct disk_idir *idir, struct disk_index *indx) int insert_node(struct disk_idir *idir, struct disk_index *indx)
{ {
int ret = 0; int ret = 0;
...@@ -157,6 +163,11 @@ struct disk_index *find_by_offset(const struct disk_idir *idir, uint64_t offset) ...@@ -157,6 +163,11 @@ struct disk_index *find_by_offset(const struct disk_idir *idir, uint64_t offset)
return index; return index;
} }
/** @brief Find index node by its time stamp
* @param[in] idir pointer to disk index directory
* @param[in] time the time stamp of the file which should be found
* @return pointer to disk index node or NULL if the corresponding file was not found
*/
struct disk_index *find_nearest_by_time(const struct disk_idir *idir, time_t time) struct disk_index *find_nearest_by_time(const struct disk_idir *idir, time_t time)
{ {
struct disk_index *ptr = NULL; struct disk_index *ptr = NULL;
......
/** @file ogmstreams.h */
#ifndef __OGGSTREAMS_H #ifndef __OGGSTREAMS_H
#define __OGGSTREAMS_H #define __OGGSTREAMS_H
/* /**
* Taken from http://tobias.everwicked.com/packfmt.htm * Taken from http://tobias.everwicked.com/packfmt.htm
* *
First packet (header)
---------------------
pos | content | description
-------+-------------------------+----------------------------------
0x0000 | 0x01 | indicates 'header packet'
-------+-------------------------+----------------------------------
0x0001 | stream_header | the size is indicated in the
| | size member
Second packet (comment)
-----------------------
pos | content | description
-------+-------------------------+----------------------------------
0x0000 | 0x03 | indicates 'comment packet'
-------+-------------------------+----------------------------------
0x0001 | data | see vorbis doc on www.xiph.org
Data packets
------------
pos | content | description
---------+-------------------------+----------------------------------
0x0000 | Bit0 0 | indicates data packet
| Bit1 Bit 2 of lenbytes |
| Bit2 unused |
| Bit3 keyframe |
| Bit4 unused |
| Bit5 unused |
| Bit6 Bit 0 of lenbytes |
| Bit7 Bit 1 of lenbytes |
---------+-------------------------+----------------------------------
0x0001 | LowByte | Length of this packet in samples
| ... | (frames for video, samples for
| HighByte | audio, 1ms units for text)
---------+-------------------------+----------------------------------
0x0001+ | data | packet contents
lenbytes | |
* *
* First packet (header)
* ---------------------
*
* pos | content | description
* -------|-------------------------|----------------------------------
* 0x0000 | 0x01 | indicates 'header packet'
* 0x0001 | stream_header | the size is indicated in the
* &nbsp; | &nbsp; | size member
*
*
* Second packet (comment)
* -----------------------
*
* pos | content | description
* -------|-------------------------|----------------------------------
* 0x0000 | 0x03 | indicates 'comment packet'
* 0x0001 | data | see vorbis doc on www.xiph.org
*
*
* Data packets
* ------------
*
* pos | content | description
* ---------|-------------------------|----------------------------------
* 0x0000 | Bit0 0 | indicates data packet
* &nbsp; | Bit1 Bit 2 of lenbytes | &nbsp;
* &nbsp; | Bit2 unused | &nbsp;
* &nbsp; | Bit3 keyframe | &nbsp;
* &nbsp; | Bit4 unused | &nbsp;
* &nbsp; | Bit5 unused | &nbsp;
* &nbsp; | Bit6 Bit 0 of lenbytes | &nbsp;
* &nbsp; | Bit7 Bit 1 of lenbytes | &nbsp;
* 0x0001 | LowByte | Length of this packet in samples
* &nbsp; | ... | (frames for video, samples for
* &nbsp; | HighByte | audio, 1ms units for text)
* 0x0001+ | data | packet contents
* lenbytes | &nbsp; | &nbsp;
* *
*/ */
//// OggDS headers /** OggDS headers */
// Header for the new header format /** Header for the new header format */
typedef struct stream_header_video { typedef struct stream_header_video {
ogg_int32_t width; ogg_int32_t width;
ogg_int32_t height; ogg_int32_t height;
......
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