Sat Mar 24 23:28:46 2007

Asterisk developer's documentation


format_ogg_vorbis.c File Reference

OGG/Vorbis streams. More...

#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisenc.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"

Include dependency graph for format_ogg_vorbis.c:

Go to the source code of this file.

Data Structures

struct  ast_filestream

Defines

#define BLOCK_SIZE   4096
#define SAMPLES_MAX   160

Functions

 AST_MUTEX_DEFINE_STATIC (ogg_vorbis_lock)
char * description ()
 Provides a description of the module.
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module ()
 Initialize the module.
static void ogg_vorbis_close (struct ast_filestream *s)
 Close a OGG/Vorbis filestream.
static char * ogg_vorbis_getcomment (struct ast_filestream *s)
static struct ast_filestreamogg_vorbis_open (FILE *f)
 Create a new OGG/Vorbis filestream and set it up for reading.
static struct ast_frameogg_vorbis_read (struct ast_filestream *s, int *whennext)
 Read a frame full of audio data from the filestream.
static struct ast_filestreamogg_vorbis_rewrite (FILE *f, const char *comment)
 Create a new OGG/Vorbis filestream and set it up for writing.
static int ogg_vorbis_seek (struct ast_filestream *s, long sample_offset, int whence)
 Seek to a specific position in an OGG/Vorbis filestream.
static long ogg_vorbis_tell (struct ast_filestream *s)
static int ogg_vorbis_trunc (struct ast_filestream *s)
 Trucate an OGG/Vorbis filestream.
static int ogg_vorbis_write (struct ast_filestream *s, struct ast_frame *f)
 Write audio data from a frame to an OGG/Vorbis filestream.
static int read_samples (struct ast_filestream *s, float ***pcm)
 Get audio data.
int unload_module ()
 Cleanup all module structures, sockets, etc.
int usecount ()
 Provides a usecount.
static void write_stream (struct ast_filestream *s)
 Write out any pending encoded data.

Variables

static char * desc = "OGG/Vorbis audio"
static char * exts = "ogg"
static int glistcnt = 0
static char * name = "ogg_vorbis"


Detailed Description

OGG/Vorbis streams.

Definition in file format_ogg_vorbis.c.


Define Documentation

#define BLOCK_SIZE   4096
 

Definition at line 53 of file format_ogg_vorbis.c.

Referenced by ogg_vorbis_open(), and read_samples().

#define SAMPLES_MAX   160
 

Definition at line 52 of file format_ogg_vorbis.c.

Referenced by ogg_vorbis_read().


Function Documentation

AST_MUTEX_DEFINE_STATIC ogg_vorbis_lock   ) 
 

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 660 of file format_ogg_vorbis.c.

References desc.

00661 {
00662    return desc;
00663 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 666 of file format_ogg_vorbis.c.

References ASTERISK_GPL_KEY.

00667 {
00668    return ASTERISK_GPL_KEY;
00669 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 636 of file format_ogg_vorbis.c.

References ast_format_register(), AST_FORMAT_SLINEAR, exts, name, ogg_vorbis_close(), ogg_vorbis_getcomment(), ogg_vorbis_open(), ogg_vorbis_read(), ogg_vorbis_rewrite(), ogg_vorbis_seek(), ogg_vorbis_tell(), ogg_vorbis_trunc(), and ogg_vorbis_write().

static void ogg_vorbis_close struct ast_filestream s  )  [static]
 

Close a OGG/Vorbis filestream.

Parameters:
s A OGG/Vorbis filestream.

Definition at line 412 of file format_ogg_vorbis.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), free, glistcnt, LOG_WARNING, s, and write_stream().

Referenced by load_module().

00413 {
00414    if(ast_mutex_lock(&ogg_vorbis_lock)) {
00415       ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
00416       return;
00417    }
00418    glistcnt--;
00419    ast_mutex_unlock(&ogg_vorbis_lock);
00420    ast_update_use_count();
00421 
00422    if(s->writing) {
00423       /* Tell the Vorbis encoder that the stream is finished
00424        * and write out the rest of the data */
00425       vorbis_analysis_wrote(&s->vd, 0);
00426       write_stream(s);
00427    }
00428 
00429    ogg_stream_clear(&s->os);
00430    vorbis_block_clear(&s->vb);
00431    vorbis_dsp_clear(&s->vd);
00432    vorbis_comment_clear(&s->vc);
00433    vorbis_info_clear(&s->vi);
00434 
00435    if(s->writing) {
00436       ogg_sync_clear(&s->oy);
00437    }
00438    
00439    fclose(s->f);
00440    free(s);
00441 }

