123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- /*
- ** nsvlib.h - NSV file/bitstream reading/writing interface
- **
- ** Copyright (C) 2001-2002 Nullsoft, Inc.
- **
- ** Confidential Subject to NDA
- */
- #ifndef _NSVLIB_H_
- #define _NSVLIB_H_
- /*********************************************************************
- ** bitstream classes
- */
- #include "nsvbs.h"
- /*********************************************************************
- ** NSV packeting limits
- */
- #define NSV_MAX_AUDIO_LEN 0x8000 // 32kb
- #define NSV_MAX_VIDEO_LEN 0x80000 // 512kb
- #define NSV_MAX_AUX_LEN 0x8000 // 32kb for each aux stream
- #define NSV_MAX_AUXSTREAMS 15 // 15 aux streams maximum
- /*********************************************************************
- ** Constants for setting certain metadata items using addHdrMetaData()
- */
- #define METADATANAME_AUTHOR "Author"
- #define METADATANAME_TITLE "Title"
- #define METADATANAME_COPYRIGHT "Copyright"
- #define METADATANAME_COMMENT "Comment"
- #define METADATANAME_PROFILE "Profile"
- #define METADATANAME_FILEID "File ID"
- /*********************************************************************
- ** NSV type utility functions/macros
- */
- /*
- ** Use NSV_MAKETYPE() to quickly make NSV audio/video/aux types.
- ** ex: NSV_MAKETYPE('R','G','B','A')
- */
- #define NSV_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24))
- /*
- ** These functions convert types to and from strings.
- */
- /* nsv_type_to_string() converts an NSV type to a string.
- * out must be at least 5 bytes long. If 't' is not a valid type,
- * then out will be set to an empty string
- * ex:
- * char out[5];
- * nsv_type_to_string(NSV_MAKETYPE('R','G','B','A'),out);
- * strcmp(out,"RGBA") == 0
- */
- void nsv_type_to_string(unsigned int t, char *out);
- /* nsv_string_to_type() converts a string to an NSV type.
- * Returns 0 if the type is not valid.
- * ex: nsv_string_to_type("RGBA") == NSV_MAKETYPE('R','G','B','A')
- */
- unsigned int nsv_string_to_type(char *in);
- /*********************************************************************
- ** NSV bitstream packeting/unpacketing classes
- */
- /* nsv_Packeter is used to packet audio/video/auxiliary data into
- * a bitstream.
- *
- * ex:
- * nsv_Packeter p;
- * nsv_OutBS bs;
- * p.setVidFmt(NSV_MAKETYPE('R','G','B','A'),320,240,30.0);
- * p.setAudFmt(NSV_MAKETYPE('P','C','M',' '));
- * for (;;) {
- * doEncodeAudioAndVideo();
- * p.setSyncFrame(is_keyframe);
- * p.setSyncOffset(av_sync_offset);
- * p.setAudio(audio_data,audio_len);
- * p.setVideo(video_data,video_len);
- * p.clearAuxChannels(); // you can add aux channels if you want
- * if (p.packet(bs)) error();
- * int outbuflen;
- * void *outbuf=bs.get(&outbuflen);
- * fwrite(outbuf,outbuflen,1,fp); // write output
- * bs.clear(); // clear bitstream
- * }
- *
- */
- class nsv_Packeter {
- public:
- nsv_Packeter();
- ~nsv_Packeter();
- // init (per file) calls
- void setVidFmt(unsigned int vfmt, unsigned int w, unsigned int h, double frt);
- void setAudFmt(unsigned int afmt) { audfmt=afmt; }
- // per frame calls
- void setSyncFrame(int is_syncframe) { is_sync_frame=is_syncframe; }
- void setSyncOffset(int syncoffs) { syncoffset_cur=syncoffs; }
- void setAudio(void *a, int a_len) { audio=a; audio_len=a_len; }
- void setVideo(void *v, int v_len) { video=v; video_len=v_len; }
- int addAuxChannel(unsigned int fmt, void *data, int data_len) // 0 on success
- {
- if (aux_used >= NSV_MAX_AUXSTREAMS) return -1;
- aux[aux_used]=data;
- aux_len[aux_used]=data_len;
- aux_types[aux_used]=fmt;
- aux_used++;
- return 0;
- }
- void clearAuxChannels() { aux_used=0; }
- int packet(nsv_OutBS &bs); // returns 0 on success
- // some utility getting functions
- unsigned int getAudFmt() { return audfmt; }
- unsigned int getVidFmt() { return vidfmt; }
- unsigned int getWidth() { return width; }
- unsigned int getHeight() { return height; }
- double getFrameRate() { return framerate; }
- private:
- unsigned char framerate_idx;
- unsigned int vidfmt;
- unsigned int audfmt;
- unsigned int width;
- unsigned int height;
- double framerate;
- int syncoffset_cur;
- int aux_used;
- void *aux[NSV_MAX_AUXSTREAMS];
- int aux_len[NSV_MAX_AUXSTREAMS];
- unsigned int aux_types[NSV_MAX_AUXSTREAMS];
- int is_sync_frame;
- void *audio;
- int audio_len;
- void *video;
- int video_len;
- };
- /* nsv_Unpacketer is used to unpacket a bitstream into audio/video/auxiliary data
- * to decode, use an nsv_InBS object with data, and call unpacket().
- * ex:
- * nsv_Unpacketer up;
- * nsv_InBS in;
- * nsv_InBS videoout, audioout;
- * up.setVideoOut(&videoout);
- * up.setAudioOut(&audioout);
- * for (;;) {
- * int ret=up.unpacket(in);
- * if (ret < 0) break; // eof
- * if (ret > 0) add_data_to_bitstream(&in,ret);
- * if (!ret) { // got frame
- * int vl=videoout.getbits(32);
- * int al=videoout.getbits(32);
- * char *vd=(char*)videoout.getcurbyteptr();
- * char *ad=(char*)audioout.getcurbyteptr();
- * doDecode(vd,vl,ad,al);
- * videoout.seek(vl*8);
- * audioout.seek(al*8);
- * videoout.compact(); // free memory up
- * audioout.compact(); // free memory up
- * in.compact(); // free memory up
- * }
- * }
- */
- class nsv_Unpacketer {
- public:
- nsv_Unpacketer() { reset(); }
- ~nsv_Unpacketer() { }
- void reset(int full=1); // if full, full reset is done.
- // if not, then it is a partial reset (ie for seeking)
- // when EOF is set, the unpacketer will fail instead of requesting more data at the
- // end; it will also not require that the next frame be available for sync
- // (normally it looks ahead to verify data)
- void setEof(int eof=1) { m_eof=eof; }
- int getEof() { return m_eof; }
- // use these to set where the unpacketer writes the output of each stream
- // set to NULL to ignore output of that stream
-
- void setAudioOut(nsv_InBS *output=NULL) { m_audiobs=output; }
- // the format of the audio data written to the output is:
- // 32 bits: length of frame
- // ? bytes: audio data
- // (to read):
- // int l=output->getbits(32);
- // decode_audio(output->getcurbyteptr(),l);
- // output->seek(l*8);
- void setVideoOut(nsv_InBS *output=NULL) { m_videobs=output; }
- // the format of the video data written to the output is:
- // 32 bits: length of frame
- // ? bytes: video data
- // (to read):
- // int l=output->getbits(32);
- // decode_video(output->getcurbyteptr(),l);
- // output->seek(l*8);
- void setAuxOut(nsv_InBS *output=NULL) { m_auxbs=output; }
- // the format of the aux data written to the output is:
- // 32 bits: length of frame
- // 32 bits: type of aux data
- // ? bytes: aux data
- // (to read):
- // int l=output->getbits(32);
- // int type=output->getbits(32);
- // decode_aux(output->getcurbyteptr(),l);
- // output->seek(l*8);
- // aux is different than audio/video in that it includes a 32 bit
- // type value that is not included in the length.
- // returns 0 on success, >0 on needs (at least X bytes) more data,
- // -1 on error (eof and no header found)
- int unpacket(nsv_InBS &bs);
- // do we have enough sync to determine formats/widths/heights/framerates
- int isValid() { return valid; }
-
- // are we fully synched?
- int isSynched() { return synched; }
- // get sync offset from when we first synched up
- signed int getSyncOffset() { return (signed int) syncoffset; }
- // get sync offset from current frame (not usually used)
- signed int getCurSyncOffset() { return (signed int) syncoffset_cur; }
- // get video, audio, width, height, framerate formats.
- unsigned int getVidFmt() { return vidfmt; }
- unsigned int getAudFmt() { return audfmt; }
- unsigned int getWidth() { return width; }
- unsigned int getHeight() { return height; }
- double getFrameRate() { return framerate; }
- unsigned char getFrameRateIdx() { return framerate_idx; }
- // is current frame a sync frame?
- int isSynchFrame() { return is_sync_frame; }
- private:
- nsv_InBS *m_audiobs, *m_videobs, *m_auxbs;
- int valid; // contents of stream info are valid for syncing
- int synched; // turns off anal packet checking
- unsigned int vidfmt;
- unsigned int audfmt;
- unsigned int width;
- unsigned int height;
- double framerate;
- int is_sync_frame;
- unsigned char framerate_idx;
- int syncoffset;
- int syncoffset_cur;
- int m_eof;
- };
- /*********************************************************************
- ** NSV file header reading/writing functions
- */
- typedef struct {
- // header_size is the size of NSV header. nsv_writeheader() and nsv_readheader()
- // will set this automatically
- unsigned int header_size;
- // file_lenbytes is the size of the NSV bitstream (not including the header size)
- // this can be 0xFFFFFFFF to signify unknown length
- unsigned int file_lenbytes;
- // file_lenms is the length of the NSV bitstream in milliseconds.
- // this can be 0xFFFFFFFF to signify unknown length
- unsigned int file_lenms;
- // metadata_len describes the length of the metadata.
- unsigned int metadata_len;
- // toc_alloc describes the allocated length of the TOC (in entries).
- // set this to zero to use toc_size (recommended).
- unsigned int toc_alloc;
- // toc_size describes the used size of the TOC (in entries)
- // set this to zero to disable the TOC. When using toc_ex,
- // this must be < toc_alloc/2 (if using nsv_writeheader, and
- // toc_size is too big, toc_alloc will be grown automatically.
- unsigned int toc_size;
- // buffer which contains the TOC. this will be automatically
- // allocated when using nsv_readheader(), but you should allocate
- // this yourself when using nsv_writeheader()
- unsigned int *toc;
- // if used, contains time pairs (in frames) for the offset. this will be
- // automatically allocated when using nsv_readheader(), but you should allocate
- // this yourself when using nsv_writeheader()
- // DO NOT FREE THIS VALUE IF IT WAS ALLOCATED FROM NSV_READHEADER. :)
- // (it is just an extension of toc, which should be freed with free())
- unsigned int *toc_ex;
- // buffer which contains metadata. allocated when using nsv_readheader(),
- // but you should allocate this yourself when using nsv_writeheader()
- // note that nsv_readheader() will NULL terminate this buffer.
- void *metadata;
- } nsv_fileHeader;
- // nsv_writeheader() writes the NSV file header to the bitstream bs.
- // the NSV file header will be at LEAST padto bytes long (usually
- // you will leave padto to 0)
- void nsv_writeheader(nsv_OutBS &bs, nsv_fileHeader *hdr, unsigned int padto);
- // nsv_readheader() reads an NSV file header from a bitstream bs.
- // if the return value is less than zero, then there is no NSV
- // file header in bs. if the return value is zero, the NSV file
- // header was succesfully read. if the return value is positive,
- // then at least that many more bytes are needed to decode the
- // header.
- // ex:
- // nsv_InBS bs;
- // nsv_fileHeader hdr;
- // for (;;) {
- // int ret=nsv_readheader(bs,&hdr);
- // if (ret<=0) break;
- // addBytesToBs(bs,ret);
- // }
- // if (hdr.header_size) { we_got_valid_header(&hdr); }
- //
- int nsv_readheader(nsv_InBS &bs, nsv_fileHeader *hdr);
- // nsv_getmetadata() retrieves a metadata item from the metadata
- // block. if that item is not found, NULL is returned.
- // Note that the value returned by nsv_getmetadata() has been
- // malloc()'d, and you must free() it when you are done.
- // ex:
- // char *v=nsv_getmetadata(hdr.metadata,"TITLE");
- // if (v) printf("title=%s\n",v);
- // free(v);
- //
- char *nsv_getmetadata(void *metadata, char *name);
- #endif//_NSVLIB_H_
|