[NUT-devel] [nut]: r259 - in trunk/libnut: Doxyfile libnut.h

ods15 subversion at mplayerhq.hu
Tue Nov 21 17:37:53 CET 2006


Author: ods15
Date: Tue Nov 21 17:37:51 2006
New Revision: 259

Added:
   trunk/libnut/Doxyfile
Modified:
   trunk/libnut/libnut.h

Log:
Add LOTS of doxygen comments to libnut.h, and plenty doxygen tags...
reorganize some of libnut.h a bit, and change some defines to enums


Added: trunk/libnut/Doxyfile
==============================================================================
--- (empty file)
+++ trunk/libnut/Doxyfile	Tue Nov 21 17:37:51 2006
@@ -0,0 +1,22 @@
+PROJECT_NAME           = libnut
+OUTPUT_DIRECTORY       = doxygen
+CREATE_SUBDIRS         = NO
+REPEAT_BRIEF           = YES
+DETAILS_AT_TOP         = YES
+OPTIMIZE_OUTPUT_FOR_C  = YES
+EXTRACT_ALL            = NO
+SORT_MEMBER_DOCS       = NO
+SHOW_USED_FILES        = NO
+QUIET                  = YES
+WARN_IF_DOC_ERROR      = YES
+INPUT                  = libnut.h
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+VERBATIM_HEADERS       = NO
+ALPHABETICAL_INDEX     = NO
+GENERATE_HTML          = YES
+GENERATE_LATEX         = NO
+MAX_INITIALIZER_LINES  = 30
+ENUM_VALUES_PER_LINE   = 1

Modified: trunk/libnut/libnut.h
==============================================================================
--- trunk/libnut/libnut.h	(original)
+++ trunk/libnut/libnut.h	Tue Nov 21 17:37:51 2006
@@ -4,125 +4,197 @@
 #ifndef _NUT_H
 #define _NUT_H
 
-#define NUT_VERSION 2
+/// \defgroup common  Common Defines and Enums
+/// \defgroup muxer   libnut Muxer
+/// \defgroup demuxer libnut Demuxer
+
+/// \addtogroup common
+/// @{
+#define NUT_VERSION 2 ///< Version of NUT specification this library implements
+
+enum nut_stream_class_t {
+	NUT_VIDEO_CLASS    = 0, ///< = 0
+	NUT_AUDIO_CLASS    = 1, ///< = 1
+	NUT_SUBTITLE_CLASS = 2, ///< = 2
+	NUT_USERDATA_CLASS = 3, ///< = 3
+};
 
-#define NUT_VIDEO_CLASS    0
-#define NUT_AUDIO_CLASS    1
-#define NUT_SUBTITLE_CLASS 2
-#define NUT_USERDATA_CLASS 3
-
-#define NUT_FLAG_KEY 1
-#define NUT_FLAG_EOR 2
-
-typedef struct {
-	void * priv;
-	size_t (*read)(void * priv, size_t len, uint8_t * buf);
-	off_t (*seek)(void * priv, long long pos, int whence); // can be NULL, but implies no read_index and no cache_syncpoints
-	int (*eof)(void * priv); // can be NULL, implies any read error is caused by EOF
-	off_t file_pos;
-} nut_input_stream_t;
+/// Frame flags bitfield (several flags may be set at once)
+enum nut_frame_flags_t {
+	NUT_FLAG_KEY = 1,  ///< Marks frame as keyframe
+	NUT_FLAG_EOR = 2,  ///< Marks end of relavence for stream. #NUT_FLAG_KEY \b must be set together with this flag.
+};
+/// @}
+
+typedef struct nut_context_s nut_context_t;
+
+/// \ingroup demuxer muxer
+/// @{
 
+/// Memory allocation function pointers
 typedef struct {
-	void * priv;
-	int (*write)(void * priv, size_t len, const uint8_t * buf);
-} nut_output_stream_t;
+	void * (*malloc)(size_t size);             ///< Memory allocation malloc function pointer
+	void * (*realloc)(void *ptr, size_t size); ///< Memory allocation realloc function pointer
+	void (*free)(void *ptr);                   ///< Memory allocation free function pointer
+} nut_alloc_t;
 
