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.

427 lines
9.6KB

  1. /*
  2. * Buffered I/O for ffmpeg system
  3. * Copyright (c) 2000,2001 Gerard Lantau
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 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 General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <netinet/in.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24. #include <sys/ioctl.h>
  25. #include <errno.h>
  26. #include <sys/time.h>
  27. #include <getopt.h>
  28. #include <string.h>
  29. #include "avformat.h"
  30. #define IO_BUFFER_SIZE 32768
  31. int init_put_byte(ByteIOContext *s,
  32. unsigned char *buffer,
  33. int buffer_size,
  34. int write_flag,
  35. void *opaque,
  36. int (*read_packet)(void *opaque, UINT8 *buf, int buf_size),
  37. void (*write_packet)(void *opaque, UINT8 *buf, int buf_size),
  38. int (*seek)(void *opaque, offset_t offset, int whence))
  39. {
  40. s->buffer = buffer;
  41. s->buffer_size = buffer_size;
  42. s->buf_ptr = buffer;
  43. s->write_flag = write_flag;
  44. if (!s->write_flag)
  45. s->buf_end = buffer;
  46. else
  47. s->buf_end = buffer + buffer_size;
  48. s->opaque = opaque;
  49. s->write_packet = write_packet;
  50. s->read_packet = read_packet;
  51. s->seek = seek;
  52. s->pos = 0;
  53. s->must_flush = 0;
  54. s->eof_reached = 0;
  55. s->is_streamed = 0;
  56. s->packet_size = 1;
  57. return 0;
  58. }
  59. static void flush_buffer(ByteIOContext *s)
  60. {
  61. if (s->buf_ptr > s->buffer) {
  62. if (s->write_packet)
  63. s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
  64. s->pos += s->buf_ptr - s->buffer;
  65. }
  66. s->buf_ptr = s->buffer;
  67. }
  68. void put_byte(ByteIOContext *s, int b)
  69. {
  70. *(s->buf_ptr)++ = b;
  71. if (s->buf_ptr >= s->buf_end)
  72. flush_buffer(s);
  73. }
  74. void put_buffer(ByteIOContext *s, unsigned char *buf, int size)
  75. {
  76. int len;
  77. while (size > 0) {
  78. len = (s->buf_end - s->buf_ptr);
  79. if (len > size)
  80. len = size;
  81. memcpy(s->buf_ptr, buf, len);
  82. s->buf_ptr += len;
  83. if (s->buf_ptr >= s->buf_end)
  84. flush_buffer(s);
  85. buf += len;
  86. size -= len;
  87. }
  88. }
  89. void put_flush_packet(ByteIOContext *s)
  90. {
  91. flush_buffer(s);
  92. s->must_flush = 0;
  93. }
  94. offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)
  95. {
  96. offset_t offset1;
  97. if (whence != SEEK_CUR && whence != SEEK_SET)
  98. return -EINVAL;
  99. if (s->write_flag) {
  100. if (whence == SEEK_CUR) {
  101. offset1 = s->pos + s->buf_ptr - s->buffer;
  102. if (offset == 0)
  103. return offset1;
  104. offset += offset1;
  105. }
  106. offset1 = offset - s->pos;
  107. if (!s->must_flush &&
  108. offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
  109. /* can do the seek inside the buffer */
  110. s->buf_ptr = s->buffer + offset1;
  111. } else {
  112. if (!s->seek)
  113. return -EPIPE;
  114. flush_buffer(s);
  115. s->must_flush = 1;
  116. s->buf_ptr = s->buffer;
  117. s->seek(s->opaque, offset, SEEK_SET);
  118. s->pos = offset;
  119. }
  120. } else {
  121. if (whence == SEEK_CUR) {
  122. offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer);
  123. if (offset == 0)
  124. return offset1;
  125. offset += offset1;
  126. }
  127. offset1 = offset - (s->pos - (s->buf_end - s->buffer));
  128. if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
  129. /* can do the seek inside the buffer */
  130. s->buf_ptr = s->buffer + offset1;
  131. } else {
  132. if (!s->seek)
  133. return -EPIPE;
  134. s->buf_ptr = s->buffer;
  135. s->buf_end = s->buffer;
  136. s->eof_reached = 0;
  137. s->seek(s->opaque, offset, SEEK_SET);
  138. s->pos = offset;
  139. }
  140. }
  141. return offset;
  142. }
  143. void url_fskip(ByteIOContext *s, offset_t offset)
  144. {
  145. url_fseek(s, offset, SEEK_CUR);
  146. }
  147. offset_t url_ftell(ByteIOContext *s)
  148. {
  149. return url_fseek(s, 0, SEEK_CUR);
  150. }
  151. int url_feof(ByteIOContext *s)
  152. {
  153. return s->eof_reached;
  154. }
  155. void put_le32(ByteIOContext *s, unsigned int val)
  156. {
  157. put_byte(s, val);
  158. put_byte(s, val >> 8);
  159. put_byte(s, val >> 16);
  160. put_byte(s, val >> 24);
  161. }
  162. void put_be32(ByteIOContext *s, unsigned int val)
  163. {
  164. put_byte(s, val >> 24);
  165. put_byte(s, val >> 16);
  166. put_byte(s, val >> 8);
  167. put_byte(s, val);
  168. }
  169. void put_le64(ByteIOContext *s, unsigned long long val)
  170. {
  171. put_le32(s, val & 0xffffffff);
  172. put_le32(s, val >> 32);
  173. }
  174. void put_be64(ByteIOContext *s, unsigned long long val)
  175. {
  176. put_be32(s, val >> 32);
  177. put_be32(s, val & 0xffffffff);
  178. }
  179. void put_le16(ByteIOContext *s, unsigned int val)
  180. {
  181. put_byte(s, val);
  182. put_byte(s, val >> 8);
  183. }
  184. void put_be16(ByteIOContext *s, unsigned int val)
  185. {
  186. put_byte(s, val >> 8);
  187. put_byte(s, val);
  188. }
  189. void put_tag(ByteIOContext *s, char *tag)
  190. {
  191. while (*tag) {
  192. put_byte(s, *tag++);
  193. }
  194. }
  195. /* Input stream */
  196. static void fill_buffer(ByteIOContext *s)
  197. {
  198. int len;
  199. len = s->read_packet(s->opaque, s->buffer, s->buffer_size);
  200. s->pos += len;
  201. s->buf_ptr = s->buffer;
  202. s->buf_end = s->buffer + len;
  203. if (len == 0) {
  204. s->eof_reached = 1;
  205. }
  206. }
  207. int get_byte(ByteIOContext *s)
  208. {
  209. if (s->buf_ptr < s->buf_end) {
  210. return *s->buf_ptr++;
  211. } else {
  212. fill_buffer(s);
  213. if (s->buf_ptr < s->buf_end)
  214. return *s->buf_ptr++;
  215. else
  216. return 0;
  217. }
  218. }
  219. int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
  220. {
  221. int len, size1;
  222. size1 = size;
  223. while (size > 0) {
  224. len = s->buf_end - s->buf_ptr;
  225. if (len > size)
  226. len = size;
  227. if (len == 0) {
  228. fill_buffer(s);
  229. len = s->buf_end - s->buf_ptr;
  230. if (len == 0)
  231. break;
  232. } else {
  233. memcpy(buf, s->buf_ptr, len);
  234. buf += len;
  235. s->buf_ptr += len;
  236. size -= len;
  237. }
  238. }
  239. return size1 - size;
  240. }
  241. unsigned int get_le16(ByteIOContext *s)
  242. {
  243. unsigned int val;
  244. val = get_byte(s);
  245. val |= get_byte(s) << 8;
  246. return val;
  247. }
  248. unsigned int get_le32(ByteIOContext *s)
  249. {
  250. unsigned int val;
  251. val = get_byte(s);
  252. val |= get_byte(s) << 8;
  253. val |= get_byte(s) << 16;
  254. val |= get_byte(s) << 24;
  255. return val;
  256. }
  257. unsigned long long get_le64(ByteIOContext *s)
  258. {
  259. UINT64 val;
  260. val = (UINT64)get_le32(s);
  261. val |= (UINT64)get_le32(s) << 32;
  262. return val;
  263. }
  264. unsigned int get_be16(ByteIOContext *s)
  265. {
  266. unsigned int val;
  267. val = get_byte(s) << 8;
  268. val |= get_byte(s);
  269. return val;
  270. }
  271. unsigned int get_be32(ByteIOContext *s)
  272. {
  273. unsigned int val;
  274. val = get_byte(s) << 24;
  275. val |= get_byte(s) << 16;
  276. val |= get_byte(s) << 8;
  277. val |= get_byte(s);
  278. return val;
  279. }
  280. unsigned long long get_be64(ByteIOContext *s)
  281. {
  282. UINT64 val;
  283. val = (UINT64)get_be32(s) << 32;
  284. val |= (UINT64)get_be32(s);
  285. return val;
  286. }
  287. /* link with avio functions */
  288. void url_write_packet(void *opaque, UINT8 *buf, int buf_size)
  289. {
  290. URLContext *h = opaque;
  291. url_write(h, buf, buf_size);
  292. }
  293. int url_read_packet(void *opaque, UINT8 *buf, int buf_size)
  294. {
  295. URLContext *h = opaque;
  296. return url_read(h, buf, buf_size);
  297. }
  298. int url_seek_packet(void *opaque, long long offset, int whence)
  299. {
  300. URLContext *h = opaque;
  301. url_seek(h, offset, whence);
  302. return 0;
  303. }
  304. int url_fdopen(ByteIOContext *s, URLContext *h)
  305. {
  306. UINT8 *buffer;
  307. int buffer_size;
  308. buffer_size = (IO_BUFFER_SIZE / h->packet_size) * h->packet_size;
  309. buffer = malloc(buffer_size);
  310. if (!buffer)
  311. return -ENOMEM;
  312. if (init_put_byte(s, buffer, buffer_size,
  313. (h->flags & URL_WRONLY) != 0, h,
  314. url_read_packet, url_write_packet, url_seek_packet) < 0) {
  315. free(buffer);
  316. return -EIO;
  317. }
  318. s->is_streamed = h->is_streamed;
  319. s->packet_size = h->packet_size;
  320. return 0;
  321. }
  322. /* XXX: must be called before any I/O */
  323. int url_setbufsize(ByteIOContext *s, int buf_size)
  324. {
  325. UINT8 *buffer;
  326. buffer = malloc(buf_size);
  327. if (!buffer)
  328. return -ENOMEM;
  329. free(s->buffer);
  330. s->buffer = buffer;
  331. s->buffer_size = buf_size;
  332. s->buf_ptr = buffer;
  333. if (!s->write_flag)
  334. s->buf_end = buffer;
  335. else
  336. s->buf_end = buffer + buf_size;
  337. return 0;
  338. }
  339. int url_fopen(ByteIOContext *s, const char *filename, int flags)
  340. {
  341. URLContext *h;
  342. int err;
  343. err = url_open(&h, filename, flags);
  344. if (err < 0)
  345. return err;
  346. err = url_fdopen(s, h);
  347. if (err < 0) {
  348. url_close(h);
  349. return err;
  350. }
  351. return 0;
  352. }
  353. int url_fclose(ByteIOContext *s)
  354. {
  355. URLContext *h = s->opaque;
  356. free(s->buffer);
  357. memset(s, 0, sizeof(ByteIOContext));
  358. return url_close(h);
  359. }
  360. URLContext *url_fileno(ByteIOContext *s)
  361. {
  362. return s->opaque;
  363. }
  364. /* buffer handling */
  365. int url_open_buf(ByteIOContext *s, UINT8 *buf, int buf_size, int flags)
  366. {
  367. return init_put_byte(s, buf, buf_size,
  368. (flags & URL_WRONLY) != 0, NULL, NULL, NULL, NULL);
  369. }
  370. /* return the written or read size */
  371. int url_close_buf(ByteIOContext *s)
  372. {
  373. return s->buf_ptr - s->buffer;
  374. }