static char* ogg_vorbis_getcomment struct ast_filestream s  )  [static]
 

Definition at line 631 of file format_ogg_vorbis.c.

References ast_log().

Referenced by load_module().

00631                                                              {
00632    ast_log(LOG_WARNING, "Getting comments is not supported on OGG/Vorbis streams!\n");
00633    return NULL;
00634 }

static struct ast_filestream* ogg_vorbis_open FILE *  f  )  [static]
 

Create a new OGG/Vorbis filestream and set it up for reading.

Parameters:
f File that points to on disk storage of the OGG/Vorbis data.
Returns:
The new filestream.

Definition at line 100 of file format_ogg_vorbis.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), BLOCK_SIZE, ast_filestream::buffer, ast_filestream::bytes, free, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, and result.

Referenced by load_module().

00101 {
00102    int i;
00103    int bytes;
00104    int result;
00105    char **ptr;
00106    char *buffer;
00107 
00108    struct ast_filestream *tmp;
00109 
00110    if((tmp = malloc(sizeof(struct ast_filestream)))) {
00111       memset(tmp, 0, sizeof(struct ast_filestream));
00112 
00113       tmp->writing = 0;
00114       tmp->f = f;
00115 
00116       ogg_sync_init(&tmp->oy);
00117 
00118       buffer = ogg_sync_buffer(&tmp->oy, BLOCK_SIZE);
00119       bytes = fread(buffer, 1, BLOCK_SIZE, f);
00120       ogg_sync_wrote(&tmp->oy, bytes);
00121 
00122       result = ogg_sync_pageout(&tmp->oy, &tmp->og);
00123       if(result != 1) {
00124          if(bytes < BLOCK_SIZE) {
00125             ast_log(LOG_ERROR, "Run out of data...\n");
00126          } else {
00127             ast_log(LOG_ERROR, "Input does not appear to be an Ogg bitstream.\n");
00128          }
00129          fclose(f);
00130          ogg_sync_clear(&tmp->oy);
00131          free(tmp);
00132          return NULL;
00133       }
00134       
00135       ogg_stream_init(&tmp->os, ogg_page_serialno(&tmp->og));
00136       vorbis_info_init(&tmp->vi);
00137       vorbis_comment_init(&tmp->vc);
00138 
00139       if(ogg_stream_pagein(&tmp->os, &tmp->og) < 0) { 
00140          ast_log(LOG_ERROR, "Error reading first page of Ogg bitstream data.\n");
00141          fclose(f);
00142          ogg_stream_clear(&tmp->os);
00143          vorbis_comment_clear(&tmp->vc);
00144          vorbis_info_clear(&tmp->vi);
00145          ogg_sync_clear(&tmp->oy);
00146          free(tmp);
00147          return NULL;
00148       }
00149       
00150       if(ogg_stream_packetout(&tmp->os, &tmp->op) != 1) { 
00151          ast_log(LOG_ERROR, "Error reading initial header packet.\n");
00152          fclose(f);
00153          ogg_stream_clear(&tmp->os);
00154          vorbis_comment_clear(&tmp->vc);
00155          vorbis_info_clear(&tmp->vi);
00156          ogg_sync_clear(&tmp->oy);
00157          free(tmp);
00158          return NULL;
00159       }
00160       
00161       if(vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op) < 0) { 
00162          ast_log(LOG_ERROR, "This Ogg bitstream does not contain Vorbis audio data.\n");
00163          fclose(f);
00164          ogg_stream_clear(&tmp->os);
00165          vorbis_comment_clear(&tmp->vc);
00166          vorbis_info_clear(&tmp->vi);
00167          ogg_sync_clear(&tmp->oy);
00168          free(tmp);
00169          return NULL;
00170       }
00171       
00172       i = 0;
00173       while(i < 2) {
00174          while(i < 2){
00175             result = ogg_sync_pageout(&tmp->oy, &tmp->og);
00176             if(result == 0)
00177                break;
00178             if(result == 1) {
00179                ogg_stream_pagein(&tmp->os, &tmp->og);
00180                while(i < 2) {
00181                   result = ogg_stream_packetout(&tmp->os,&tmp->op);
00182                   if(result == 0)
00183                      break;
00184                   if(result < 0) {
00185                      ast_log(LOG_ERROR, "Corrupt secondary header.  Exiting.\n");
00186                      fclose(f);
00187                      ogg_stream_clear(&tmp->os);
00188                      vorbis_comment_clear(&tmp->vc);
00189                      vorbis_info_clear(&tmp->vi);
00190                      ogg_sync_clear(&tmp->oy);
00191                      free(tmp);
00192                      return NULL;
00193                   }
00194                   vorbis_synthesis_headerin(&tmp->vi, &tmp->vc, &tmp->op);
00195                   i++;
00196                }
00197             }
00198          }
00199 
00200          buffer = ogg_sync_buffer(&tmp->oy, BLOCK_SIZE);
00201          bytes = fread(buffer, 1, BLOCK_SIZE, f);
00202          if(bytes == 0 && i < 2) {
00203             ast_log(LOG_ERROR, "End of file before finding all Vorbis headers!\n");
00204             fclose(f);
00205             ogg_stream_clear(&tmp->os);
00206             vorbis_comment_clear(&tmp->vc);
00207             vorbis_info_clear(&tmp->vi);
00208             ogg_sync_clear(&tmp->oy);
00209             free(tmp);
00210             return NULL;
00211          }
00212          ogg_sync_wrote(&tmp->oy, bytes);
00213       }
00214       
00215       ptr = tmp->vc.user_comments;
00216       while(*ptr){
00217          ast_log(LOG_DEBUG, "OGG/Vorbis comment: %s\n", *ptr);
00218          ++ptr;
00219       }
00220       ast_log(LOG_DEBUG, "OGG/Vorbis bitstream is %d channel, %ldHz\n", tmp->vi.channels, tmp->vi.rate);
00221       ast_log(LOG_DEBUG, "OGG/Vorbis file encoded by: %s\n", tmp->vc.vendor);
00222 
00223       if(tmp->vi.channels != 1) {
00224          ast_log(LOG_ERROR, "Only monophonic OGG/Vorbis files are currently supported!\n");
00225          ogg_stream_clear(&tmp->os);
00226          vorbis_comment_clear(&tmp->vc);
00227          vorbis_info_clear(&tmp->vi);
00228          ogg_sync_clear(&tmp->oy);
00229          free(tmp);
00230          return NULL;
00231       }
00232       
00233 
00234       if(tmp->vi.rate != 8000) {
00235          ast_log(LOG_ERROR, "Only 8000Hz OGG/Vorbis files are currently supported!\n");
00236          fclose(f);
00237          ogg_stream_clear(&tmp->os);
00238          vorbis_block_clear(&tmp->vb);
00239          vorbis_dsp_clear(&tmp->vd);
00240          vorbis_comment_clear(&tmp->vc);
00241          vorbis_info_clear(&tmp->vi);
00242          ogg_sync_clear(&tmp->oy);
00243          free(tmp);
00244          return NULL;
00245       }
00246       
00247       vorbis_synthesis_init(&tmp->vd, &tmp->vi);
00248       vorbis_block_init(&tmp->vd, &tmp->vb);
00249 
00250       if(ast_mutex_lock(&ogg_vorbis_lock)) {
00251          ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
00252          fclose(f);
00253          ogg_stream_clear(&tmp->os);
00254          vorbis_block_clear(&tmp->vb);
00255          vorbis_dsp_clear(&tmp->vd);
00256          vorbis_comment_clear(&tmp->vc);
00257          vorbis_info_clear(&tmp->vi);
00258          ogg_sync_clear(&tmp->oy);
00259          free(tmp);
00260          return NULL;
00261       }
00262       glistcnt++;
00263       ast_mutex_unlock(&ogg_vorbis_lock);
00264       ast_update_use_count();
00265    }
00266    return tmp;
00267 }