-typedef struct { // for example 23.976 (24000/1001)
-	int nom; // is 1001
-	int den; // 24000
+/// Timebase struct
+typedef struct {
+	int nom; ///< Example: 1001
+	int den; ///< Example: 24000
 } nut_timebase_t;
 
+/// Stream header struct
 typedef struct {
-	int type; // -1 means end
-	int fourcc_len;
-	uint8_t * fourcc;
-	nut_timebase_t time_base;
-	int fixed_fps;
-	int decode_delay;
-	int codec_specific_len;
-	uint8_t * codec_specific;
-	// video
-	int width;
-	int height;
-	int sample_width;
-	int sample_height;
+	int type;                 ///< Possible values are enum ::nut_stream_class_t. Value of -1 terminates a stream header array
+	int fourcc_len;           ///< Length of fourcc
+	uint8_t * fourcc;         ///< fourcc in big-endian format
+	nut_timebase_t time_base; ///< Timebase of stream
+	int fixed_fps;            ///< Flag if stream is fixed fps or not
+	int decode_delay;         ///< Decode delay of codec in this stream
+	int codec_specific_len;   ///< Length of codec specific data
+	uint8_t * codec_specific; ///< Codec specific data. May be NULL is #codec_specific_len is zero.
+	uint64_t max_pts;         ///< Only used in demuxer. If non-zero, then it is the highest value in stream
+
+	/// \name Video
+	/// Only used is type is #NUT_VIDEO_CLASS @{
+	int width;                ///< Width of video in pixels
+	int height;               ///< Height of video in pixels
+	int sample_width;         ///< Ratio to stretch the video. May only be zero if #sample_height is zero
+	int sample_height;        ///< Ratio to stretch the video. May only be zero if #sample_width is zero
 	int colorspace_type;
-	// audio
-	int samplerate_nom;
-	int samplerate_denom;
-	int channel_count;
-	// does not need to be set, only read
-	int max_pts;
+	/// @}
+
+	/// \name audio
+	/// Only used is type is #NUT_AUDIO_CLASS @{
+	int samplerate_nom;       ///< Sample rate of audio. Example: 44100
+	int samplerate_denom;     ///< Sample rate denominator of audio. Example: 1
+	int channel_count;        ///< Amount of audio channels
+	/// @}
 } nut_stream_header_t;
 
+/// Single info field struct
 typedef struct {
-	int flag; // -1 => end
-	int pts;
-	int stream;
-	int mul;
-	int size;
-	int count;
-} nut_frame_table_input_t;
+	char type[7];      ///< NULL-terminated string. "v"=integer value, "s"=signed integer value, "r"=fraction rational, "t"=timestamp
+	char name[65];     ///< NULL-terminated string. Name of info field
+	int64_t val;       ///< used in types "v", "s", "r", "t", and is the length of #data in bytes in other types.
+	int den;           ///< used in type=="r", #val is the numerator.
+	nut_timebase_t tb; ///< used in type=="t". This is the timebase, and #val is the timestamp in this timebase.
+	uint8_t * data;    ///< Value of binary data. \b Must be NULL if carries no data. \note This data is not NULL terminated!
+} nut_info_field_t;
 
+/// Single info packet struct
 typedef struct {
-	void * (*malloc)(size_t size);
-	void * (*realloc)(void *ptr, size_t size);
-	void (*free)(void *ptr);
-} nut_alloc_t;
+	int count;                 ///< -1 terminates the nut_info_packet_t array
+	int stream_id_plus1;       ///< Zero indicates non-stream-specific info packet
+	int chapter_id;            ///< Zero indicates info packet applies to complete file. Positive values are real, non-overlapping chapters. Negative values may overlap
+	nut_timebase_t chapter_tb; ///< Timebase of #chapter_start and #chapter_len
+	uint64_t chapter_start;    ///< Start of chapter or complete file
+	uint64_t chapter_len;      ///< Length of chapter or complete file
+	nut_info_field_t * fields; ///< Info fields, has #count elements
+} nut_info_packet_t;
 
