# Oggz Write API

Oggz maintains a packet queue, such that you can independently add packets to the queue and write an Ogg bitstream. More...

## Typedefs
typedef int(* | OggzWriteHungry )(OGGZ *oggz, int empty, void *user_data)
| This is the signature of a callback which Oggz will call when oggz is hungry .
## Functions
int | oggz_write_set_hungry_callback (OGGZ *oggz, OggzWriteHungry hungry, int only_when_empty, void *user_data)
| Set a callback for Oggz to call when oggz is hungry .
int | oggz_write_feed (OGGZ *oggz, ogg_packet *op, long serialno, int flush, int *guard)
| Add a packet to oggz's packet queue.
long | oggz_write_output (OGGZ *oggz, unsigned char *buf, long n)
| Output data from an OGGZ handle.
long | oggz_write (OGGZ *oggz, long n)
| Write n bytes from an OGGZ handle.
long | oggz_write_get_next_page_size (OGGZ *oggz)
| Query the number of bytes in the next page to be written.

## Detailed Description

Oggz maintains a packet queue, such that you can independently add packets to the queue and write an Ogg bitstream.

There are two complementary methods for adding packets to the packet queue.

- by force feeding Oggz
- by using OggzHungry callbacks

As each packet is enqueued, its validity is checked against the framing constraints outlined in the Ogg basics section. If it does not pass these constraints, oggz_write_feed() will fail with an appropriate error code.

Note:
  - When writing, you can ensure that a packet starts on a new page by setting the flush parameter of oggz_write_feed() to OGGZ_FLUSH_BEFORE when enqueuing it. Similarly you can ensure that the last page a packet is written into won't contain any following packets by setting the flush parameter of oggz_write_feed() to OGGZ_FLUSH_AFTER.
  - The OGGZ_FLUSH_BEFORE and OGGZ_FLUSH_AFTER flags can be bitwise OR'd together to ensure that the packet will not share any pages with any other packets, either before or after.

## Typedef Documentation

typedef int(* OggzWriteHungry)(OGGZ *oggz, int empty, void *user_data)

This is the signature of a callback which Oggz will call when oggz is hungry .

Parameters:

  | oggz | The OGGZ handle
  | empty | A value of 1 indicates that the packet queue is currently empty. A value of 0 indicates that the packet queue is not empty.
  | user_data | A generic pointer you have provided earlier

Return values:

  | 0 | Continue
  | non-zero | Instruct Oggz to stop.

## Function Documentation

long oggz_write | ( | OGGZ * | oggz,
|  | long | n |
| ) |  |  |

Write n bytes from an OGGZ handle.

Oggz will call your write callback as needed.

Parameters:

  | oggz | An OGGZ handle previously opened for writing
  | n | A count of bytes to be written

Return values:

  | > 0 | The number of bytes successfully output
  | 0 | End of stream
  | OGGZ_ERR_RECURSIVE_WRITE | Attempt to initiate writing from within an OggzHungry callback
  | OGGZ_ERR_BAD_OGGZ | oggz does not refer to an existing OGGZ
  | OGGZ_ERR_INVALID | Operation not suitable for this OGGZ
  | OGGZ_ERR_STOP_OK | Writing was stopped by an OggzHungry callback returning OGGZ_STOP_OK
  | OGGZ_ERR_STOP_ERR | Reading was stopped by an OggzHungry callback returning OGGZ_STOP_ERR

int oggz_write_feed | ( | OGGZ * | oggz,
|  | ogg_packet * | op,
|  | long | serialno,
|  | int | flush,
|  | int * | guard |
| ) |  |  |

Add a packet to oggz's packet queue.

Parameters:

  | oggz | An OGGZ handle previously opened for writing
  | op | An ogg_packet with all fields filled in
  | serialno | Identify the logical bitstream in oggz to add the packet to
  | flush | Bitmask of OGGZ_FLUSH_BEFORE, OGGZ_FLUSH_AFTER
  | guard | A guard for nocopy, NULL otherwise