static struct ast_frame* ogg_vorbis_read struct ast_filestream s,
int *  whennext
[static]
 

Read a frame full of audio data from the filestream.

Parameters:
s The filestream.
whennext Number of sample times to schedule the next call.
Returns:
A pointer to a frame containing audio data or NULL ifthere is no more audio data.

Definition at line 524 of file format_ogg_vorbis.c.

References read_samples(), s, and SAMPLES_MAX.

Referenced by load_module().

00525 {
00526    int clipflag = 0;
00527    int i;
00528    int j;
00529    float **pcm;
00530    float *mono;
00531    double accumulator[SAMPLES_MAX];
00532    int val;
00533    int samples_in;
00534    int samples_out = 0;
00535 
00536    while (1) {
00537       /* See ifwe have filled up an audio frame yet */
00538       if(samples_out == SAMPLES_MAX)
00539          break;
00540 
00541       /* See ifVorbis decoder has some audio data for us ... */
00542       samples_in = read_samples(s, &pcm);
00543       if(samples_in <= 0)
00544          break;
00545 
00546       /* Got some audio data from Vorbis... */
00547       /* Convert the float audio data to 16-bit signed linear */
00548       
00549       clipflag = 0;
00550 
00551       samples_in = samples_in < (SAMPLES_MAX - samples_out) ? samples_in : (SAMPLES_MAX - samples_out);
00552   
00553       for(j = 0; j < samples_in; j++)
00554          accumulator[j] = 0.0;
00555 
00556       for(i = 0; i < s->vi.channels; i++) {
00557          mono = pcm[i];
00558          for (j = 0; j < samples_in; j++) {
00559             accumulator[j] += mono[j];
00560          }
00561       }
00562 
00563       for (j = 0; j < samples_in; j++) {
00564          val =  accumulator[j] * 32767.0 / s->vi.channels;
00565          if(val > 32767) {
00566             val = 32767;
00567             clipflag = 1;
00568          }
00569          if(val < -32768) {
00570             val = -32768;
00571             clipflag = 1;
00572          }
00573          s->buffer[samples_out + j] = val;
00574       }
00575          
00576       if(clipflag)
00577          ast_log(LOG_WARNING, "Clipping in frame %ld\n", (long)(s->vd.sequence));
00578       
00579       /* Tell the Vorbis decoder how many samples we actually used. */
00580       vorbis_synthesis_read(&s->vd, samples_in);
00581       samples_out += samples_in;
00582    }
00583 
00584    if(samples_out > 0) {
00585       s->fr.frametype = AST_FRAME_VOICE;
00586       s->fr.subclass = AST_FORMAT_SLINEAR;
00587       s->fr.offset = AST_FRIENDLY_OFFSET;
00588       s->fr.datalen = samples_out * 2;
00589       s->fr.data = s->buffer;
00590       s->fr.src = name;
00591       s->fr.mallocd = 0;
00592       s->fr.samples = samples_out;
00593       *whennext = samples_out;
00594       
00595       return &s->fr;
00596    } else {
00597       return NULL;
00598    }
00599 }