+/// Single frame packet struct
 typedef struct {
-	char type[7];
-	char name[65];
-	int64_t val; // used in all types, is the length of data if there is data
-	int den; // used in type=="r"
-	nut_timebase_t tb; // used in type=="t"
-	uint8_t * data; // must be NULL if carries no data
-} nut_info_field_t;
+	int len;          ///< Length of frame in bytes. \b Must be zero if #NUT_FLAG_EOR is set.
+	int stream;       ///< Stream index of frame
+	uint64_t pts;     ///< Presentation timestamp of frame
+	int flags;        ///< Frame flags from #nut_frame_flags_t
+	int64_t next_pts; ///< Only used in muxer. Only necessary if nut_write_frame_reorder() is used.
+} nut_packet_t;
+/// @}
 
+
+
+/*****************************************
+ * Muxer                                 *
+ *****************************************/
+
+/// \addtogroup muxer
+/// @{
+
+/// Output stream struct
 typedef struct {
-	int count; // count=-1 terminates the nut_info_packet_t array
-	int stream_id_plus1;
-	int chapter_id;
-	nut_timebase_t chapter_tb;
-	uint64_t chapter_start;
-	uint64_t chapter_len;
-	nut_info_field_t * fields;
-} nut_info_packet_t;
+	void * priv;                                                ///< Opaque priv pointer to be given to function calls
+	int (*write)(void * priv, size_t len, const uint8_t * buf); ///< If NULL, nut_output_stream_t::priv is used as FILE*
+} nut_output_stream_t;
 
+/// NUT Framecode table input
 typedef struct {
-	int len;
-	int stream;
-	uint64_t pts;
-	int flags; // 1 - keyframe, 2 - EOR
-	// not manditory, for reorderer muxer
-	int64_t next_pts;
-} nut_packet_t;
+	int flag;   ///< Flags of framecode entry.
+	int pts;    ///< pts delta from previous frame
+	int stream; ///< stream_id of frame
+	int mul;    ///< Multiplier for coded frame size
+	int size;   ///< LSB for coded frame size
+	int count;  ///< Explicit count of framecode entry, \b should be (mul-size) in almost all cases.
+} nut_frame_table_input_t;
 
+/// Muxer options struct
 typedef struct {
-	nut_output_stream_t output;
-	nut_alloc_t alloc;
-	int write_index;
-	int realtime_stream; // implies no write_index
-	int max_distance;
-	nut_frame_table_input_t * fti;
+	nut_output_stream_t output;    ///< Output stream function pointers
+	nut_alloc_t alloc;             ///< Memory allocation function pointers
+	int write_index;               ///< Writes index at end-of-file
+	int realtime_stream;           ///< Implies no write_index
+	int max_distance;              ///< Valid values from 32-65536. Recommended value is 32768. Lower values give better seekability and error detection and recovery but cause higher overhead.
+	nut_frame_table_input_t * fti; ///< Framecode table. May be NULL.
 } nut_muxer_opts_t;
 
