You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
5.9KB

  1. /*
  2. * WAV encoder and decoder
  3. * Copyright (c) 2001, 2002 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library 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 GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "avformat.h"
  20. #include "allformats.h"
  21. #include "riff.h"
  22. typedef struct {
  23. offset_t data;
  24. offset_t data_end;
  25. } WAVContext;
  26. #ifdef CONFIG_MUXERS
  27. static int wav_write_header(AVFormatContext *s)
  28. {
  29. WAVContext *wav = s->priv_data;
  30. ByteIOContext *pb = &s->pb;
  31. offset_t fmt;
  32. put_tag(pb, "RIFF");
  33. put_le32(pb, 0); /* file length */
  34. put_tag(pb, "WAVE");
  35. /* format header */
  36. fmt = start_tag(pb, "fmt ");
  37. if (put_wav_header(pb, s->streams[0]->codec) < 0) {
  38. av_free(wav);
  39. return -1;
  40. }
  41. end_tag(pb, fmt);
  42. av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
  43. /* data header */
  44. wav->data = start_tag(pb, "data");
  45. put_flush_packet(pb);
  46. return 0;
  47. }
  48. static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
  49. {
  50. ByteIOContext *pb = &s->pb;
  51. put_buffer(pb, pkt->data, pkt->size);
  52. return 0;
  53. }
  54. static int wav_write_trailer(AVFormatContext *s)
  55. {
  56. ByteIOContext *pb = &s->pb;
  57. WAVContext *wav = s->priv_data;
  58. offset_t file_size;
  59. if (!url_is_streamed(&s->pb)) {
  60. end_tag(pb, wav->data);
  61. /* update file size */
  62. file_size = url_ftell(pb);
  63. url_fseek(pb, 4, SEEK_SET);
  64. put_le32(pb, (uint32_t)(file_size - 8));
  65. url_fseek(pb, file_size, SEEK_SET);
  66. put_flush_packet(pb);
  67. }
  68. return 0;
  69. }
  70. #endif //CONFIG_MUXERS
  71. /* return the size of the found tag */
  72. /* XXX: > 2GB ? */
  73. static int find_tag(ByteIOContext *pb, uint32_t tag1)
  74. {
  75. unsigned int tag;
  76. int size;
  77. for(;;) {
  78. if (url_feof(pb))
  79. return -1;
  80. tag = get_le32(pb);
  81. size = get_le32(pb);
  82. if (tag == tag1)
  83. break;
  84. url_fseek(pb, size, SEEK_CUR);
  85. }
  86. if (size < 0)
  87. size = 0x7fffffff;
  88. return size;
  89. }
  90. static int wav_probe(AVProbeData *p)
  91. {
  92. /* check file header */
  93. if (p->buf_size <= 32)
  94. return 0;
  95. if (p->buf[0] == 'R' && p->buf[1] == 'I' &&
  96. p->buf[2] == 'F' && p->buf[3] == 'F' &&
  97. p->buf[8] == 'W' && p->buf[9] == 'A' &&
  98. p->buf[10] == 'V' && p->buf[11] == 'E')
  99. return AVPROBE_SCORE_MAX;
  100. else
  101. return 0;
  102. }
  103. /* wav input */
  104. static int wav_read_header(AVFormatContext *s,
  105. AVFormatParameters *ap)
  106. {
  107. int size;
  108. unsigned int tag;
  109. ByteIOContext *pb = &s->pb;
  110. AVStream *st;
  111. WAVContext *wav = s->priv_data;
  112. /* check RIFF header */
  113. tag = get_le32(pb);
  114. if (tag != MKTAG('R', 'I', 'F', 'F'))
  115. return -1;
  116. get_le32(pb); /* file size */
  117. tag = get_le32(pb);
  118. if (tag != MKTAG('W', 'A', 'V', 'E'))
  119. return -1;
  120. /* parse fmt header */
  121. size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
  122. if (size < 0)
  123. return -1;
  124. st = av_new_stream(s, 0);
  125. if (!st)
  126. return AVERROR_NOMEM;
  127. get_wav_header(pb, st->codec, size);
  128. st->need_parsing = 1;
  129. av_set_pts_info(st, 64, 1, st->codec->sample_rate);
  130. size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
  131. if (size < 0)
  132. return -1;
  133. wav->data_end= url_ftell(pb) + size;
  134. return 0;
  135. }
  136. #define MAX_SIZE 4096
  137. static int wav_read_packet(AVFormatContext *s,
  138. AVPacket *pkt)
  139. {
  140. int ret, size, left;
  141. AVStream *st;
  142. WAVContext *wav = s->priv_data;
  143. if (url_feof(&s->pb))
  144. return AVERROR_IO;
  145. st = s->streams[0];
  146. left= wav->data_end - url_ftell(&s->pb);
  147. if(left <= 0){
  148. left = find_tag(&(s->pb), MKTAG('d', 'a', 't', 'a'));
  149. if (left < 0) {
  150. return AVERROR_IO;
  151. }
  152. wav->data_end= url_ftell(&s->pb) + left;
  153. }
  154. size = MAX_SIZE;
  155. if (st->codec->block_align > 1) {
  156. if (size < st->codec->block_align)
  157. size = st->codec->block_align;
  158. size = (size / st->codec->block_align) * st->codec->block_align;
  159. }
  160. size= FFMIN(size, left);
  161. if (av_new_packet(pkt, size))
  162. return AVERROR_IO;
  163. pkt->stream_index = 0;
  164. ret = get_buffer(&s->pb, pkt->data, pkt->size);
  165. if (ret < 0)
  166. av_free_packet(pkt);
  167. /* note: we need to modify the packet size here to handle the last
  168. packet */
  169. pkt->size = ret;
  170. return ret;
  171. }
  172. static int wav_read_close(AVFormatContext *s)
  173. {
  174. return 0;
  175. }
  176. static int wav_read_seek(AVFormatContext *s,
  177. int stream_index, int64_t timestamp, int flags)
  178. {
  179. AVStream *st;
  180. st = s->streams[0];
  181. switch(st->codec->codec_id) {
  182. case CODEC_ID_MP2:
  183. case CODEC_ID_MP3:
  184. case CODEC_ID_AC3:
  185. case CODEC_ID_DTS:
  186. /* use generic seeking with dynamically generated indexes */
  187. return -1;
  188. default:
  189. break;
  190. }
  191. return pcm_read_seek(s, stream_index, timestamp, flags);
  192. }
  193. #ifdef CONFIG_WAV_DEMUXER
  194. AVInputFormat wav_demuxer = {
  195. "wav",
  196. "wav format",
  197. sizeof(WAVContext),
  198. wav_probe,
  199. wav_read_header,
  200. wav_read_packet,
  201. wav_read_close,
  202. wav_read_seek,
  203. };
  204. #endif
  205. #ifdef CONFIG_WAV_MUXER
  206. AVOutputFormat wav_muxer = {
  207. "wav",
  208. "wav format",
  209. "audio/x-wav",
  210. "wav",
  211. sizeof(WAVContext),
  212. CODEC_ID_PCM_S16LE,
  213. CODEC_ID_NONE,
  214. wav_write_header,
  215. wav_write_packet,
  216. wav_write_trailer,
  217. };
  218. #endif