static struct ast_filestream* ogg_vorbis_rewrite FILE *  f,
const char *  comment
[static]
 

Create a new OGG/Vorbis filestream and set it up for writing.

Parameters:
f File pointer that points to on-disk storage.
comment Comment that should be embedded in the OGG/Vorbis file.
Returns:
A new filestream.

Definition at line 275 of file format_ogg_vorbis.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), free, LOG_ERROR, LOG_WARNING, and malloc.

Referenced by load_module().

00276 {
00277    ogg_packet header;
00278    ogg_packet header_comm;
00279    ogg_packet header_code;
00280 
00281    struct ast_filestream *tmp;
00282 
00283    if((tmp = malloc(sizeof(struct ast_filestream)))) {
00284       memset(tmp, 0, sizeof(struct ast_filestream));
00285 
00286       tmp->writing = 1;
00287       tmp->f = f;
00288 
00289       vorbis_info_init(&tmp->vi);
00290 
00291       if(vorbis_encode_init_vbr(&tmp->vi, 1, 8000, 0.4)) {
00292          ast_log(LOG_ERROR, "Unable to initialize Vorbis encoder!\n");
00293          free(tmp);
00294          return NULL;
00295       }
00296 
00297       vorbis_comment_init(&tmp->vc);
00298       vorbis_comment_add_tag(&tmp->vc, "ENCODER", "Asterisk PBX");
00299       if(comment)
00300          vorbis_comment_add_tag(&tmp->vc, "COMMENT", (char *) comment);
00301 
00302       vorbis_analysis_init(&tmp->vd, &tmp->vi);
00303       vorbis_block_init(&tmp->vd, &tmp->vb);
00304 
00305       ogg_stream_init(&tmp->os, rand());
00306 
00307       vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm, &header_code);
00308       ogg_stream_packetin(&tmp->os, &header);                     
00309       ogg_stream_packetin(&tmp->os, &header_comm);
00310       ogg_stream_packetin(&tmp->os, &header_code);
00311 
00312       while(!tmp->eos) {
00313          if(ogg_stream_flush(&tmp->os, &tmp->og) == 0)
00314             break;
00315          fwrite(tmp->og.header, 1, tmp->og.header_len, tmp->f);
00316          fwrite(tmp->og.body, 1, tmp->og.body_len, tmp->f);
00317          if(ogg_page_eos(&tmp->og))
00318             tmp->eos = 1;
00319       }
00320 
00321       if(ast_mutex_lock(&ogg_vorbis_lock)) {
00322          ast_log(LOG_WARNING, "Unable to lock ogg_vorbis list\n");
00323          fclose(f);
00324          ogg_stream_clear(&tmp->os);
00325          vorbis_block_clear(&tmp->vb);
00326          vorbis_dsp_clear(&tmp->vd);
00327          vorbis_comment_clear(&tmp->vc);
00328          vorbis_info_clear(&tmp->vi);
00329          free(tmp);
00330          return NULL;
00331       }
00332       glistcnt++;
00333       ast_mutex_unlock(&ogg_vorbis_lock);
00334       ast_update_use_count();
00335    }
00336    return tmp;
00337 }