+/// Allocates NUT muxer context and writes headers to file
+nut_context_t * nut_muxer_init(const nut_muxer_opts_t * mopts, const nut_stream_header_t s[], const nut_info_packet_t info[]);
+
+/// Deallocates NUT muxer context
+void nut_muxer_uninit(nut_context_t * nut);
+
+/// Writes a single frame to NUT file
+void nut_write_frame(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf);
+
+/// Write a single info packet to NUT file
+void nut_write_info(nut_context_t * nut, const nut_info_packet_t * info);
+
+/// Buffers and sorts a single frame to be written NUT file
+void nut_write_frame_reorder(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf);
+
+/// Flushes reorder buffer and deallocates NUT muxer context
+void nut_muxer_uninit_reorder(nut_context_t * nut);
+
+/// Creates an optimized framecode table for NUT main header based on stream info
+void nut_framecode_generate(const nut_stream_header_t s[], nut_frame_table_input_t fti[256]);
+/// @}
+
+
+
+/*****************************************
+ * Demuxer                               *
+ *****************************************/
+
+/// \addtogroup demuxer
+/// @{
+
+/// Input stream struct
 typedef struct {
-	nut_input_stream_t input;
-	nut_alloc_t alloc;
-	int read_index; // implies cache_syncpoints
-	int cache_syncpoints;
-	void * info_priv;
-	void (*new_info)(void * priv, nut_info_packet_t * info);
-} nut_demuxer_opts_t;
+	void * priv;                                            ///< Opaque priv pointer to be given to function calls
+	size_t (*read)(void * priv, size_t len, uint8_t * buf); ///< Input stream read function. Must return amount of bytes actually read.
+	off_t (*seek)(void * priv, long long pos, int whence);  ///< Input stream seek function. Must return position in file after seek.
+	int (*eof)(void * priv);                                ///< Returns if EOF has been met in stream in case of read error.
+	off_t file_pos;                                         ///< File position at begginning of read.
+} nut_input_stream_t;
 
-typedef struct nut_context_s nut_context_t;
+/// Demuxer options struct
+typedef struct {
+	nut_input_stream_t input;  ///< Input stream function pointers
+	nut_alloc_t alloc;         ///< Memory allocation function pointers
+	int read_index;            ///< Seeks to end-of-file at begginning of playback to search for index. Implies cache_syncpoints
+	int cache_syncpoints;      ///< Improoves seekability and error recovery greatly, but costs some memory (0.5mb for very large files).
+	void * info_priv;          ///< Opaque priv pointer to be given to #new_info
+	void (*new_info)(void * priv, nut_info_packet_t * info); ///< Function to be called when info is found mid-stream. May be NULL.
+} nut_demuxer_opts_t;
 
 enum nut_errors {
-	NUT_ERR_NO_ERROR = 0,
-	NUT_ERR_EOF = 1,
-	NUT_ERR_EAGAIN = 2,
-	NUT_ERR_OUT_OF_MEM = 3, // these first 3 errors are "fatal" errors, the rest are simple stream corruption
+	NUT_ERR_NO_ERROR      = 0,    ///< = 0
+	NUT_ERR_EOF           = 1,    ///< = 1
+	NUT_ERR_EAGAIN        = 2,    ///< = 2
+	NUT_ERR_OUT_OF_MEM    = 3,    ///< = 3
+	NUT_ERR_NOT_SEEKABLE,         ///< Can only be returned by nut_seek(). Indicates that the seek was not successful.
 	NUT_ERR_GENERAL_ERROR,
 	NUT_ERR_BAD_VERSION,
 	NUT_ERR_NOT_FRAME_NOT_N,
@@ -130,7 +202,6 @@
 	NUT_ERR_MAX_SYNCPOINT_DISTANCE,
 	NUT_ERR_MAX_DISTANCE,
 	NUT_ERR_NO_HEADERS,
-	NUT_ERR_NOT_SEEKABLE,
 	NUT_ERR_OUT_OF_ORDER,
 	NUT_ERR_MAX_PTS_DISTANCE,
 	NUT_ERR_VLC_TOO_LONG,
@@ -139,78 +210,308 @@
 	NUT_ERR_BAD_EOF,
 };
 
