1 /*
2 Copyright (c) 2012, Broadcom Europe Ltd
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12     * Neither the name of the copyright holder nor the
13       names of its contributors may be used to endorse or promote products
14       derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #ifndef VC_CONTAINERS_H
28 #define VC_CONTAINERS_H
29 
30 /** \file containers.h
31  * Public API for container readers and writers
32  */
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #include "containers/containers_types.h"
39 
40 /** \defgroup VcContainerApi Container API
41  *  API for container readers and writers */
42 /* @{ */
43 
44 /** Status codes returned by the container API */
45 typedef enum
46 {
47    VC_CONTAINER_SUCCESS = 0,                        /**< No error */
48    VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED,         /**< Format of container is not supported */
49    VC_CONTAINER_ERROR_FORMAT_FEATURE_NOT_SUPPORTED, /**< Format of container uses unsupported features */
50    VC_CONTAINER_ERROR_FORMAT_INVALID,               /**< Format of container is invalid */
51    VC_CONTAINER_ERROR_CORRUPTED,                    /**< Container is corrupted */
52    VC_CONTAINER_ERROR_URI_NOT_FOUND,                /**< URI could not be found */
53    VC_CONTAINER_ERROR_URI_OPEN_FAILED,              /**< URI could not be opened */
54    VC_CONTAINER_ERROR_OUT_OF_MEMORY,                /**< Out of memory */
55    VC_CONTAINER_ERROR_OUT_OF_SPACE,                 /**< Out of disk space (used when writing) */
56    VC_CONTAINER_ERROR_OUT_OF_RESOURCES,             /**< Out of resources (other than memory) */
57    VC_CONTAINER_ERROR_EOS,                          /**< End of stream reached */
58    VC_CONTAINER_ERROR_LIMIT_REACHED,                /**< User defined limit reached (used when writing) */
59    VC_CONTAINER_ERROR_BUFFER_TOO_SMALL,             /**< Given buffer is too small for data to be copied */
60    VC_CONTAINER_ERROR_INCOMPLETE_DATA,              /**< Requested data is incomplete */
61    VC_CONTAINER_ERROR_NO_TRACK_AVAILABLE,           /**< Container doesn't have any track */
62    VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED,   /**< Format of the track is not supported */
63    VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION,        /**< The requested operation is not supported */
64    VC_CONTAINER_ERROR_INVALID_ARGUMENT,             /**< The argument provided is invalid */
65    VC_CONTAINER_ERROR_CONTINUE,                     /**< The requested operation was interrupted and needs to be tried again */
66    VC_CONTAINER_ERROR_ABORTED,                      /**< The requested operation was aborted */
67    VC_CONTAINER_ERROR_NOT_FOUND,                    /**< The requested data was not found */
68    VC_CONTAINER_ERROR_DRM_NOT_AUTHORIZED,           /**< The DRM was not authorized */
69    VC_CONTAINER_ERROR_DRM_EXPIRED,                  /**< The DRM has expired */
70    VC_CONTAINER_ERROR_DRM_FAILED,                   /**< Generic DRM error */
71    VC_CONTAINER_ERROR_FAILED,                       /**< Generic error */
72    VC_CONTAINER_ERROR_NOT_READY                     /**< The container was not yet able to carry out the operation. */
73 } VC_CONTAINER_STATUS_T;
74 
75 /** Four Character Code type used to identify codecs, etc. */
76 typedef uint32_t VC_CONTAINER_FOURCC_T;
77 
78 /** Type definition for language codes.
79  * Language are defined as ISO639 Alpha-3 codes (http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) */
80 typedef uint8_t VC_CONTAINER_LANGUAGE_T[3];
81 
82 /** Enumeration of the character encodings supported. */
83 typedef enum {
84    VC_CONTAINER_CHAR_ENCODING_UNKNOWN = 0, /**< Encoding is unknown */
85    VC_CONTAINER_CHAR_ENCODING_UTF8         /**< UTF8 encoding */
86 } VC_CONTAINER_CHAR_ENCODING_T;
87 
88 /** \name Container Capabilities
89  * The following flags are exported by containers to describe their capabilities */
90 /* @{ */
91 /** Type definition for container capabilities */
92 typedef uint32_t VC_CONTAINER_CAPABILITIES_T;
93 /** The container can seek */
94 #define VC_CONTAINER_CAPS_CAN_SEEK               0x1
95 /** Seeking is fast. The absence of this flag can be used as a hint to avoid seeking as much as possible */
96 #define VC_CONTAINER_CAPS_SEEK_IS_FAST           0x2
97 /** The container controls the pace at which it is reading the data */
98 #define VC_CONTAINER_CAPS_CAN_CONTROL_PACE       0x4
99 /** The container provides an index. This basically means that seeking will be precise and fast */
100 #define VC_CONTAINER_CAPS_HAS_INDEX              0x8
101 /** The container provides keyframe information */
102 #define VC_CONTAINER_CAPS_DATA_HAS_KEYFRAME_FLAG 0x10
103 /** The container supports adding tracks after TRACK_ADD_DONE control message has been sent */
104 #define VC_CONTAINER_CAPS_DYNAMIC_TRACK_ADD      0x20
105 /** The container supports forcing reading of a given track */
106 #define VC_CONTAINER_CAPS_FORCE_TRACK            0x40
107 /* @} */
108 
109 /** \defgroup VcContainerMetadata Container Metadata
110  * Container metadata contains descriptive information which is associated with the multimedia data */
111 /* @{ */
112 
113 /** Enumeration of the different metadata keys available. */
114 typedef enum {
115    /* Metadata of global scope */
116    VC_CONTAINER_METADATA_KEY_TITLE       = VC_FOURCC('t','i','t','l'),
117    VC_CONTAINER_METADATA_KEY_ARTIST      = VC_FOURCC('a','r','t','i'),
118    VC_CONTAINER_METADATA_KEY_ALBUM       = VC_FOURCC('a','l','b','m'),
119    VC_CONTAINER_METADATA_KEY_DESCRIPTION = VC_FOURCC('d','e','s','c'),
120    VC_CONTAINER_METADATA_KEY_YEAR        = VC_FOURCC('y','e','a','r'),
121    VC_CONTAINER_METADATA_KEY_GENRE       = VC_FOURCC('g','e','n','r'),
122    VC_CONTAINER_METADATA_KEY_TRACK       = VC_FOURCC('t','r','a','k'),
123    VC_CONTAINER_METADATA_KEY_LYRICS      = VC_FOURCC('l','y','r','x'),
124 
125    VC_CONTAINER_METADATA_KEY_UNKNOWN     = 0
126 
127 } VC_CONTAINER_METADATA_KEY_T;
128 
129 /** Definition of the metadata type.
130  * This type is used to store one element of metadata */
131 typedef struct VC_CONTAINER_METADATA_T
132 {
133    /** Identifier for the type of metadata the value refers to.
134     * Using an enum for the id will mean that a list of possible values will have to be
135     * defined and maintained. This might limit extensibility and customisation.\n
136     * Maybe it would be better to use a FOURCC or even a string here. */
137    VC_CONTAINER_METADATA_KEY_T key;
138 
139    VC_CONTAINER_LANGUAGE_T language; /**< Language code for the metadata */
140    VC_CONTAINER_CHAR_ENCODING_T encoding; /**< Encoding of the metadata */
141 
142    /** Metadata value. This value is defined as null-terminated UTF-8 string.\n
143     * Do we want to support other types than strings (e.g. integer) ?\n
144     * We need an encoding conversion library! */
145    char *value;
146 
147    /** Size of the memory area reserved for metadata value (including any
148     * terminating characters). */
149    unsigned int size;
150 } VC_CONTAINER_METADATA_T;
151 /* @} */
152 
153 /** \defgroup VcContainerESFormat Container Elementary Stream Format
154  * This describes the format of an elementary stream associated with a track */
155 /* @{ */
156 
157 /** Enumeration of the different types of elementary streams.
158  * This divides elementary streams into 4 big categories. */
159 typedef enum
160 {
161    VC_CONTAINER_ES_TYPE_UNKNOWN,     /**< Unknown elementary stream type */
162    VC_CONTAINER_ES_TYPE_AUDIO,       /**< Audio elementary stream */
163    VC_CONTAINER_ES_TYPE_VIDEO,       /**< Video elementary stream */
164    VC_CONTAINER_ES_TYPE_SUBPICTURE   /**< Sub-picture elementary stream (e.g. subtitles, overlays) */
165 
166 } VC_CONTAINER_ES_TYPE_T;
167 
168 /** Definition of a video format.
169  * This describes the properties specific to a video stream */
170 typedef struct VC_CONTAINER_VIDEO_FORMAT_T
171 {
172    uint32_t width;           /**< Width of the frame */
173    uint32_t height;          /**< Height of the frame */
174    uint32_t visible_width;   /**< Width of the visible area of the frame */
175    uint32_t visible_height;  /**< Height of the visible area of the frame */
176    uint32_t x_offset;        /**< Offset to the start of the visible width */
177    uint32_t y_offset;        /**< Offset to the start of the visible height */
178    uint32_t frame_rate_num;  /**< Frame rate numerator */
179    uint32_t frame_rate_den;  /**< Frame rate denominator */
180    uint32_t par_num;         /**< Pixel aspect ratio numerator */
181    uint32_t par_den;         /**< Pixel aspect ratio denominator */
182 } VC_CONTAINER_VIDEO_FORMAT_T;
183 
184 /** Enumeration for the different channel locations */
185 typedef enum
186 {
187    VC_CONTAINER_AUDIO_CHANNEL_LEFT = 0,            /**< Left channel */
188    VC_CONTAINER_AUDIO_CHANNEL_RIGHT,               /**< Right channel */
189    VC_CONTAINER_AUDIO_CHANNEL_CENTER,              /**< Center channel */
190    VC_CONTAINER_AUDIO_CHANNEL_LOW_FREQUENCY,       /**< Low frequency channel */
191    VC_CONTAINER_AUDIO_CHANNEL_BACK_LEFT,           /**< Back left channel */
192    VC_CONTAINER_AUDIO_CHANNEL_BACK_RIGHT,          /**< Back right channel */
193    VC_CONTAINER_AUDIO_CHANNEL_BACK_CENTER,         /**< Back center channel */
194    VC_CONTAINER_AUDIO_CHANNEL_SIDE_LEFT,           /**< Side left channel */
195    VC_CONTAINER_AUDIO_CHANNEL_SIDE_RIGHT,          /**< Side right channel */
196 
197    VC_CONTAINER_AUDIO_CHANNELS_MAX = 32            /**< Maximum number of channels supported */
198 
199 } VC_CONTAINER_AUDIO_CHANNEL_T;
200 
201 /** \name Audio format flags
202  * \anchor audioformatflags
203  * The following flags describe properties of an audio stream */
204 /* @{ */
205 #define VC_CONTAINER_AUDIO_FORMAT_FLAG_CHANNEL_MAPPING 0x1 /**< Channel mapping available */
206 /* @} */
207 
208 /** Definition of an audio format.
209  * This describes the properties specific to an audio stream */
210 typedef struct VC_CONTAINER_AUDIO_FORMAT_T
211 {
212    uint32_t channels;           /**< Number of audio channels */
213    uint32_t sample_rate;        /**< Sample rate */
214 
215    uint32_t bits_per_sample;    /**< Bits per sample */
216    uint32_t block_align;        /**< Size of a block of data */
217 
218    uint32_t flags;              /**< Flags describing the audio format.
219                                  * See \ref audioformatflags "Audio format flags". */
220 
221    /** Mapping of the channels in order of appearance */
222    VC_CONTAINER_AUDIO_CHANNEL_T channel_mapping[VC_CONTAINER_AUDIO_CHANNELS_MAX];
223 
224    uint16_t gap_delay;   /**< Delay introduced by the encoder. Used for gapless playback */
225    uint16_t gap_padding; /**< Padding introduced by the encoder. Used for gapless playback */
226 
227    /** Replay gain information. First element is the track information and the second
228     * is the album information. */
229    struct {
230       float peak; /**< Peak value (full range is 1.0) */
231       float gain; /**< Gain value in dB */
232    } replay_gain[2];
233 
234 } VC_CONTAINER_AUDIO_FORMAT_T;
235 
236 /** Definition of a subpicture format.
237  * This describes the properties specific to a subpicture stream */
238 typedef struct VC_CONTAINER_SUBPICTURE_FORMAT_T
239 {
240    VC_CONTAINER_CHAR_ENCODING_T encoding; /**< Encoding for text based subpicture formats */
241    uint32_t x_offset;        /**< Width offset to the start of the subpicture */
242    uint32_t y_offset;        /**< Height offset to the start of the subpicture */
243 } VC_CONTAINER_SUBPICTURE_FORMAT_T;
244 
245 /** \name Elementary stream format flags
246  * \anchor esformatflags
247  * The following flags describe properties of an elementary stream */
248 /* @{ */
249 #define VC_CONTAINER_ES_FORMAT_FLAG_FRAMED 0x1 /**< Elementary stream is framed */
250 /* @} */
251 
252 /** Definition of the type specific format.
253  * This describes the type specific information of the elementary stream. */
254 typedef union
255 {
256    VC_CONTAINER_AUDIO_FORMAT_T      audio;      /**< Audio specific information */
257    VC_CONTAINER_VIDEO_FORMAT_T      video;      /**< Video specific information */
258    VC_CONTAINER_SUBPICTURE_FORMAT_T subpicture; /**< Subpicture specific information */
259 } VC_CONTAINER_ES_SPECIFIC_FORMAT_T;
260 
261 /** Definition of an elementary stream format */
262 typedef struct VC_CONTAINER_ES_FORMAT_T
263 {
264    VC_CONTAINER_ES_TYPE_T es_type;    /**< Type of the elementary stream */
265    VC_CONTAINER_FOURCC_T  codec;      /**< Coding of the elementary stream */
266    VC_CONTAINER_FOURCC_T  codec_variant;  /**< If set, indicates a variant of the coding */
267 
268    VC_CONTAINER_ES_SPECIFIC_FORMAT_T *type; /**< Type specific information for the elementary stream */
269 
270    uint32_t bitrate;         /**< Bitrate */
271 
272    VC_CONTAINER_LANGUAGE_T language; /**< Language code for the elementary stream */
273    uint32_t group_id;                /**< ID of the group this elementary stream belongs to */
274 
275    uint32_t flags;         /**< Flags describing the properties of an elementary stream.
276                             * See \ref esformatflags "Elementary stream format flags". */
277 
278    unsigned int extradata_size; /**< Size of the codec specific data */
279    uint8_t *extradata;     /**< Codec specific data */
280 
281 } VC_CONTAINER_ES_FORMAT_T;
282 /* @} */
283 
284 /** \defgroup VcContainerPacket Container Packet
285  * A container packet is the unit of data that is being read from or written to a container */
286 /* @{ */
287 
288 /** Structure describing a data packet */
289 typedef struct VC_CONTAINER_PACKET_T
290 {
291    struct VC_CONTAINER_PACKET_T *next; /**< Used to build lists of packets */
292    uint8_t *data;              /**< Pointer to the buffer containing the actual data for the packet */
293    unsigned int buffer_size;   /**< Size of the p_data buffer. This is used to indicate how much data can be read in p_data */
294    unsigned int size;          /**< Size of the data contained in p_data */
295    unsigned int frame_size;    /**< If set, indicates the size of the frame this packet belongs to */
296    int64_t pts;                /**< Presentation Timestamp of the packet */
297    int64_t dts;                /**< Decoding Timestamp of the packet */
298    uint64_t num;               /**< Number of this packet */
299    uint32_t track;             /**< Track associated with this packet */
300    uint32_t flags;             /**< Flags associated with this packet */
301 
302    void *user_data;            /**< Field reserved for use by the client */
303    void *framework_data;       /**< Field reserved for use by the framework */
304 
305 } VC_CONTAINER_PACKET_T;
306 
307 /** \name Container Packet Flags
308  * The following flags describe properties of the data packet */
309 /* @{ */
310 #define VC_CONTAINER_PACKET_FLAG_KEYFRAME       0x01   /**< Packet is a keyframe */
311 #define VC_CONTAINER_PACKET_FLAG_FRAME_START    0x02   /**< Packet starts a frame */
312 #define VC_CONTAINER_PACKET_FLAG_FRAME_END      0x04   /**< Packet ends a frame */
313 #define VC_CONTAINER_PACKET_FLAG_FRAME          0x06   /**< Packet contains only complete frames */
314 #define VC_CONTAINER_PACKET_FLAG_DISCONTINUITY  0x08   /**< Packet comes after a discontinuity in the stream. Decoders might have to be flushed */
315 #define VC_CONTAINER_PACKET_FLAG_ENCRYPTED      0x10   /**< Packet contains DRM encrypted data */
316 #define VC_CONTAINER_PACKET_FLAG_CONFIG         0x20   /**< Packet contains stream specific config data */
317 /* @} */
318 
319 /** \name Special Unknown Time Value
320  * This is the special value used to signal that a timestamp is not known */
321 /* @{ */
322 #define VC_CONTAINER_TIME_UNKNOWN (INT64_C(1)<<63)     /**< Special value for signalling that time is not known */
323 /* @} */
324 
325 /* @} */
326 
327 /** \name Track flags
328  * \anchor trackflags
329  * The following flags describe properties of a track */
330 /* @{ */
331 #define VC_CONTAINER_TRACK_FLAG_CHANGED 0x1 /**< Track definition has changed */
332 /* @} */
333 
334 /** Definition of the track type */
335 typedef struct VC_CONTAINER_TRACK_T
336 {
337    struct VC_CONTAINER_TRACK_PRIVATE_T *priv; /**< Private member used by the implementation */
338    uint32_t is_enabled;               /**< Flag to specify if the track is enabled */
339    uint32_t flags;                    /**< Flags describing the properties of a track.
340                                        * See \ref trackflags "Track flags". */
341 
342    VC_CONTAINER_ES_FORMAT_T *format;  /**< Format of the elementary stream contained in the track */
343 
344    unsigned int meta_num;             /**< Number of metadata elements associated with the track */
345    VC_CONTAINER_METADATA_T **meta;    /**< Array of metadata elements associated with the track */
346 
347 } VC_CONTAINER_TRACK_T;
348 
349 /** Definition of the DRM type */
350 typedef struct VC_CONTAINER_DRM_T
351 {
352    VC_CONTAINER_FOURCC_T format;    /**< Four character code describing the format of the DRM in use */
353    unsigned int views_max;          /**< Maximum number of views allowed */
354    unsigned int views_current;      /**< Current number of views */
355 
356 } VC_CONTAINER_DRM_T;
357 
358 /** Type definition for the progress reporting function. This function will be called regularly
359  * by the container during a call which blocks for too long and will report the progress of the
360  * operation as an estimated total length in microseconds and a percentage done.
361  * Returning anything else than VC_CONTAINER_SUCCESS in this function will abort the current
362  * operation. */
363 typedef VC_CONTAINER_STATUS_T (*VC_CONTAINER_PROGRESS_REPORT_FUNC_T)(void *userdata,
364    int64_t length, unsigned int percentage_done);
365 
366 /** \name Container Events
367  * The following flags are exported by containers to notify the application of events */
368 /* @{ */
369 /** Type definition for container events */
370 typedef uint32_t VC_CONTAINER_EVENTS_T;
371 #define VC_CONTAINER_EVENT_TRACKS_CHANGE   1    /**< Track information has changed */
372 #define VC_CONTAINER_EVENT_METADATA_CHANGE 2    /**< Metadata has changed */
373 /* @} */
374 
375 /** Definition of the container context */
376 typedef struct VC_CONTAINER_T
377 {
378    struct VC_CONTAINER_PRIVATE_T *priv; /**< Private member used by the implementation */
379 
380    VC_CONTAINER_EVENTS_T events; /**< Events generated by the container */
381    VC_CONTAINER_CAPABILITIES_T capabilities; /**< Capabilities exported by the container */
382 
383    VC_CONTAINER_PROGRESS_REPORT_FUNC_T pf_progress; /**< Progress report function pointer */
384    void *progress_userdata;                          /**< Progress report user data */
385 
386    int64_t duration;                  /**< Duration of the media in microseconds */
387    int64_t position;                  /**< Current time position into the media */
388    int64_t size;                      /**< Size of the media in bytes */
389 
390    unsigned int tracks_num;           /**< Number of tracks available */
391    /** Pointer to an array of pointers to track elements.
392     * The reasoning for using a pointer to pointers here is to allow us to extend
393     * VC_CONTAINER_TRACK_T without losing binary backward compatibility. */
394    VC_CONTAINER_TRACK_T **tracks;
395 
396    unsigned int meta_num;             /**< Number of metadata elements associated with the container */
397    VC_CONTAINER_METADATA_T **meta;    /**< Array of metadata elements associated with the container */
398 
399    VC_CONTAINER_DRM_T *drm;           /**< Description used for DRM protected content */
400 
401 } VC_CONTAINER_T;
402 
403 /** Forward declaration of a container input / output context.
404  * This structure defines the context for a container io instance */
405 typedef struct VC_CONTAINER_IO_T VC_CONTAINER_IO_T;
406 
407 /** Opens the media container pointed to by the URI for reading.
408  * This will create an an instance of a container reader and its associated context.
409  * The context returned will also be filled with the information retrieved from the media.
410  *
411  * If the media isn't accessible or recognized, this will return a null pointer as well as
412  * an error code indicating why this failed.
413  *
414  * \param  psz_uri      Unified Resource Identifier pointing to the media container
415  * \param  status       Returns the status of the operation
416  * \param  pf_progress  User provided function pointer to a progress report function. Can be set to
417  *                      null if no progress report is wanted. This function will be used during
418  *                      the whole lifetime of the instance (i.e. it will be used during
419  *                      open / seek / close)
420  * \param  progress_userdata User provided pointer that will be passed during the progress report
421  *                      function call.
422  * \return              A pointer to the context of the new instance of the
423  *                      container reader. Returns NULL on failure.
424  */
425 VC_CONTAINER_T *vc_container_open_reader( const char *psz_uri, VC_CONTAINER_STATUS_T *status,
426    VC_CONTAINER_PROGRESS_REPORT_FUNC_T pf_progress, void *progress_userdata);
427 
428 /** Opens for reading the media container pointed to by the container i/o.
429  * This will create an an instance of a container reader and its associated context.
430  * The context returned will also be filled with the information retrieved from the media.
431  *
432  * If the media isn't accessible or recognized, this will return a null pointer as well as
433  * an error code indicating why this failed.
434  *
435  * \param  p_io         Instance of the container i/o to use
436  * \param  psz_uri      Unified Resource Identifier pointing to the media container (optional)
437  * \param  status       Returns the status of the operation
438  * \param  pf_progress  User provided function pointer to a progress report function. Can be set to
439  *                      null if no progress report is wanted. This function will be used during
440  *                      the whole lifetime of the instance (i.e. it will be used during
441  *                      open / seek / close)
442  * \param  progress_userdata User provided pointer that will be passed during the progress report
443  *                      function call.
444  * \return              A pointer to the context of the new instance of the
445  *                      container reader. Returns NULL on failure.
446  */
447 VC_CONTAINER_T *vc_container_open_reader_with_io( VC_CONTAINER_IO_T *p_io,
448    const char *psz_uri, VC_CONTAINER_STATUS_T *status,
449    VC_CONTAINER_PROGRESS_REPORT_FUNC_T pf_progress, void *progress_userdata);
450 
451 /** Opens the media container pointed to by the URI for writing.
452  * This will create an an instance of a container writer and its associated context.
453  * The context returned will be initialised to sensible values.
454  *
455  * The application will need to add all the media tracks using \ref vc_container_control before
456  * it starts writing data using \ref vc_container_write.
457  *
458  * If the media isn't accessible or recognized, this will return a null pointer as well as
459  * an error code indicating why this failed.
460  *
461  * \param  psz_uri      Unified Resource Identifier pointing to the media container
462  * \param  status       Returns the status of the operation
463  * \param  pf_progress User provided function pointer to a progess report function. Can be set to
464  *                      null if no progress report is wanted.
465  * \param  progress_userdata User provided pointer that will be passed during the progress report
466  *                      function call.
467  * \return              A pointer to the context of the new instance of the
468  *                      container writer. Returns NULL on failure.
469  */
470 VC_CONTAINER_T *vc_container_open_writer( const char *psz_uri, VC_CONTAINER_STATUS_T *status,
471    VC_CONTAINER_PROGRESS_REPORT_FUNC_T pf_progress, void *progress_userdata);
472 
473 /** Closes an instance of a container reader / writer.
474  * This will free all the resources associated with the context.
475  *
476  * \param  context   Pointer to the context of the instance to close
477  * \return           the status of the operation
478  */
479 VC_CONTAINER_STATUS_T vc_container_close( VC_CONTAINER_T *context );
480 
481 /** \name Container read flags
482  * The following flags can be passed during a read call */
483 /* @{ */
484 /** Type definition for the read flags */
485 typedef uint32_t VC_CONTAINER_READ_FLAGS_T;
486 /** Ask the container to only return information on the next packet without reading it */
487 #define VC_CONTAINER_READ_FLAG_INFO   1
488 /** Ask the container to skip the next packet */
489 #define VC_CONTAINER_READ_FLAG_SKIP   2
490 /** Force the container to read data from the specified track */
491 #define VC_CONTAINER_READ_FLAG_FORCE_TRACK 4
492 /* @} */
493 
494 /** Reads a data packet from a container reader.
495  * By default, the reader will read whatever packet comes next in the container and update the
496  * given \ref VC_CONTAINER_PACKET_T structure with this packet's information.
497  * This behaviour can be changed using the \ref VC_CONTAINER_READ_FLAGS_T.\n
498  * \ref VC_CONTAINER_READ_FLAG_INFO will instruct the reader to only return information on the
499  * following packet but not its actual data. The data can be retreived later by issuing another
500  * read request.\n
501  * \ref VC_CONTAINER_READ_FLAG_FORCE_TRACK will force the reader to read the next packet for the
502  * selected track (as present in the \ref VC_CONTAINER_PACKET_T structure) instead of defaulting
503  * to reading the packet which comes next in the container.\n
504  * \ref VC_CONTAINER_READ_FLAG_SKIP will instruct the reader to skip the next packet. In this case
505  * it isn't necessary for the caller to pass a pointer to a \ref VC_CONTAINER_PACKET_T structure
506  * unless the \ref VC_CONTAINER_READ_FLAG_INFO is also given.\n
507  * A combination of all these flags can be used.
508  *
509  * \param  context   Pointer to the context of the reader to use
510  * \param  packet    Pointer to the VC_CONTAINER_PACKET_T structure describing the data packet
511  *                   This needs to be partially filled before the call (buffer, buffer_size)
512  * \param  flags     Flags controlling the read operation
513  * \return           the status of the operation
514  */
515 VC_CONTAINER_STATUS_T vc_container_read( VC_CONTAINER_T *context,
516    VC_CONTAINER_PACKET_T *packet, VC_CONTAINER_READ_FLAGS_T flags );
517 
518 /** Writes a data packet to a container writer.
519  *
520  * \param  context   Pointer to the context of the writer to use
521  * \param  packet    Pointer to the VC_CONTAINER_PACKET_T structure describing the data packet
522  * \return           the status of the operation
523  */
524 VC_CONTAINER_STATUS_T vc_container_write( VC_CONTAINER_T *context,
525    VC_CONTAINER_PACKET_T *packet );
526 
527 /** Definition of the different seek modes */
528 typedef enum
529 {
530    /** The offset provided for seeking is an absolute time offset in microseconds */
531    VC_CONTAINER_SEEK_MODE_TIME = 0,
532    /** The offset provided for seeking is a percentage (Q32 ?) */
533    VC_CONTAINER_SEEK_MODE_PERCENT
534 
535 } VC_CONTAINER_SEEK_MODE_T;
536 
537 /** \name Container Seek Flags
538  * The following flags control seek operations */
539 /* @{ */
540 /** Type definition for the seek flags */
541 typedef uint32_t VC_CONTAINER_SEEK_FLAGS_T;
542 /** Choose precise seeking even if slower */
543 #define VC_CONTAINER_SEEK_FLAG_PRECISE     0x1
544 /** By default a seek will always seek to the keyframe which comes just before the requested
545  * position. This flag allows the caller to force the container to seek to the keyframe which
546  * comes just after the requested position. */
547 #define VC_CONTAINER_SEEK_FLAG_FORWARD     0x2
548 /* @} */
549 
550 /** Seek into a container reader.
551  *
552  * \param  context   Pointer to the context of the reader to use
553  * \param  offset    Offset to seek to. Used as an input as well as output value.
554  * \param  mode      Seeking mode requested.
555  * \param  flags     Flags affecting the seeking operation.
556  * \return           the status of the operation
557  */
558 VC_CONTAINER_STATUS_T vc_container_seek( VC_CONTAINER_T *context, int64_t *offset,
559       VC_CONTAINER_SEEK_MODE_T mode, VC_CONTAINER_SEEK_FLAGS_T flags);
560 
561 /** Performance statistics.
562  */
563 /** The maximum number of bins a statistics value is held in */
564 #define VC_CONTAINER_STATS_BINS 10
565 
566 /** This type is used to represent multiple values of a statistic.
567  */
568 typedef struct VC_CONTAINER_STATS_T
569 {
570    /** The number of places to right shift count before using.  Resulting values
571     * of zero are rounded to 1. */
572    uint32_t shift;
573 
574    /** We store VC_CONTAINER_STATS_BINS+1 records, in sorted order of numpc.
575     * At least one will be invalid and all zero.  We combine adjacent records
576     * as necessary. */
577    struct {
578       /** Sum of count.  For single value statistics this is the freqency, for paired statistics
579        * this is the number of bytes written. */
580       uint32_t count;
581       /** Number of count. For single value statistics this is the total value, for paired statistics
582        * this is the total length of time.  */
583       uint32_t num;
584       /** Number>>shift per count.  Stored to save recalculation. */
585       uint32_t numpc;
586    } record[VC_CONTAINER_STATS_BINS+1];
587 } VC_CONTAINER_STATS_T;
588 
589 /** This type represents the statistics saved by the io layer. */
590 typedef struct VC_CONTAINER_WRITE_STATS_T
591 {
592    /** This logs the number of bytes written in count, and the microseconds taken to write
593     * in num. */
594    VC_CONTAINER_STATS_T write;
595    /** This logs the length of time the write function has to wait for the asynchronous task. */
596    VC_CONTAINER_STATS_T wait;
597    /** This logs the length of time that we wait for a flush command to complete. */
598    VC_CONTAINER_STATS_T flush;
599 } VC_CONTAINER_WRITE_STATS_T;
600 
601 /** Control operations which can be done on containers. */
602 typedef enum
603 {
604    /** Adds a new track to the list of tracks. This should be used by writers to create
605     * their list of tracks.\n
606     * Arguments:\n
607     *   arg1= VC_CONTAINER_ES_FORMAT_T *: format of the track to add\n
608     *   return=  VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED if the format is not supported */
609    VC_CONTAINER_CONTROL_TRACK_ADD = 0,
610 
611    /** Specifies that we're done adding new tracks. This is optional but can be used by writers
612     * to trigger the writing of the container header early. If this isn't used, the header will be
613     * written when the first data packet is received.\n
614     * No arguments.\n
615     *   return=  VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED if the format is not supported */
616    VC_CONTAINER_CONTROL_TRACK_ADD_DONE,
617 
618    /** Change the format of a track in the list of tracks. This should be used by writers to modify
619     * the format of a track at run-time.\n
620     * Arguments:\n
621     *   arg1= unsigned int: index of track to change\n
622     *   arg2= VC_CONTAINER_ES_FORMAT_T *: format of the track to add\n
623     *   return=  VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED if the format is not supported */
624    VC_CONTAINER_CONTROL_TRACK_CHANGE,
625 
626    /** Deletes a track from the list of tracks. This should be used by writers to delete tracks
627     * during run-time. Note that vc_container_close will automatically delete all track so it
628     * isn't necessary to call this before closing a writer.\n
629     * Arguments:\n
630     *   arg1= index of the track to delete  */
631    VC_CONTAINER_CONTROL_TRACK_DEL,
632 
633    /** Activate the playback of DRM protected content.\n
634     * No arguments.\n
635     *   return=  one of the VC_CONTAINER_ERROR_DRM error codes if content can't be played */
636    VC_CONTAINER_CONTROL_DRM_PLAY,
637 
638    /** TBD */
639    VC_CONTAINER_CONTROL_METADATA_ADD,
640    /** TBD */
641    VC_CONTAINER_CONTROL_METADATA_CHANGE,
642    /** TBD */
643    VC_CONTAINER_CONTROL_METADATA_DEL,
644 
645    /** TBD */
646    VC_CONTAINER_CONTROL_CHAPTER_ADD,
647    /** TBD */
648    VC_CONTAINER_CONTROL_CHAPTER_DEL,
649 
650    /** Set a maximum size for files generated by writers.\n
651     * Arguments:\n
652     *   arg1= uint64_t: maximum size */
653    VC_CONTAINER_CONTROL_SET_MAXIMUM_SIZE,
654 
655    /** Enables/disabled performance statistic gathering.\n
656     * Arguments:\n
657     *   arg1= bool: enable or disable */
658    VC_CONTAINER_CONTROL_SET_IO_PERF_STATS,
659 
660    /** Collects performance statistics.\n
661     * Arguments:\n
662     *   arg1= VC_CONTAINER_WRITE_STATS_T *: */
663    VC_CONTAINER_CONTROL_GET_IO_PERF_STATS,
664 
665    /** HACK.\n
666     * Arguments:\n
667     *   arg1= void (*)(void *): callback function
668     *   arg1= void *: opaque pointer to pass during the callback */
669    VC_CONTAINER_CONTROL_SET_IO_BUFFER_FULL_CALLBACK,
670 
671    /** Set the I/O read buffer size to be used.\n
672     * Arguments:\n
673     *   arg1= uint32_t: New buffer size in bytes*/
674    VC_CONTAINER_CONTROL_IO_SET_READ_BUFFER_SIZE,
675 
676    /** Set the timeout on I/O read operations, if applicable.\n
677     * Arguments:\n
678     *   arg1= uint32_t: New timeout in milliseconds, or VC_CONTAINER_READ_TIMEOUT_BLOCK */
679    VC_CONTAINER_CONTROL_IO_SET_READ_TIMEOUT_MS,
680 
681    /** Set the timestamp base.\n
682     * The timestamp passed equates to time zero for the stream.\n
683     * Arguments:\n
684     *   arg1= uint32_t: Timestamp base in stream clock units. */
685    VC_CONTAINER_CONTROL_SET_TIMESTAMP_BASE,
686 
687    /** Set the next expected sequence number for the stream.\n
688     * Arguments:\n
689     *   arg1= uint32_t: Next expected sequence number. */
690    VC_CONTAINER_CONTROL_SET_NEXT_SEQUENCE_NUMBER,
691 
692    /** Set the source ID for the container.\n
693     * Arguments:\n
694     *   arg1= uint32_t: Source identifier. */
695    VC_CONTAINER_CONTROL_SET_SOURCE_ID,
696 
697    /** Arguments:\n
698     *   arg1= void *: metadata buffer
699     *   arg2= unsigned long: length of metadata in bytes */
700    VC_CONTAINER_CONTROL_GET_DRM_METADATA,
701 
702    /** Arguments:\n
703     *   arg1= unsigned long: track number
704     *   arg2= VC_CONTAINER_FOURCC_T : drm type
705     *   arg3= void *: encryption configuration parameters.
706     *   arg4= unsigned long: configuration data length */
707    VC_CONTAINER_CONTROL_ENCRYPT_TRACK,
708 
709    /** Causes the io to be flushed.\n
710     * Arguments: none */
711    VC_CONTAINER_CONTROL_IO_FLUSH,
712 
713    /** Request the container reader to packetize data for the specified track.
714     * Arguments:\n
715     *   arg1= unsigned long: track number
716     *   arg2= VC_CONTAINER_FOURCC_T: codec variant to output */
717    VC_CONTAINER_CONTROL_TRACK_PACKETIZE,
718 
719    /** Private user extensions must be above this number */
720    VC_CONTAINER_CONTROL_USER_EXTENSIONS = 0x1000
721 
722 } VC_CONTAINER_CONTROL_T;
723 
724 /** Used with the VC_CONTAINER_CONTROL_IO_SET_READ_TIMEOUT_MS control to indicate the read shall
725  * block until either data is available, or an error occurs.
726  */
727 #define VC_CONTAINER_READ_TIMEOUT_BLOCK   (uint32_t)(-1)
728 
729 /** Extensible control function for container readers and writers.
730  * This function takes a variable number of arguments which will depend on the specific operation.
731  *
732  * \param  context   Pointer to the VC_CONTAINER_T context to use
733  * \param  operation The requested operation
734  * \return           the status of the operation. Can be \ref VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION
735  *                   if the operation is not supported or implemented by the container.
736  */
737 VC_CONTAINER_STATUS_T vc_container_control( VC_CONTAINER_T *context, VC_CONTAINER_CONTROL_T operation, ... );
738 
739 /* @} */
740 
741 #ifdef __cplusplus
742 }
743 #endif
744 
745 #endif /* VC_CONTAINERS_H */
746