Return values:

  | 0 | Success
  | OGGZ_ERR_BAD_GUARD | guard specified has non-zero initialization
  | OGGZ_ERR_BOS | Packet would be bos packet of a new logical bitstream, but oggz has already written one or more non-bos packets in other logical bitstreams, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_EOS | The logical bitstream identified by serialno is already at eos, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_BAD_BYTES | op->bytes is invalid, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_BAD_B_O_S | op->b_o_s is invalid, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_BAD_GRANULEPOS | op->granulepos is less than that of an earlier packet within this logical bitstream, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_BAD_PACKETNO | op->packetno is less than that of an earlier packet within this logical bitstream, and oggz is not flagged OGGZ_NONSTRICT
  | OGGZ_ERR_BAD_SERIALNO | serialno does not identify an existing logical bitstream in oggz, and oggz is not flagged OGGZ_NONSTRICT or serialno is equal to -1, or serialno does not fit in 32 bits, ie. within the range (-(2^31), (2^31)-1)
  | OGGZ_ERR_BAD_OGGZ | oggz does not refer to an existing OGGZ
  | OGGZ_ERR_INVALID | Operation not suitable for this OGGZ
  | OGGZ_ERR_OUT_OF_MEMORY | Unable to allocate memory to queue packet

Note:
  If op->b_o_s is initialized to -1 before calling oggz_write_feed(), Oggz will fill it in with the appropriate value; ie. 1 for the first packet of a new stream, and 0 otherwise.

long oggz_write_get_next_page_size | ( | OGGZ * | oggz | ) |

Query the number of bytes in the next page to be written.

Parameters:

  | oggz | An OGGZ handle previously opened for writing

Return values:

  | >= 0 | The number of bytes in the next page
  | OGGZ_ERR_BAD_OGGZ | oggz does not refer to an existing OGGZ
  | OGGZ_ERR_INVALID | Operation not suitable for this OGGZ

long oggz_write_output | ( | OGGZ * | oggz,
|  | unsigned char * | buf,
|  | long | n |
| ) |  |  |

Output data from an OGGZ handle.

Oggz will call your write callback as needed.

Parameters:

  | oggz | An OGGZ handle previously opened for writing
  | buf | A memory buffer
  | n | A count of bytes to output

Return values:

  | > 0 | The number of bytes successfully output
  | 0 | End of stream
  | OGGZ_ERR_RECURSIVE_WRITE | Attempt to initiate writing from within an OggzHungry callback
  | OGGZ_ERR_BAD_OGGZ | oggz does not refer to an existing OGGZ
  | OGGZ_ERR_INVALID | Operation not suitable for this OGGZ
  | OGGZ_ERR_STOP_OK | Writing was stopped by an OggzHungry callback returning OGGZ_STOP_OK
  | OGGZ_ERR_STOP_ERR | Reading was stopped by an OggzHungry callback returning OGGZ_STOP_ERR

int oggz_write_set_hungry_callback | ( | OGGZ * | oggz,
|  | OggzWriteHungry | hungry,
|  | int | only_when_empty,
|  | void * | user_data |
| ) |  |  |

Set a callback for Oggz to call when oggz is hungry .

Parameters:

  | oggz | An OGGZ handle previously opened for writing
  | hungry | Your callback function
  | only_when_empty | When to call: a value of 0 indicates that Oggz should call hungry() after each and every packet is written; a value of 1 indicates that Oggz should call hungry() only when its packet queue is empty
  | user_data | Arbitrary data you wish to pass to your callback

Return values:

  | 0 | Success
  | OGGZ_ERR_BAD_OGGZ | oggz does not refer to an existing OGGZ
  | OGGZ_ERR_INVALID | Operation not suitable for this OGGZ

Note:
  Passing a value of 0 for only_when_empty allows you to feed new packets into oggz's packet queue on the fly.