-// Muxer
-
-/** allocs nut context, writes headers to file */
-nut_context_t * nut_muxer_init(const nut_muxer_opts_t * mopts, const nut_stream_header_t s[], const nut_info_packet_t info[]);
-/** writes index (optionally), frees alloced ram */
-void nut_muxer_uninit(nut_context_t * nut);
-
-/** nut_write_frame does magic, it writes headers */
-void nut_write_frame(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf);
-/** the use of this function is illegal in non realtime streams!! */
-void nut_write_info(nut_context_t * nut, const nut_info_packet_t * info);
-
-/** do the same as the above function, but deal with frame reordering */
-void nut_write_frame_reorder(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf);
-void nut_muxer_uninit_reorder(nut_context_t * nut);
-
-/** generate framecode table input for the muxer. the fallback for the muxer if the muxer option is NULL */
-void nut_framecode_generate(const nut_stream_header_t s[], nut_frame_table_input_t fti[256]);
-
-// Demuxer
-
-/** Just inits stuff, can never fail, except memory error... */
+/// Creates a NUT demuxer context. Does not read any information from file
 nut_context_t * nut_demuxer_init(nut_demuxer_opts_t * dopts);
-/** Just frees stuff. */
+
+/// Frees a NUT demuxer context. No other functions can be called after this
 void nut_demuxer_uninit(nut_context_t * nut);
 
-/**
-All of the following functions return:
-0 success
-1 unexpected or expected EOF.
-2 EAGAIN.
-other: error, detailed error in nut_error(ret);
-
-All errors except EAGAIN or ERR_NOT_SEEKABLE from nut_seek are fatal.
-The only legal operation after a fatal error is nut_demuxer_uninit().
-
-After an EAGAIN, whichever function returned it should always be
-re-called with same params when data is available.
-*/
-
-/** Read headers, must be called at begginning
-Both `s' and `info' are handeled by context, and are illegal pointers
-after nut_demuxer_uninit() . If `info' is NULL, no info is read.
-*/
+/// Read headers and index, \b must be called at begginning
 int nut_read_headers(nut_context_t * nut, nut_stream_header_t * s [], nut_info_packet_t * info []);
 
-/** Gives information on next frame, must be called before each packet. */
+/// Gets frame header, must be called before each packet
 int nut_read_next_packet(nut_context_t * nut, nut_packet_t * pd);
 
-/** Just reads the frame DATA. all it's header has already been
-read by nut_read_next_packet. buf must be allocated and big enough.
-len will be non-zero in the case of EAGAIN or EOF
-len is the amount of bytes that are LEFT, not the ones read.
-example:
-len = pd.len;
-while((err = nut_read_frame(nut, &len, buf+pd.len-len)) == NUT_ERR_EAGAIN);
-*/
+/// Just reads the frame \b data, not the header
 int nut_read_frame(nut_context_t * nut, int * len, uint8_t * buf);
 
-/** "Can't find start code" "invalid frame code" "bad checksum" "bleh" */
+/// Gives human readable description of the error return code of any demuxing function
 const char * nut_error(int error);
 
-/** Seeks to requested position in seconds
-if (flags & 1), time_pos is relative to current position, otherwise absoloute.
-if (flags & 2), the seek should go forwards when seeking, and find
-                the nearest keyframe after target pts.
-                No percise seeking is preformed.
-if it returns (non fatal) error, no seek is preformed.
-After nut_seek, nut_read_next_packet should be called to get the next frame.
-active_streams is a -1 terminated list of all streams that are active...
-if NULL, all streams are active.
-*/
+/// Seeks to requested position in seconds
 int nut_seek(nut_context_t * nut, double time_pos, int flags, const int * active_streams);
