/project/jni/sndfile/src/ogg.c

https://github.com/aichunyu/FFPlayer · C · 250 lines · 157 code · 54 blank · 39 comment · 20 complexity · 91853f4bdf066f4cc34c4f23b8bc1e00 MD5 · raw file

  1. /*
  2. ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. ** Copyright (C) 2007 John ffitch
  4. **
  5. ** This program is free software ; you can redistribute it and/or modify
  6. ** it under the terms of the GNU Lesser General Public License as published by
  7. ** the Free Software Foundation ; either version 2.1 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU Lesser General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU Lesser General Public License
  16. ** along with this program ; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. #include "sfconfig.h"
  20. #include <stdio.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <time.h>
  25. #include <math.h>
  26. #if HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #include "sndfile.h"
  30. #include "sfendian.h"
  31. #include "common.h"
  32. #if HAVE_EXTERNAL_LIBS
  33. #include <ogg/ogg.h>
  34. #include "ogg.h"
  35. static int ogg_close (SF_PRIVATE *psf) ;
  36. static int ogg_stream_classify (SF_PRIVATE *psf, OGG_PRIVATE * odata) ;
  37. static int ogg_page_classify (SF_PRIVATE * psf, const ogg_page * og) ;
  38. int
  39. ogg_open (SF_PRIVATE *psf)
  40. { OGG_PRIVATE* odata = calloc (1, sizeof (OGG_PRIVATE)) ;
  41. sf_count_t pos = psf_ftell (psf) ;
  42. int error = 0 ;
  43. psf->container_data = odata ;
  44. psf->container_close = ogg_close ;
  45. if (psf->file.mode == SFM_RDWR)
  46. return SFE_BAD_MODE_RW ;
  47. if (psf->file.mode == SFM_READ)
  48. if ((error = ogg_stream_classify (psf, odata)) != 0)
  49. return error ;
  50. /* Reset everything to an initial state. */
  51. ogg_sync_clear (&odata->osync) ;
  52. ogg_stream_clear (&odata->ostream) ;
  53. psf_fseek (psf, pos, SEEK_SET) ;
  54. switch (psf->sf.format)
  55. { case SF_FORMAT_OGG | SF_FORMAT_VORBIS :
  56. return ogg_vorbis_open (psf) ;
  57. case SF_FORMAT_OGGFLAC :
  58. free (psf->container_data) ;
  59. psf->container_data = NULL ;
  60. psf->container_close = NULL ;
  61. return flac_open (psf) ;
  62. #if ENABLE_EXPERIMENTAL_CODE
  63. case SF_FORMAT_OGG | SF_FORMAT_SPEEX :
  64. return ogg_speex_open (psf) ;
  65. case SF_FORMAT_OGG | SF_FORMAT_PCM_16 :
  66. case SF_FORMAT_OGG | SF_FORMAT_PCM_24 :
  67. return ogg_pcm_open (psf) ;
  68. #endif
  69. default :
  70. break ;
  71. } ;
  72. psf_log_printf (psf, "%s : mode should be SFM_READ or SFM_WRITE.\n", __func__) ;
  73. return SFE_INTERNAL ;
  74. } /* ogg_open */
  75. static int
  76. ogg_close (SF_PRIVATE *psf)
  77. { OGG_PRIVATE* odata = psf->container_data ;
  78. ogg_sync_clear (&odata->osync) ;
  79. ogg_stream_clear (&odata->ostream) ;
  80. return 0 ;
  81. } /* ogg_close */
  82. static int
  83. ogg_stream_classify (SF_PRIVATE *psf, OGG_PRIVATE* odata)
  84. { char *buffer ;
  85. int bytes, nn ;
  86. /* Call this here so it only gets called once, so no memory is leaked. */
  87. ogg_sync_init (&odata->osync) ;
  88. odata->eos = 0 ;
  89. /* Weird stuff happens if these aren't called. */
  90. ogg_stream_reset (&odata->ostream) ;
  91. ogg_sync_reset (&odata->osync) ;
  92. /*
  93. ** Grab some data at the head of the stream. We want the first page
  94. ** (which is guaranteed to be small and only contain the Vorbis
  95. ** stream initial header) We need the first page to get the stream
  96. ** serialno.
  97. */
  98. /* Expose the buffer */
  99. buffer = ogg_sync_buffer (&odata->osync, 4096L) ;
  100. /* Grab the part of the header that has already been read. */
  101. memcpy (buffer, psf->header, psf->headindex) ;
  102. bytes = psf->headindex ;
  103. /* Submit a 4k block to libvorbis' Ogg layer */
  104. bytes += psf_fread (buffer + psf->headindex, 1, 4096 - psf->headindex, psf) ;
  105. ogg_sync_wrote (&odata->osync, bytes) ;
  106. /* Get the first page. */
  107. if ((nn = ogg_sync_pageout (&odata->osync, &odata->opage)) != 1)
  108. {
  109. /* Have we simply run out of data? If so, we're done. */
  110. if (bytes < 4096)
  111. return 0 ;
  112. /* Error case. Must not be Vorbis data */
  113. psf_log_printf (psf, "Input does not appear to be an Ogg bitstream.\n") ;
  114. return SFE_MALFORMED_FILE ;
  115. } ;
  116. /*
  117. ** Get the serial number and set up the rest of decode.
  118. ** Serialno first ; use it to set up a logical stream.
  119. */
  120. ogg_stream_clear (&odata->ostream) ;
  121. ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
  122. if (ogg_stream_pagein (&odata->ostream, &odata->opage) < 0)
  123. { /* Error ; stream version mismatch perhaps. */
  124. psf_log_printf (psf, "Error reading first page of Ogg bitstream data\n") ;
  125. return SFE_MALFORMED_FILE ;
  126. } ;
  127. if (ogg_stream_packetout (&odata->ostream, &odata->opacket) != 1)
  128. { /* No page? must not be vorbis. */
  129. psf_log_printf (psf, "Error reading initial header packet.\n") ;
  130. return SFE_MALFORMED_FILE ;
  131. } ;
  132. odata->codec = ogg_page_classify (psf, &odata->opage) ;
  133. switch (odata->codec)
  134. { case OGG_VORBIS :
  135. psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  136. return 0 ;
  137. case OGG_FLAC :
  138. case OGG_FLAC0 :
  139. psf->sf.format = SF_FORMAT_OGGFLAC ;
  140. return 0 ;
  141. case OGG_SPEEX :
  142. psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_SPEEX ;
  143. return 0 ;
  144. case OGG_PCM :
  145. psf_log_printf (psf, "Detected Ogg/PCM data. This is not supported yet.\n") ;
  146. return SFE_UNIMPLEMENTED ;
  147. default :
  148. break ;
  149. } ;
  150. psf_log_printf (psf, "This Ogg bitstream contains some uknown data type.\n") ;
  151. return SFE_UNIMPLEMENTED ;
  152. } /* ogg_stream_classify */
  153. /*==============================================================================
  154. */
  155. static struct
  156. { const char *str, *name ;
  157. int len, codec ;
  158. } codec_lookup [] =
  159. { { "Annodex", "Annodex", 8, OGG_ANNODEX },
  160. { "AnxData", "AnxData", 7, OGG_ANXDATA },
  161. { "\177FLAC", "Flac1", 5, OGG_FLAC },
  162. { "fLaC", "Flac0", 4, OGG_FLAC0 },
  163. { "PCM ", "PCM", 8, OGG_PCM },
  164. { "Speex", "Speex", 5, OGG_SPEEX },
  165. { "\001vorbis", "Vorbis", 7, OGG_VORBIS },
  166. } ;
  167. static int
  168. ogg_page_classify (SF_PRIVATE * psf, const ogg_page * og)
  169. { int k, len ;
  170. for (k = 0 ; k < ARRAY_LEN (codec_lookup) ; k++)
  171. { if (codec_lookup [k].len > og->body_len)
  172. continue ;
  173. if (memcmp (og->body, codec_lookup [k].str, codec_lookup [k].len) == 0)
  174. { psf_log_printf (psf, "Ogg stream data : %s\n", codec_lookup [k].name) ;
  175. psf_log_printf (psf, "Stream serialno : %010D\n", (int64_t) ogg_page_serialno (og)) ;
  176. return codec_lookup [k].codec ;
  177. } ;
  178. } ;
  179. len = og->body_len < 8 ? og->body_len : 8 ;
  180. psf_log_printf (psf, "Ogg_stream data : '") ;
  181. for (k = 0 ; k < len ; k++)
  182. psf_log_printf (psf, "%c", isprint (og->body [k]) ? og->body [k] : '.') ;
  183. psf_log_printf (psf, "' ") ;
  184. for (k = 0 ; k < len ; k++)
  185. psf_log_printf (psf, " %02x", og->body [k] & 0xff) ;
  186. psf_log_printf (psf, "\n") ;
  187. return 0 ;
  188. } /* ogg_page_classify */
  189. #else /* HAVE_EXTERNAL_LIBS */
  190. int
  191. ogg_open (SF_PRIVATE *psf)
  192. {
  193. psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Vorbis support.\n") ;
  194. return SFE_UNIMPLEMENTED ;
  195. } /* ogg_open */
  196. #endif