Main Page | Modules | Data Structures | File List | Globals | Related Pages

Reading from files and file descriptors
[Reading]

If the Annodex media you wish to access is directly available as a local file or via a file descriptor (such as a network socket), it can be directly opened as follows:

This procedure is illustrated in src/examples/print-title-file.c:

#include <stdio.h>
#include <annodex/annodex.h>

static char buf[102400];

static int
read_head (ANNODEX * anx, const AnxHead * head, void * user_data)
{
  puts (head->title);
  return ANX_CONTINUE;
}

int
main (int argc, char *argv[])
{
  ANNODEX * anx = NULL;
  char * filename;
  long n;

  if (argc != 2) {
    fprintf (stderr, "Usage: %s file.anx\n", argv[0]);
    exit (1);
  }

  filename = argv[1];

  anx = anx_open (filename, ANX_READ);

  anx_set_read_head_callback (anx, read_head);

  while ((n = anx_read (anx, 1024)) > 0);

  anx_close (anx);

  exit (0);
}

Reading from memory buffers

Sometimes it is not possible to provide a file descriptor for a data source; for example, if the data is extracted from a high level library. In this case, you must directly input the data to libannodex using memory buffers as follows:

This procedure is illustrated in src/examples/print-title-memory.c:

#include <stdio.h>
#include <annodex/annodex.h>

static int
read_head (ANNODEX * anx, const AnxHead * head, void * user_data)
{
  puts (head->title);
  return ANX_CONTINUE;
}

int
main (int argc, char *argv[])
{
  ANNODEX * anx = NULL;
  unsigned char buf[1024];
  long n = 1024;

  anx = anx_new (ANX_READ);

  anx_set_read_head_callback (anx, read_head);

  while (n > 0) {
    /* Fill a memory buffer */
    n = fread (buf, 1, 1024, stdin);

    /* Input that memory buffer into the annodex */
    n = anx_reader_input (anx, buf, n);
  }

  anx_close (anx);

  exit (0);
}

Advanced management of AnxRead* callbacks

You retain control of the number of bytes read or input, and the callbacks you provide can instruct libannodex to immediately return control back to your application.

These mechanisms are illustrated in src/examples/print-lots.c:

#include <stdio.h>
#include <string.h>
#include <annodex/annodex.h>

struct my_data {
  char * filename;
  long interesting_serialno;
  int interesting_media_packets;
  int done;
};

static int
read_stream (ANNODEX * anx, double timebase, char * utc, void * user_data)
{
  struct my_data * happy = (struct my_data *) user_data;

  printf ("Welcome to %s! The timebase is %f\n", happy->filename, timebase);
  return ANX_CONTINUE;
}

static int
read_track (ANNODEX * anx, long serialno, char * id, char * mime_type,
            anx_int64_t granule_rate_n, anx_int64_t granule_rate_d,
            int nr_header_packets, void * user_data)
{
  struct my_data * happy = (struct my_data *) user_data;

  /* Ignore the annotations track, we don't find it interesting! */
  if (!strcmp (mime_type, "text/x-annodex")) return ANX_CONTINUE;

  printf ("Our first track has mime-type %s and granule rate %lld/%lld.\n",
          mime_type, granule_rate_n, granule_rate_d);

  printf ("We will remember it by its serial number %ld and mark it with crosses.\n", serialno);
  happy->interesting_serialno = serialno;

  /* We don't care about any other tracks! */
  anx_set_read_substream_callback (anx, NULL);

  return ANX_CONTINUE;
}

static int
read_media (ANNODEX * annodex, unsigned char * buf, long n,
            long serialno, anx_int64_t granulepos, void * user_data)
{
  struct my_data * happy = (struct my_data *) user_data;

  if (happy->done) {
    putchar ('!');
  } else if (serialno == happy->interesting_serialno) {
    happy->interesting_media_packets++;
    putchar ('+');
  } else {
    putchar ('.');
  }

  return ANX_CONTINUE;
}