+/// @}
+
+
+
+/*****************************************
+ * Extended Doxygen Documentation        *
+ *****************************************/
+
+/*! \mainpage libnut Documentation
+ * \author Oded Shimon <ods15 at ods15.dyndns.org>
+ * \date 2005-2006
+ *
+ * Reference implementation for NUT open container format.
+ *
+ * libnut source code can be downloaded from svn://svn.mplayerhq.hu/nut
+ *
+ * Copyright of this library is MIT/X license. For more details, see the
+ * file COPYING in the repository.
+ *
+ * For more information on the format, please visit http://www.nut.hu
+ */
+
+/*! \struct nut_alloc_t
+ * libc semantics are assumed to all functions. (realloc must work with NULL or zero size)
+ *
+ * #malloc function pointer may be NULL. This indicates using libc malloc, realloc and free functions.
+ *
+ * If #malloc is not NULL, #realloc and #free \b must \b not be NULL.
+ */
+
+/*! \struct nut_timebase_t
+ * The example shown is if fps is 23.976 (24000/1001). Timebase is the opposite of fps.
+ */
+
+/*!
+ * \var int nut_frame_table_input_t::flag
+ *
+ * This variable is a bitfield. Valid flags are:
+ * -    1  FLAG_KEYFRAME
+ * -    2  FLAG_EOR
+ * -    8  FLAG_CODED_PTS
+ * -   16  FLAG_CODED_STREAM_ID
+ * -   32  FLAG_SIZE_MSB
+ * -   64  FLAG_CHECKSUM
+ * -  128  FLAG_RESERVED
+ * - 4096  FLAG_CODED
+ * - 8192  FLAG_INVALID
+ *
+ * Last entry of frame table \b must have flag==-1.
+ */
+
+/*! \fn nut_context_t * nut_muxer_init(const nut_muxer_opts_t * mopts, const nut_stream_header_t s[], const nut_info_packet_t info[])
+ * \param mopts Muxer options
+ * \param s     Stream header data, terminated by \a type=-1.
+ * \param info  Info packet data, terminated by \a count=-1. May be \a NULL.
+ * \return NUT muxer context
+ *
+ * In case nut_muxer_opts_t::realtime_stream is set, the first packet given
+ * to the nut_output_stream_t::write() function given by muxer options will
+ * be all of the main headers. This packet must be given exactly once at
+ * the begginning of any stream forwarded out.
+ */
+
+/*! \fn void nut_muxer_uninit(nut_context_t *nut)
+ * \param nut NUT muxer context
+ *
+ * Optionally writes index if nut_muxer_opts_t::write_index is set and
+ * nut_muxer_opts_t::realtime_stream is unset.
+ *
+ * \warning Must \b not be used directly if nut_write_frame_reorder() was used.
+ * \see nut_muxer_uninit_reorder()
+ */
+
+/*! \fn void nut_write_frame(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf)
+ * \param nut NUT muxer context
+ * \param p   Infomation on the frame written.
+ * \param buf Actual data of frame.
+ *
+ * If nut_muxer_opts_t::realtime_stream realtime_stream is unset, repeated
+ * headers will be written at some positions. Syncpoints will be written in
+ * accordance to NUT spec. If nut_muxer_opts_t::realtime_stream is set,
+ * calling this function will result in a single nut_output_stream_t::write()
+ * call, which will be the full frame NUT packet. If the packet starts with
+ * a syncpoint startcode, it may be used as a start point after giving the
+ * main headers to a new client.
+ *
+ * \warning
+ * The use of this function is discouraged if more than a single stream is
+ * used, as frames must meet the NUT specification ordering rule.
+ * nut_write_frame_reorder() should be used instead.
+ * \sa nut_write_frame_reorder()
+ */
+
+/*! \fn void nut_write_info(nut_context_t * nut, const nut_info_packet_t * info)
+ * \param nut NUT muxer context
+ * \param info A single info packet.
+ *
+ * The use of this function is \b illegal in non realtime streams, and will
+ * do nothing if nut_muxer_opts_t::realtime_stream is not set. The result
+ * is a single call to nut_output_stream_t::write() with the NUT info packet.
+ */
+
+/*! \fn void nut_write_frame_reorder(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf)
+ * \param nut NUT muxer context
+ * \param p   Infomation on the frame written.
+ * \param buf Actual data of frame.
+ *
+ * Uses an internal buffer and sorts the frames to meet NUT's ordering rule.
+ * Calls to this function \b must \b not be mixed with calls to
+ * nut_write_frame().
+ *
+ * If this function is used, nut_muxer_uninit_reorder() \b must be used.
+ * \sa nut_muxer_uninit_reorder()
+ */
+
+/*! \fn void nut_muxer_uninit_reorder(nut_context_t * nut)
+ * \param nut NUT muxer context
+ *
+ * Must be used if nut_write_frame_reorder() was used.
+ * \sa nut_muxer_uninit()
+ */
+
+/*! \fn void nut_framecode_generate(const nut_stream_header_t s[], nut_frame_table_input_t fti[256])
+ * \param s   Stream header data, terminated by \a type=-1.
+ * \param fti Output framecode table data. Must be pre-allocated to 256 entries.
+ *
+ * Creates an optimized framecode table for NUT main header based on stream
+ * types and codecs. Currently recognized fourcc values are "mp4v", "h264",
+ * "mp3 ", and "vrbs".
+ *
+ * This function is used directly by nut_muxer_init() if
+ * nut_muxer_opts_t::fti is \a NULL.
+ */
+
+/*! \addtogroup demuxer
+ * All of the demuxer related functions return an integer value
+ * representing one of the following return codes:
+ * - 0 (=#NUT_ERR_NO_ERROR) Success
+ * - #NUT_ERR_EOF           Unexpected or expected EOF
+ * - #NUT_ERR_EAGAIN        Insufficient data for demuxing
+ * - #NUT_ERR_NOT_SEEKABLE  Unsuccessful seek in nut_seek()
+ *
+ * \par NUT_ERR_EOF
+ * If any function returns EOF, it can be recovered by using nut_seek().
+ * The exception to this is nut_read_headers(), then it is a fatal
+ * error and only nut_demuxer_uninit() can be called.
+ *
+ * \par NUT_ERR_EAGAIN
+ * Indicates not enough data was given from nut_input_stream_t::read()
+ * function, but EOF was not met. Whichever function returned this should
+ * be re-called given the exact same params when more data is available.
+ * The exception to this is nut_read_frame(), which should be called with
+ * an updated \a buf param.
+ *
+ * \par NUT_ERR_NOT_SEEKABLE
+ * Can only be returned from nut_seek(). Indicates that no seek has been
+ * performed and that the stream is in the exact same position before the
+ * seek.
+ *
+ * \par Other errors
+ * All errors except the list above are fatal.
+ * The only legal operation after a fatal error is nut_demuxer_uninit().
+ */
+
+/*! \var size_t (*nut_input_stream_t::read)(void * priv, size_t len, uint8_t * buf)
+ * If NULL, nut_input_stream_t::priv is used as FILE*, and
+ * nut_input_stream_t::seek and nut_input_stream_t::eof are ignored.
+ */
+
+/*! \var off_t (*nut_input_stream_t::seek)(void * priv, long long pos, int whence)
+ * If NULL (and nut_input_stream_t::read is non-NULL), indicates stream is
+ * unseekable. This implies nut_demuxer_opts_t::read_index and
+ * nut_demuxer_opts_t::cache_syncpoints to be unset. Any call to
+ * nut_seek() with an unseekable stream will yield #NUT_ERR_NOT_SEEKABLE
+ *
+ * Parameter whence must support the following libc defines:
+ * - SEEK_SET - pos is used as offset from begginning of file
+ * - SEEK_CUR - pos is used as offset from current position
+ * - SEEK_END - pos is used as offset from end of file
+ */
+
+/*! \var int (*nut_input_stream_t::eof)(void * priv)
+ * Only necessary if stream supports non-blocking mode.
+ * Returns non-zero if stream is at EOF, 0 otherwise.
+ *
+ * This function is called if nut_input_stream_t::read returns less data
+ * read than requested. If it returns zero, then the stream is assumed to
+ * be lacking data and #NUT_ERR_EAGAIN is raised. Otherwise, #NUT_ERR_EOF
+ * is raised.
+ *
+ * If NULL, then any read error is assumed to be caused by EOF.
+ */
+
+/*! \var off_t nut_input_stream_t::file_pos
+ * Must contain position in file at begginning of demuxing. Should
+ * usually be zero.
+ */
+
+/*! \fn int nut_read_headers(nut_context_t * nut, nut_stream_header_t * s [], nut_info_packet_t * info [])
+ * \param nut  NUT demuxer context
+ * \param s    Pointer to stream header variable to be set to an array
+ * \param info Pointer to info header variable, may be NULL.
+ *
+ * Both `s' and `info' are handeled by context, and are illegal pointers
+ * after nut_demuxer_uninit().
+ *
+ * If main NUT headers are not found at begginning of file and the input
+ * stream is seekable, Several parts of the file are searched for the main
+ * headers before giving up in accordance to NUT spec (EOF and 2^n
+ * locations).
+ *
+ * Any error returned from this function except #NUT_ERR_EAGAIN is fatal.
+ * No other functions may be called until a successful call to
+ * nut_read_headers().
+ */
+
+/*! \fn int nut_read_next_packet(nut_context_t * nut, nut_packet_t * pd)
+ * \param nut NUT demuxer context
+ * \param pd  Pointer to frame header struct to be filled with next frame
+ *            info.
+ *
+ * After a successful call to nut_read_next_packet(), nut_read_frame()
+ * \b must be called.
+ *
+ * If nut_demuxer_opts_t::new_info is non-NULL, a new info packet may be
+ * seen before decoding of frame header and this function pointer will be
+ * called (possibly even several times).
+ *
+ * If a stream error is detected during decoding of frame header,
+ * nut_read_next_packet() will attempt to recover from the error and gives
+ * the next undamaged frame in the stream.
+ */
+
+/*! \fn int nut_read_frame(nut_context_t * nut, int * len, uint8_t * buf)
+ * \param nut NUT demuxer context
+ * \param len length of data left to be read
+ * \param buf buffer to write the frame data
+ *
+ * This function must be called \b after nut_read_next_packet().
+ *
+ * If the function return #NUT_ERR_EAGAIN or #NUT_ERR_EOF, \a len will
+ * return the amount of bytes actually read.
+ *
+ * Data is always written to the \b begginning of the buffer \a buf, so it
+ * must be moved accordingly in case of beign called again for
+ * #NUT_ERR_EAGAIN.
+ *
+ * \par Example:
+ * \code
+ * nut_packet_t pd;
+ * int len = pd.len;
+ * while((err = nut_read_frame(nut, &len, buf+pd.len-len)) == NUT_ERR_EAGAIN)
+ * 	sleep(1);
+ * \endcode
+ */
+
+/*! \fn int nut_seek(nut_context_t * nut, double time_pos, int flags, const int * active_streams)
+ * \param nut            NUT demuxer context
+ * \param time_pos       Position to seek to in seconds
+ * \param flags          Bitfield given as seek options.
+ * \param active_streams -1 terminated list of all streams that are active.
+ *                       May be NULL - indicates all streams are active.
+ *
+ * Flag bitfield options:
+ * - 1 RELATIVE: If set, time_pos is relative to current position,
+ *               otherwise it is absoloute.
+ * - 2 FORWARD:  If set, the seek should find the nearest keyframe
+ *               after the target position. If unset, the nearest
+ *               keyframe before the target position is picked.
+ *
+ * Active streams decide which keyframe the function will seek to. In
+ * backwards seeking, a keyframe for all active streams is garunteed to be
+ * found before the target presentation timestamp.
+ *
+ * In forward seeking, no percise seeking is preformed. The function seeks
+ * to the first keyframe for an active stream after the target timestamp.
+ *
+ * If the function returns #NUT_ERR_NOT_SEEKABLE, no seek was performed.
+ * If #NUT_ERR_EOF is returned, requested position is outside bounds of
+ * file.
+ *
+ * After nut_seek, nut_read_next_packet should be called to get the next frame.
+ */
 
 #endif // _NUT_H



More information about the NUT-devel mailing list