Home | History | Annotate | Download | only in nestegg
      1 /*
      2  * Copyright  2010 Mozilla Foundation
      3  *
      4  * This program is made available under an ISC-style license.  See the
      5  * accompanying file LICENSE for details.
      6  */
      7 #if !defined(NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79)
      8 #define NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
      9 
     10 #include "vpx/vpx_integer.h"
     11 
     12 #if defined(__cplusplus)
     13 extern "C" {
     14 #endif
     15 
     16 /** @mainpage
     17 
     18     @section intro Introduction
     19 
     20     This is the documentation for the <tt>libnestegg</tt> C API.
     21     <tt>libnestegg</tt> is a demultiplexing library for <a
     22     href="http://www.webmproject.org/code/specs/container/">WebM</a>
     23     media files.
     24 
     25     @section example Example code
     26 
     27     @code
     28     nestegg * demux_ctx;
     29     nestegg_init(&demux_ctx, io, NULL);
     30 
     31     nestegg_packet * pkt;
     32     while ((r = nestegg_read_packet(demux_ctx, &pkt)) > 0) {
     33       unsigned int track;
     34 
     35       nestegg_packet_track(pkt, &track);
     36 
     37       // This example decodes the first track only.
     38       if (track == 0) {
     39         unsigned int chunk, chunks;
     40 
     41         nestegg_packet_count(pkt, &chunks);
     42 
     43         // Decode each chunk of data.
     44         for (chunk = 0; chunk < chunks; ++chunk) {
     45           unsigned char * data;
     46           size_t data_size;
     47 
     48           nestegg_packet_data(pkt, chunk, &data, &data_size);
     49 
     50           example_codec_decode(codec_ctx, data, data_size);
     51         }
     52       }
     53 
     54       nestegg_free_packet(pkt);
     55     }
     56 
     57     nestegg_destroy(demux_ctx);
     58     @endcode
     59 */
     60 
     61 
     62 /** @file
     63     The <tt>libnestegg</tt> C API. */
     64 
     65 #define NESTEGG_TRACK_VIDEO 0 /**< Track is of type video. */
     66 #define NESTEGG_TRACK_AUDIO 1 /**< Track is of type audio. */
     67 
     68 #define NESTEGG_CODEC_VP8    0 /**< Track uses Google On2 VP8 codec. */
     69 #define NESTEGG_CODEC_VORBIS 1 /**< Track uses Xiph Vorbis codec. */
     70 #define NESTEGG_CODEC_VP9    2 /**< Track uses Google On2 VP9 codec. */
     71 #define NESTEGG_CODEC_OPUS   3 /**< Track uses Xiph Opus codec. */
     72 
     73 #define NESTEGG_VIDEO_MONO              0 /**< Track is mono video. */
     74 #define NESTEGG_VIDEO_STEREO_LEFT_RIGHT 1 /**< Track is side-by-side stereo video.  Left first. */
     75 #define NESTEGG_VIDEO_STEREO_BOTTOM_TOP 2 /**< Track is top-bottom stereo video.  Right first. */
     76 #define NESTEGG_VIDEO_STEREO_TOP_BOTTOM 3 /**< Track is top-bottom stereo video.  Left first. */
     77 #define NESTEGG_VIDEO_STEREO_RIGHT_LEFT 11 /**< Track is side-by-side stereo video.  Right first. */
     78 
     79 #define NESTEGG_SEEK_SET 0 /**< Seek offset relative to beginning of stream. */
     80 #define NESTEGG_SEEK_CUR 1 /**< Seek offset relative to current position in stream. */
     81 #define NESTEGG_SEEK_END 2 /**< Seek offset relative to end of stream. */
     82 
     83 #define NESTEGG_LOG_DEBUG    1     /**< Debug level log message. */
     84 #define NESTEGG_LOG_INFO     10    /**< Informational level log message. */
     85 #define NESTEGG_LOG_WARNING  100   /**< Warning level log message. */
     86 #define NESTEGG_LOG_ERROR    1000  /**< Error level log message. */
     87 #define NESTEGG_LOG_CRITICAL 10000 /**< Critical level log message. */
     88 
     89 typedef struct nestegg nestegg;               /**< Opaque handle referencing the stream state. */
     90 typedef struct nestegg_packet nestegg_packet; /**< Opaque handle referencing a packet of data. */
     91 
     92 /** User supplied IO context. */
     93 typedef struct {
     94   /** User supplied read callback.
     95       @param buffer   Buffer to read data into.
     96       @param length   Length of supplied buffer in bytes.
     97       @param userdata The #userdata supplied by the user.
     98       @retval  1 Read succeeded.
     99       @retval  0 End of stream.
    100       @retval -1 Error. */
    101   int (* read)(void * buffer, size_t length, void * userdata);
    102 
    103   /** User supplied seek callback.
    104       @param offset   Offset within the stream to seek to.
    105       @param whence   Seek direction.  One of #NESTEGG_SEEK_SET,
    106                       #NESTEGG_SEEK_CUR, or #NESTEGG_SEEK_END.
    107       @param userdata The #userdata supplied by the user.
    108       @retval  0 Seek succeeded.
    109       @retval -1 Error. */
    110   int (* seek)(int64_t offset, int whence, void * userdata);
    111 
    112   /** User supplied tell callback.
    113       @param userdata The #userdata supplied by the user.
    114       @returns Current position within the stream.
    115       @retval -1 Error. */
    116   int64_t (* tell)(void * userdata);
    117 
    118   /** User supplied pointer to be passed to the IO callbacks. */
    119   void * userdata;
    120 } nestegg_io;
    121 
    122 /** Parameters specific to a video track. */
    123 typedef struct {
    124   unsigned int stereo_mode;    /**< Video mode.  One of #NESTEGG_VIDEO_MONO,
    125                                     #NESTEGG_VIDEO_STEREO_LEFT_RIGHT,
    126                                     #NESTEGG_VIDEO_STEREO_BOTTOM_TOP, or
    127                                     #NESTEGG_VIDEO_STEREO_TOP_BOTTOM. */
    128   unsigned int width;          /**< Width of the video frame in pixels. */
    129   unsigned int height;         /**< Height of the video frame in pixels. */
    130   unsigned int display_width;  /**< Display width of the video frame in pixels. */
    131   unsigned int display_height; /**< Display height of the video frame in pixels. */
    132   unsigned int crop_bottom;    /**< Pixels to crop from the bottom of the frame. */
    133   unsigned int crop_top;       /**< Pixels to crop from the top of the frame. */
    134   unsigned int crop_left;      /**< Pixels to crop from the left of the frame. */
    135   unsigned int crop_right;     /**< Pixels to crop from the right of the frame. */
    136 } nestegg_video_params;
    137 
    138 /** Parameters specific to an audio track. */
    139 typedef struct {
    140   double rate;           /**< Sampling rate in Hz. */
    141   unsigned int channels; /**< Number of audio channels. */
    142   unsigned int depth;    /**< Bits per sample. */
    143   uint64_t  codec_delay; /**< Nanoseconds that must be discarded from the start. */
    144   uint64_t  seek_preroll;/**< Nanoseconds that must be discarded after a seek. */
    145 } nestegg_audio_params;
    146 
    147 /** Logging callback function pointer. */
    148 typedef void (* nestegg_log)(nestegg * context, unsigned int severity, char const * format, ...);
    149 
    150 /** Initialize a nestegg context.  During initialization the parser will
    151     read forward in the stream processing all elements until the first
    152     block of media is reached.  All track metadata has been processed at this point.
    153     @param context  Storage for the new nestegg context.  @see nestegg_destroy
    154     @param io       User supplied IO context.
    155     @param callback Optional logging callback function pointer.  May be NULL.
    156     @param max_offset Optional maximum offset to be read. Set -1 to ignore.
    157     @retval  0 Success.
    158     @retval -1 Error. */
    159 int nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t max_offset);
    160 
    161 /** Destroy a nestegg context and free associated memory.
    162     @param context #nestegg context to be freed.  @see nestegg_init */
    163 void nestegg_destroy(nestegg * context);
    164 
    165 /** Query the duration of the media stream in nanoseconds.
    166     @param context  Stream context initialized by #nestegg_init.
    167     @param duration Storage for the queried duration.
    168     @retval  0 Success.
    169     @retval -1 Error. */
    170 int nestegg_duration(nestegg * context, uint64_t * duration);
    171 
    172 /** Query the tstamp scale of the media stream in nanoseconds.
    173     Timecodes presented by nestegg have been scaled by this value
    174     before presentation to the caller.
    175     @param context Stream context initialized by #nestegg_init.
    176     @param scale   Storage for the queried scale factor.
    177     @retval  0 Success.
    178     @retval -1 Error. */
    179 int nestegg_tstamp_scale(nestegg * context, uint64_t * scale);
    180 
    181 /** Query the number of tracks in the media stream.
    182     @param context Stream context initialized by #nestegg_init.
    183     @param tracks  Storage for the queried track count.
    184     @retval  0 Success.
    185     @retval -1 Error. */
    186 int nestegg_track_count(nestegg * context, unsigned int * tracks);
    187 
    188 /** Query the start and end offset for a particular cluster.
    189     @param context     Stream context initialized by #nestegg_init.
    190     @param cluster_num Zero-based cluster number; order they appear in cues.
    191     @param max_offset  Optional maximum offset to be read. Set -1 to ignore.
    192     @param start_pos   Starting offset of the cluster. -1 means non-existant.
    193     @param end_pos     Starting offset of the cluster. -1 means non-existant or
    194                        final cluster.
    195     @param tstamp      Starting timestamp of the cluster.
    196     @retval  0 Success.
    197     @retval -1 Error. */
    198 int nestegg_get_cue_point(nestegg * context, unsigned int cluster_num,
    199                           int64_t max_offset, int64_t * start_pos,
    200                           int64_t * end_pos, uint64_t * tstamp);
    201 
    202 /** Seek to @a offset.  Stream will seek directly to offset.
    203     Should be used to seek to the start of a resync point, i.e. cluster; the
    204     parser will not be able to understand other offsets.
    205     @param context Stream context initialized by #nestegg_init.
    206     @param offset  Absolute offset in bytes.
    207     @retval  0 Success.
    208     @retval -1 Error. */
    209 int nestegg_offset_seek(nestegg * context, uint64_t offset);
    210 
    211 /** Seek @a track to @a tstamp.  Stream seek will terminate at the earliest
    212     key point in the stream at or before @a tstamp.  Other tracks in the
    213     stream will output packets with unspecified but nearby timestamps.
    214     @param context Stream context initialized by #nestegg_init.
    215     @param track   Zero based track number.
    216     @param tstamp  Absolute timestamp in nanoseconds.
    217     @retval  0 Success.
    218     @retval -1 Error. */
    219 int nestegg_track_seek(nestegg * context, unsigned int track, uint64_t tstamp);
    220 
    221 /** Query the type specified by @a track.
    222     @param context Stream context initialized by #nestegg_init.
    223     @param track   Zero based track number.
    224     @retval #NESTEGG_TRACK_VIDEO Track type is video.
    225     @retval #NESTEGG_TRACK_AUDIO Track type is audio.
    226     @retval -1 Error. */
    227 int nestegg_track_type(nestegg * context, unsigned int track);
    228 
    229 /** Query the codec ID specified by @a track.
    230     @param context Stream context initialized by #nestegg_init.
    231     @param track   Zero based track number.
    232     @retval #NESTEGG_CODEC_VP8    Track codec is VP8.
    233     @retval #NESTEGG_CODEC_VORBIS Track codec is Vorbis.
    234     @retval -1 Error. */
    235 int nestegg_track_codec_id(nestegg * context, unsigned int track);
    236 
    237 /** Query the number of codec initialization chunks for @a track.  Each
    238     chunk of data should be passed to the codec initialization functions in
    239     the order returned.
    240     @param context Stream context initialized by #nestegg_init.
    241     @param track   Zero based track number.
    242     @param count   Storage for the queried chunk count.
    243     @retval  0 Success.
    244     @retval -1 Error. */
    245 int nestegg_track_codec_data_count(nestegg * context, unsigned int track,
    246                                    unsigned int * count);
    247 
    248 /** Get a pointer to chunk number @a item of codec initialization data for
    249     @a track.
    250     @param context Stream context initialized by #nestegg_init.
    251     @param track   Zero based track number.
    252     @param item    Zero based chunk item number.
    253     @param data    Storage for the queried data pointer.
    254                    The data is owned by the #nestegg context.
    255     @param length  Storage for the queried data size.
    256     @retval  0 Success.
    257     @retval -1 Error. */
    258 int nestegg_track_codec_data(nestegg * context, unsigned int track, unsigned int item,
    259                              unsigned char ** data, size_t * length);
    260 
    261 /** Query the video parameters specified by @a track.
    262     @param context Stream context initialized by #nestegg_init.
    263     @param track   Zero based track number.
    264     @param params  Storage for the queried video parameters.
    265     @retval  0 Success.
    266     @retval -1 Error. */
    267 int nestegg_track_video_params(nestegg * context, unsigned int track,
    268                                nestegg_video_params * params);
    269 
    270 /** Query the audio parameters specified by @a track.
    271     @param context Stream context initialized by #nestegg_init.
    272     @param track   Zero based track number.
    273     @param params  Storage for the queried audio parameters.
    274     @retval  0 Success.
    275     @retval -1 Error. */
    276 int nestegg_track_audio_params(nestegg * context, unsigned int track,
    277                                nestegg_audio_params * params);
    278 
    279 /** Read a packet of media data.  A packet consists of one or more chunks of
    280     data associated with a single track.  nestegg_read_packet should be
    281     called in a loop while the return value is 1 to drive the stream parser
    282     forward.  @see nestegg_free_packet
    283     @param context Context returned by #nestegg_init.
    284     @param packet  Storage for the returned nestegg_packet.
    285     @retval  1 Additional packets may be read in subsequent calls.
    286     @retval  0 End of stream.
    287     @retval -1 Error. */
    288 int nestegg_read_packet(nestegg * context, nestegg_packet ** packet);
    289 
    290 /** Destroy a nestegg_packet and free associated memory.
    291     @param packet #nestegg_packet to be freed. @see nestegg_read_packet */
    292 void nestegg_free_packet(nestegg_packet * packet);
    293 
    294 /** Query the track number of @a packet.
    295     @param packet Packet initialized by #nestegg_read_packet.
    296     @param track  Storage for the queried zero based track index.
    297     @retval  0 Success.
    298     @retval -1 Error. */
    299 int nestegg_packet_track(nestegg_packet * packet, unsigned int * track);
    300 
    301 /** Query the time stamp in nanoseconds of @a packet.
    302     @param packet Packet initialized by #nestegg_read_packet.
    303     @param tstamp Storage for the queried timestamp in nanoseconds.
    304     @retval  0 Success.
    305     @retval -1 Error. */
    306 int nestegg_packet_tstamp(nestegg_packet * packet, uint64_t * tstamp);
    307 
    308 /** Query the number of data chunks contained in @a packet.
    309     @param packet Packet initialized by #nestegg_read_packet.
    310     @param count  Storage for the queried timestamp in nanoseconds.
    311     @retval  0 Success.
    312     @retval -1 Error. */
    313 int nestegg_packet_count(nestegg_packet * packet, unsigned int * count);
    314 
    315 /** Get a pointer to chunk number @a item of packet data.
    316     @param packet  Packet initialized by #nestegg_read_packet.
    317     @param item    Zero based chunk item number.
    318     @param data    Storage for the queried data pointer.
    319                    The data is owned by the #nestegg_packet packet.
    320     @param length  Storage for the queried data size.
    321     @retval  0 Success.
    322     @retval -1 Error. */
    323 int nestegg_packet_data(nestegg_packet * packet, unsigned int item,
    324                         unsigned char ** data, size_t * length);
    325 
    326 /** Returns discard_padding for given packet
    327     @param packet  Packet initialized by #nestegg_read_packet.
    328     @param discard_padding pointer to store discard padding in.
    329     @retval  0 Success.
    330     @retval -1 Error. */
    331 int nestegg_packet_discard_padding(nestegg_packet * packet,
    332                                    int64_t * discard_padding);
    333 
    334 /** Query the presence of cues.
    335     @param context  Stream context initialized by #nestegg_init.
    336     @retval 0 The media has no cues.
    337     @retval 1 The media has cues. */
    338 int nestegg_has_cues(nestegg * context);
    339 
    340 /**
    341  * Try to determine if the buffer looks like the beginning of a WebM file.
    342  *
    343  * @param buffer A buffer containing the beginning of a media file.
    344  * @param length The size of the buffer.
    345  * @retval 0 The file is not a WebM file.
    346  * @retval 1 The file is a WebM file. */
    347 int nestegg_sniff(unsigned char const * buffer, size_t length);
    348 
    349 #if defined(__cplusplus)
    350 }
    351 #endif
    352 
    353 #endif /* NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79 */
    354