static int
read_anchor3 (ANNODEX * anx, const AnxAnchor * anchor, void * user_data)
{
  struct my_data * happy = (struct my_data *) user_data;

  printf ("\nAnd the third anchor links to %s\n", anchor->href);

  happy->done = 1;

  printf ("This completes our whirlwind tour of the first three anchors!\n");
  return ANX_STOP_OK;
}

static int
read_anchor2 (ANNODEX * anx, const AnxAnchor * anchor, void * user_data)
{
  printf ("\nThe second anchor links to %s\n", anchor->href);
  anx_set_read_anchor_callback (anx, read_anchor3);
  return ANX_CONTINUE;
}

static int
read_anchor1 (ANNODEX * anx, const AnxAnchor * anchor, void * user_data)
{
  printf ("\nThe first anchor links to %s\n", anchor->href);
  anx_set_read_anchor_callback (anx, read_anchor2);
  return ANX_CONTINUE;
}

int
main (int argc, char *argv[])
{
  ANNODEX * anx = NULL;
  struct my_data me;
  long n;

  if (argc != 2) {
    fprintf (stderr, "Usage: %s file.anx\n", argv[0]);
    exit (1);
  }

  me.filename = argv[1];
  me.interesting_serialno = -1;
  me.interesting_media_packets = 0;
  me.done = 0;

  anx = anx_open (me.filename, ANX_READ);

  anx_set_read_stream_callback (anx, read_stream);
  anx_set_read_substream_callback (anx, read_track);
  anx_set_read_media_callback (anx, read_media);
  anx_set_read_anchor_callback (anx, read_anchor1);

  anx_set_user_data (anx, &me);

  while (!me.done && (n = anx_read (anx, 1024)) > 0);

  printf ("%d packets from the first track (serialno %ld) were received\n",
          me.interesting_media_packets, me.interesting_serialno);
  printf ("before the third anchor.\n");

  anx_close (anx);

  exit (0);
}

which produces output like:

Welcome to /tmp/alien_song-ogg.anx! The timebase is 20.000000 Our first track has mime-type video/x-theora and granule rate 1536/1. We will remember it by its serial number 1810353996 and mark it with crosses. +...+++++++++++++++++...................................++++++++++++++.......... ......................++++++++++++..............................++++++++++++++++ ++++..............................+++++++++++++................................. ...++++++++++++++++++++++................................++++++++++++++......... ........................++++++++++++++++....................................++++ ++++++++++.......................................++++++++++++++................. ......+++++++++++++.......................+++++++++++++......................... ...+++++++++++++..................................+++++++++++++................. ......+++++++++++++...............................++++++++++++++................ ..........+++++++++++..........................++++++++++++++................... .....++++++++++++.......................++++++++++++........................++++ ++++++++........................+++++++++++++........................+++++++++++ +++++.......................+++++++++++.......................+++++++++++++++++. ......................+++++++++++++........................++++++++++........... .............+++++++++++.......................++++++++++++++++++............... ........++++++++........................+++++++++++++++++....................... ++++++++.......................+++++++++++++++++........................++++++++ ++++++...........................+++++++++++........................++++++++++++ +++........................+++++++++++.......................++++++++++++++..... .................++++++++++++++..............................++++++++++......... .........................++++++++++++................................+++++++++++ +++...................................++++++ The first anchor links to http://www.mars.int/ + The second anchor links to http://www.pluto.int/ +++......................+++++++++++.............................+++++++++++.... ...........................+++++++++++.......................................... .......+++++++++++++...........................+++++++++++...................... .......+

And the third anchor links to http://www.venus.int/ This completes our whirlwind tour of the first three anchors!

639 packets from the first track (serialno 1810353996) were received before the third anchor.


Generated on Sun Sep 21 21:29:22 2003 for libannodex by doxygen 1.3.2