static int ogg_vorbis_seek struct ast_filestream s,
long  sample_offset,
int  whence
[static]
 

Seek to a specific position in an OGG/Vorbis filestream.

Parameters:
s The filestream to truncate.
sample_offset New position for the filestream, measured in 8KHz samples.
whence Location to measure
Returns:
0 on success, -1 on failure.

Definition at line 621 of file format_ogg_vorbis.c.

References ast_log().

Referenced by load_module().

00621                                                                                      {
00622    ast_log(LOG_WARNING, "Seeking is not supported on OGG/Vorbis streams!\n");
00623    return -1;
00624 }

static long ogg_vorbis_tell struct ast_filestream s  )  [static]
 

Definition at line 626 of file format_ogg_vorbis.c.

References ast_log().

Referenced by load_module().

00626                                                       {
00627    ast_log(LOG_WARNING, "Telling is not supported on OGG/Vorbis streams!\n");
00628    return -1;
00629 }

static int ogg_vorbis_trunc struct ast_filestream s  )  [static]
 

Trucate an OGG/Vorbis filestream.

Parameters:
s The filestream to truncate.
Returns:
0 on success, -1 on failure.

Definition at line 607 of file format_ogg_vorbis.c.

References ast_log().

Referenced by load_module().

00608 {
00609    ast_log(LOG_WARNING, "Truncation is not supported on OGG/Vorbis streams!\n");
00610    return -1;
00611 }

static int ogg_vorbis_write struct ast_filestream s,
struct ast_frame f
[static]
 

Write audio data from a frame to an OGG/Vorbis filestream.

Parameters:
s A OGG/Vorbis filestream.
f An frame containing audio to be written to the filestream.
Returns:
-1 ifthere was an error, 0 on success.

Definition at line 371 of file format_ogg_vorbis.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_filestream::buffer, ast_filestream::f, LOG_ERROR, LOG_WARNING, and s.

Referenced by load_module().

00372 {
00373    int i;
00374    float **buffer;
00375    short *data;
00376 
00377    if(!s->writing) {
00378       ast_log(LOG_ERROR, "This stream is not set up for writing!\n");
00379       return -1;
00380    }
00381 
00382    if(f->frametype != AST_FRAME_VOICE) {
00383       ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
00384       return -1;
00385    }
00386    if(f->subclass != AST_FORMAT_SLINEAR) {
00387       ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%d)!\n", f->subclass);
00388       return -1;
00389    }
00390    if(!f->datalen)
00391       return -1;
00392 
00393    data = (short *) f->data;
00394 
00395    buffer = vorbis_analysis_buffer(&s->vd, f->samples);
00396 
00397    for (i = 0; i < f->samples; i++) {
00398       buffer[0][i] = data[i]/32768.f;
00399    }
00400 
00401    vorbis_analysis_wrote(&s->vd, f->samples);
00402 
00403    write_stream(s);
00404 
00405    return 0;
00406 }

static int read_samples struct ast_filestream s,
float ***  pcm
[static]
 

Get audio data.

Parameters:
s An OGG/Vorbis filestream.
pcm Pointer to a buffere to store audio data in.

Definition at line 449 of file format_ogg_vorbis.c.

