decoder-ogg-stream.c
author nathan
Sun, 12 Dec 2010 11:31:54 +0100
branchtrunk
changeset 38 79b272a68eb4
parent 33 65ed49cbc08b
permissions -rw-r--r--
fix compile without OGG library
     1 /*
     2  * MP3/MPlayer plugin to VDR (C++)
     3  *
     4  * (C) 2001-2010 Stefan Huelswitt <s.huelswitt@gmx.de>
     5  *
     6  * OGG stream support initialy developed by Manuel Reimer <manuel.reimer@gmx.de>
     7  *
     8  * This code is free software; you can redistribute it and/or
     9  * modify it under the terms of the GNU General Public License
    10  * as published by the Free Software Foundation; either version 2
    11  * of the License, or (at your option) any later version.
    12  *
    13  * This code is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    21  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
    22  */
    23 
    24 #ifdef HAVE_VORBISFILE
    25 
    26 #include <stdlib.h>
    27 #include <stdio.h>
    28 
    29 #include "common.h"
    30 #include "decoder-ogg-stream.h"
    31 #include "stream.h"
    32 
    33 // --- Ogg callbacks -----------------------------------------------------------
    34 
    35 static size_t callback_read(void *ptr, size_t size, size_t nmemb, void *datasource)
    36 {
    37   cNetStream *nstr=(cNetStream*)datasource;
    38   unsigned char *sdata;
    39   unsigned long slen=0;
    40   // Read in loop until we either get data or function "Stream" fails
    41   do {
    42     if(!nstr->Stream(sdata,slen)) {
    43       d(printf("oggstream-callback-read: EOF?\n"))
    44       return 0;
    45       }
    46     } while(slen==0);
    47 
    48   size_t read_size=size*nmemb;
    49   if(slen>read_size) {
    50     // If someone ever gets this message, buffer handling has to be improved...
    51     d(printf("oggstream-callback-read: buffer size too small...\n"))
    52     slen=read_size;
    53     }
    54   memcpy(ptr,sdata,slen);
    55   return slen/size;
    56 }
    57 
    58 static int callback_close(void *datasource)
    59 {
    60   cNetStream *nstr=(cNetStream*)datasource;
    61   nstr->Close();
    62   return 0;
    63 }
    64 
    65 static const ov_callbacks callbacks = {
    66   callback_read,
    67   NULL,
    68   callback_close,
    69   NULL
    70   };
    71 
    72 // --- cNetOggFile -------------------------------------------------------------
    73 
    74 cNetOggFile::cNetOggFile(const char *Filename)
    75 :cOggFile(Filename)
    76 {
    77   nstr=new cNetStream(Filename);
    78 }
    79 
    80 bool cNetOggFile::Open(bool log)
    81 {
    82   if(opened) return true;
    83   if(!nstr->Open(log)) return false;
    84   int r=ov_open_callbacks(nstr,&vf,NULL,0,callbacks);
    85   if(!r) opened=true;
    86   else {
    87     nstr->Close();
    88     if(log) Error("open",r);
    89     }
    90   return opened;
    91 }
    92 
    93 // --- cNetOggInfo -------------------------------------------------------------
    94 
    95 cNetOggInfo::cNetOggInfo(cNetOggFile *File)
    96 :cOggInfo(File)
    97 {
    98   nfile=File;
    99   nstr=nfile->nstr;
   100 }
   101 
   102 bool cNetOggInfo::DoScan(bool KeepOpen)
   103 {
   104   Clear();
   105   IcyInfo();
   106   if(!Title) FakeTitle(nstr->Filename);
   107   Total=0;
   108   ChMode=3;
   109   DecoderID=DEC_OGGS;
   110   InfoDone();
   111   return true;
   112 }
   113 
   114 void cNetOggInfo::InfoHook()
   115 {
   116   if(nstr->IcyChanged()) IcyInfo();
   117   vorbis_info *vi=ov_info(&nfile->vf,-1);
   118   if(!vi) return;
   119   Channels=vi->channels;
   120   ChMode=Channels>1 ? 3:0;
   121   SampleFreq=vi->rate;
   122   if(vi->bitrate_upper>0 && vi->bitrate_lower>0) {
   123     Bitrate=vi->bitrate_lower;
   124     MaxBitrate=vi->bitrate_upper;
   125     }
   126   else
   127     Bitrate=vi->bitrate_nominal;
   128 
   129   Total=(int)ov_time_total(&nfile->vf,-1);
   130   Frames=-1;
   131 }
   132 
   133 void cNetOggInfo::IcyInfo(void)
   134 {
   135   const char *t=nstr->IcyTitle();
   136   const char *a;
   137   if(t) {
   138     a=nstr->IcyName();
   139     if(!a) a=nstr->IcyUrl();
   140     }
   141   else {
   142     t=nstr->IcyName();
   143     a=nstr->IcyUrl();
   144     }
   145   if(t && (!Title || strcmp(t,Title))) {
   146     free(Title);
   147     Title=strdup(t);
   148     }
   149   if(a && (!Album || strcmp(a,Album))) {
   150     free(Album);
   151     Album=strdup(a);
   152     }
   153 }
   154 
   155 // --- cOggStreamDecoder -------------------------------------------------------
   156 
   157 cOggStreamDecoder::cOggStreamDecoder(const char *Filename)
   158 :cOggDecoder(Filename,false)
   159 {
   160   nfile=new cNetOggFile(Filename);
   161   file=nfile;
   162   info=new cNetOggInfo(nfile);
   163 }
   164 
   165 #endif //HAVE_VORBISFILE