Blame tools/skeleton.c

Packit 664db3
/*
Packit 664db3
 * skeleton.c
Packit 664db3
 * author: Tahseen Mohammad
Packit 664db3
 */
Packit 664db3
Packit 664db3
/* This file depends on WORDS_BIGENDIAN being defined to 1 if the host
Packit 664db3
 * processor stores words with the most significant byte first (like Motorola
Packit 664db3
 * and SPARC, unlike Intel and VAX). 
Packit 664db3
 * On little endian systems, WORDS_BIGENDIAN should be undefined.
Packit 664db3
 *
Packit 664db3
 * When using GNU Autotools, the correct value will be written into config.h
Packit 664db3
 * if the autoconf macro AC_C_BIGENDIAN is called in configure.ac.
Packit 664db3
 */
Packit 664db3
#ifdef HAVE_CONFIG_H
Packit 664db3
#include "config.h"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#include <stdlib.h>
Packit 664db3
#include <string.h>
Packit 664db3
#include <stdio.h>
Packit 664db3
Packit 664db3
#include <ogg/ogg.h>
Packit 664db3
Packit 664db3
#include "skeleton.h"
Packit 664db3
Packit 664db3
#ifdef WIN32                                                                   
Packit 664db3
#define snprintf _snprintf
Packit 664db3
#endif
Packit 664db3
Packit 664db3
static  unsigned short
Packit 664db3
_le_16 (unsigned short s)
Packit 664db3
{ 
Packit 664db3
  unsigned short ret=s;
Packit 664db3
#ifdef WORDS_BIGENDIAN
Packit 664db3
  ret = (s>>8) & 0x00ffU;
Packit 664db3
  ret += (s<<8) & 0xff00U;
Packit 664db3
#endif
Packit 664db3
  return ret;
Packit 664db3
}
Packit 664db3
Packit 664db3
static  ogg_uint32_t
Packit 664db3
_le_32 (ogg_uint32_t i)
Packit 664db3
{  
Packit 664db3
   ogg_uint32_t ret=i;
Packit 664db3
#ifdef WORDS_BIGENDIAN
Packit 664db3
   ret =  (i>>24);
Packit 664db3
   ret += (i>>8) & 0x0000ff00;
Packit 664db3
   ret += (i<<8) & 0x00ff0000;
Packit 664db3
   ret += (i<<24);
Packit 664db3
#endif
Packit 664db3
   return ret;
Packit 664db3
}
Packit 664db3
Packit 664db3
static  ogg_int64_t
Packit 664db3
_le_64 (ogg_int64_t l)
Packit 664db3
{ 
Packit 664db3
  ogg_int64_t ret=l;
Packit 664db3
  unsigned char *ucptr = (unsigned char *)&ret;
Packit 664db3
#ifdef WORDS_BIGENDIAN
Packit 664db3
  unsigned char temp;
Packit 664db3
Packit 664db3
  temp = ucptr [0] ;
Packit 664db3
  ucptr [0] = ucptr [7] ;
Packit 664db3
  ucptr [7] = temp ;
Packit 664db3
Packit 664db3
  temp = ucptr [1] ;
Packit 664db3
  ucptr [1] = ucptr [6] ;
Packit 664db3
  ucptr [6] = temp ;
Packit 664db3
Packit 664db3
  temp = ucptr [2] ;
Packit 664db3
  ucptr [2] = ucptr [5] ;
Packit 664db3
  ucptr [5] = temp ;
Packit 664db3
Packit 664db3
  temp = ucptr [3] ;
Packit 664db3
  ucptr [3] = ucptr [4] ;
Packit 664db3
  ucptr [4] = temp ;
Packit 664db3
Packit 664db3
#endif
Packit 664db3
  return (*(ogg_int64_t *)ucptr);
Packit 664db3
}
Packit 664db3
Packit 664db3
/* write an ogg_page to a file pointer */
Packit 664db3
int write_ogg_page_to_file(ogg_page *og, FILE *out) {
Packit 664db3
   int written;
Packit 664db3
   
Packit 664db3
   written = fwrite(og->header,1, og->header_len, out);
Packit 664db3
   written += fwrite(og->body,1, og->body_len, out);
Packit 664db3
Packit 664db3
   return written;
Packit 664db3
}
Packit 664db3
Packit 664db3
int add_message_header_field(fisbone_packet *fp, 
Packit 664db3
                                        char *header_key, 
Packit 664db3
                                        char *header_value) {
Packit 664db3
Packit 664db3
    /* size of both key and value + ': ' + CRLF */
Packit 664db3
    int this_message_size = strlen(header_key) + strlen(header_value) + 4;
Packit 664db3
    if (fp->message_header_fields == NULL) {
Packit 664db3
        fp->message_header_fields = _ogg_calloc(this_message_size+1, sizeof(char));
Packit 664db3
    } else {
Packit 664db3
        int new_size = (fp->current_header_size + this_message_size+1) * sizeof(char);
Packit 664db3
        fp->message_header_fields = _ogg_realloc(fp->message_header_fields, new_size);
Packit 664db3
    }
Packit 664db3
    snprintf(fp->message_header_fields + fp->current_header_size, 
Packit 664db3
                this_message_size+1, 
Packit 664db3
                "%s: %s\r\n", 
Packit 664db3
                header_key, 
Packit 664db3
                header_value);
Packit 664db3
    fp->current_header_size += this_message_size;
Packit 664db3
Packit 664db3
    return 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
/* create a ogg_packet from a fishead_packet structure */
Packit 664db3
ogg_packet ogg_from_fishead(fishead_packet *fp) {
Packit 664db3
Packit 664db3
    ogg_packet op;
Packit 664db3
Packit 664db3
    memset(&op, 0, sizeof(op));
Packit 664db3
    op.packet = _ogg_calloc(FISHEAD_SIZE, sizeof(unsigned char));
Packit 664db3
    memset(op.packet, 0, FISHEAD_SIZE);
Packit 664db3
Packit 664db3
    memcpy (op.packet, FISHEAD_IDENTIFIER, 8); /* identifier */
Packit 664db3
    *((ogg_uint16_t*)(op.packet+8)) = _le_16 (SKELETON_VERSION_MAJOR); /* version major */
Packit 664db3
    *((ogg_uint16_t*)(op.packet+10)) = _le_16 (SKELETON_VERSION_MINOR); /* version minor */
Packit 664db3
    *((ogg_int64_t*)(op.packet+12)) = _le_64 (fp->ptime_n); /* presentationtime numerator */
Packit 664db3
    *((ogg_int64_t*)(op.packet+20)) = _le_64 (fp->ptime_d); /* presentationtime denominator */
Packit 664db3
    *((ogg_int64_t*)(op.packet+28)) = _le_64 (fp->btime_n); /* basetime numerator */
Packit 664db3
    *((ogg_int64_t*)(op.packet+36)) = _le_64 (fp->btime_d); /* basetime denominator */
Packit 664db3
    /* TODO: UTC time, set to zero for now */
Packit 664db3
Packit 664db3
    op.b_o_s = 1;   /* its the first packet of the stream */
Packit 664db3
    op.e_o_s = 0;   /* its not the last packet of the stream */
Packit 664db3
    op.bytes = FISHEAD_SIZE;  /* length of the packet in bytes */
Packit 664db3
Packit 664db3
    return op;
Packit 664db3
}
Packit 664db3
Packit 664db3
/* create a ogg_packet from a fisbone_packet structure. 
Packit 664db3
 * call this method after the fisbone_packet is filled and all message header fields are added
Packit 664db3
 * by calling add_message_header_field method.
Packit 664db3
 */
Packit 664db3
ogg_packet ogg_from_fisbone(fisbone_packet *fp) {
Packit 664db3
    
Packit 664db3
    ogg_packet op;
Packit 664db3
    int packet_size = FISBONE_SIZE + fp->current_header_size;
Packit 664db3
Packit 664db3
    memset (&op, 0, sizeof (op));       
Packit 664db3
    op.packet = _ogg_calloc (packet_size, sizeof(unsigned char));
Packit 664db3
    memset (op.packet, 0, packet_size);
Packit 664db3
    memcpy (op.packet, FISBONE_IDENTIFIER, 8); /* identifier */
Packit 664db3
    *((ogg_uint32_t*)(op.packet+8)) = _le_32 (FISBONE_MESSAGE_HEADER_OFFSET); /* offset of the message header fields */
Packit 664db3
    *((ogg_uint32_t*)(op.packet+12)) = _le_32 (fp->serial_no); /* serialno of the respective stream */
Packit 664db3
    *((ogg_uint32_t*)(op.packet+16)) = _le_32 (fp->nr_header_packet); /* number of header packets */
Packit 664db3
    *((ogg_int64_t*)(op.packet+20)) = _le_64 (fp->granule_rate_n); /* granulrate numerator */
Packit 664db3
    *((ogg_int64_t*)(op.packet+28)) = _le_64 (fp->granule_rate_d); /* granulrate denominator */
Packit 664db3
    *((ogg_int64_t*)(op.packet+36)) = _le_64 (fp->start_granule); /* start granule */
Packit 664db3
    *((ogg_uint32_t*)(op.packet+44)) = _le_32 (fp->preroll); /* preroll, for theora its 0 */
Packit 664db3
    *(op.packet+48) = fp->granule_shift; /* granule shift */
Packit 664db3
    memcpy((op.packet+FISBONE_SIZE), fp->message_header_fields, fp->current_header_size);
Packit 664db3
Packit 664db3
    op.b_o_s = 0;
Packit 664db3
    op.e_o_s = 0;
Packit 664db3
    op.bytes = packet_size; /* size of the packet in bytes */
Packit 664db3
Packit 664db3
    return op;
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
Packit 664db3
int add_fishead_to_stream(ogg_stream_state *os, fishead_packet *fp) {
Packit 664db3
Packit 664db3
    ogg_packet op;
Packit 664db3
Packit 664db3
    op = ogg_from_fishead(fp);
Packit 664db3
    ogg_stream_packetin(os, &op);
Packit 664db3
    _ogg_free(op.packet);
Packit 664db3
Packit 664db3
    return 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
int add_fisbone_to_stream(ogg_stream_state *os, fisbone_packet *fp) {
Packit 664db3
Packit 664db3
    ogg_packet op;
Packit 664db3
Packit 664db3
    op = ogg_from_fisbone(fp);
Packit 664db3
    ogg_stream_packetin(os, &op);
Packit 664db3
    _ogg_free(op.packet);
Packit 664db3
Packit 664db3
    return 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
int add_eos_packet_to_stream(ogg_stream_state *os) {
Packit 664db3
Packit 664db3
    ogg_packet op;
Packit 664db3
Packit 664db3
    memset (&op, 0, sizeof(op));
Packit 664db3
    op.e_o_s = 1;
Packit 664db3
    ogg_stream_packetin(os, &op);
Packit 664db3
Packit 664db3
    return 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
int flush_ogg_stream_to_file(ogg_stream_state *os, FILE *out) {
Packit 664db3
Packit 664db3
    ogg_page og;
Packit 664db3
    int result;
Packit 664db3
Packit 664db3
    while((result = ogg_stream_flush(os, &og)))
Packit 664db3
    {
Packit 664db3
        if(!result) break;
Packit 664db3
        result = write_ogg_page_to_file(&og, out);
Packit 664db3
        if(result != og.header_len + og.body_len)
Packit 664db3
            return 1;
Packit 664db3
    }
Packit 664db3
Packit 664db3
    return 0;
Packit 664db3
}