References ast_log(), BLOCK_SIZE, ast_filestream::buffer, ast_filestream::bytes, LOG_WARNING, result, and s.

Referenced by ogg_vorbis_read().

00450 {
00451    int samples_in;
00452    int result;
00453    char *buffer;
00454    int bytes;
00455 
00456    while (1) {
00457       samples_in = vorbis_synthesis_pcmout(&s->vd, pcm);
00458       if(samples_in > 0) {
00459          return samples_in;
00460       }
00461       
00462       /* The Vorbis decoder needs more data... */
00463       /* See ifOGG has any packets in the current page for the Vorbis decoder. */
00464       result = ogg_stream_packetout(&s->os, &s->op);
00465       if(result > 0) {
00466          /* Yes OGG had some more packets for the Vorbis decoder. */
00467          if(vorbis_synthesis(&s->vb, &s->op) == 0) {
00468             vorbis_synthesis_blockin(&s->vd, &s->vb);
00469          }
00470          
00471          continue;
00472       }
00473 
00474       if(result < 0)
00475          ast_log(LOG_WARNING, "Corrupt or missing data at this page position; continuing...\n");
00476       
00477       /* No more packets left in the current page... */
00478 
00479       if(s->eos) {
00480          /* No more pages left in the stream */
00481          return -1;
00482       }
00483 
00484       while (!s->eos) {
00485          /* See ifOGG has any pages in it's internal buffers */
00486          result = ogg_sync_pageout(&s->oy, &s->og);
00487          if(result > 0) {
00488             /* Yes, OGG has more pages in it's internal buffers,
00489                add the page to the stream state */
00490             result = ogg_stream_pagein(&s->os, &s->og);
00491             if(result == 0) {
00492                /* Yes, got a new,valid page */
00493                if(ogg_page_eos(&s->og)) {
00494                   s->eos = 1;
00495                }
00496                break;
00497             }
00498             ast_log(LOG_WARNING, "Invalid page in the bitstream; continuing...\n");
00499          }
00500          
00501          if(result < 0)
00502             ast_log(LOG_WARNING, "Corrupt or missing data in bitstream; continuing...\n");
00503 
00504          /* No, we need to read more data from the file descrptor */
00505          /* get a buffer from OGG to read the data into */
00506          buffer = ogg_sync_buffer(&s->oy, BLOCK_SIZE);
00507          /* read more data from the file descriptor */
00508          bytes = fread(buffer, 1, BLOCK_SIZE, s->f);
00509          /* Tell OGG how many bytes we actually read into the buffer */
00510          ogg_sync_wrote(&s->oy, bytes);
00511          if(bytes == 0) {
00512             s->eos = 1;
00513          }
00514       }
00515    }
00516 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 650 of file format_ogg_vorbis.c.

References ast_format_unregister(), and name.

00651 {
00652    return ast_format_unregister(name);
00653 }  

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 655 of file format_ogg_vorbis.c.

References glistcnt.

00656 {
00657    return glistcnt;
00658 }

static void write_stream struct ast_filestream s  )  [static]
 

Write out any pending encoded data.

Parameters:
s A OGG/Vorbis filestream.

Definition at line 343 of file format_ogg_vorbis.c.

References s.

Referenced by ogg_vorbis_close().

00344 {
00345    while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
00346       vorbis_analysis(&s->vb, NULL);
00347       vorbis_bitrate_addblock(&s->vb);
00348       
00349       while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
00350          ogg_stream_packetin(&s->os, &s->op);
00351          while (!s->eos) {
00352             if(ogg_stream_pageout(&s->os, &s->og) == 0) {
00353                break;
00354             }
00355             fwrite(s->og.header, 1, s->og.header_len, s->f);
00356             fwrite(s->og.body, 1, s->og.body_len, s->f);
00357             if(ogg_page_eos(&s->og)) {
00358                s->eos = 1;
00359             }
00360          }
00361       }
00362    }
00363 }


Variable Documentation

char* desc = "OGG/Vorbis audio" [static]
 

Definition at line 92 of file format_ogg_vorbis.c.

char* exts = "ogg" [static]
 

Definition at line 93 of file format_ogg_vorbis.c.

int glistcnt = 0 [static]
 

Definition at line 89 of file format_ogg_vorbis.c.

char* name = "ogg_vorbis" [static]
 

Definition at line 91 of file format_ogg_vorbis.c.


Generated on Sat Mar 24 23:28:46 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6