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.

619 lines
15KB

  1. /*
  2. * Various utilities 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 "avformat.h"
  20. #ifndef CONFIG_WIN32
  21. #include <unistd.h>
  22. #include <fcntl.h>
  23. #include <sys/time.h>
  24. #include <time.h>
  25. #else
  26. #define strcasecmp _stricmp
  27. #include <sys/types.h>
  28. #include <sys/timeb.h>
  29. #endif
  30. AVFormat *first_format;
  31. void register_avformat(AVFormat *format)
  32. {
  33. AVFormat **p;
  34. p = &first_format;
  35. while (*p != NULL) p = &(*p)->next;
  36. *p = format;
  37. format->next = NULL;
  38. }
  39. int match_ext(const char *filename, const char *extensions)
  40. {
  41. const char *ext, *p;
  42. char ext1[32], *q;
  43. ext = strrchr(filename, '.');
  44. if (ext) {
  45. ext++;
  46. p = extensions;
  47. for(;;) {
  48. q = ext1;
  49. while (*p != '\0' && *p != ',')
  50. *q++ = *p++;
  51. *q = '\0';
  52. if (!strcasecmp(ext1, ext))
  53. return 1;
  54. if (*p == '\0')
  55. break;
  56. p++;
  57. }
  58. }
  59. return 0;
  60. }
  61. AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
  62. {
  63. AVFormat *fmt, *fmt_found;
  64. int score_max, score;
  65. /* find the proper file type */
  66. fmt_found = NULL;
  67. score_max = 0;
  68. fmt = first_format;
  69. while (fmt != NULL) {
  70. score = 0;
  71. if (fmt->name && short_name && !strcmp(fmt->name, short_name))
  72. score += 100;
  73. if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
  74. score += 10;
  75. if (filename && fmt->extensions &&
  76. match_ext(filename, fmt->extensions)) {
  77. score += 5;
  78. }
  79. if (score > score_max) {
  80. score_max = score;
  81. fmt_found = fmt;
  82. }
  83. fmt = fmt->next;
  84. }
  85. return fmt_found;
  86. }
  87. /* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
  88. set to the next character in 'str' after the prefix */
  89. int strstart(const char *str, const char *val, const char **ptr)
  90. {
  91. const char *p, *q;
  92. p = str;
  93. q = val;
  94. while (*q != '\0') {
  95. if (*p != *q)
  96. return 0;
  97. p++;
  98. q++;
  99. }
  100. if (ptr)
  101. *ptr = p;
  102. return 1;
  103. }
  104. void nstrcpy(char *buf, int buf_size, const char *str)
  105. {
  106. int c;
  107. char *q = buf;
  108. for(;;) {
  109. c = *str++;
  110. if (c == 0 || q >= buf + buf_size - 1)
  111. break;
  112. *q++ = c;
  113. }
  114. *q = '\0';
  115. }
  116. void register_all(void)
  117. {
  118. avcodec_init();
  119. avcodec_register_all();
  120. register_avformat(&mp2_format);
  121. register_avformat(&ac3_format);
  122. register_avformat(&mpeg_mux_format);
  123. register_avformat(&mpeg1video_format);
  124. register_avformat(&mjpeg_format);
  125. register_avformat(&h263_format);
  126. register_avformat(&rm_format);
  127. register_avformat(&asf_format);
  128. register_avformat(&avi_format);
  129. register_avformat(&mpjpeg_format);
  130. register_avformat(&jpeg_format);
  131. register_avformat(&single_jpeg_format);
  132. register_avformat(&swf_format);
  133. register_avformat(&wav_format);
  134. register_avformat(&pcm_s16le_format);
  135. register_avformat(&pcm_s16be_format);
  136. register_avformat(&pcm_u16le_format);
  137. register_avformat(&pcm_u16be_format);
  138. register_avformat(&pcm_s8_format);
  139. register_avformat(&pcm_u8_format);
  140. register_avformat(&pcm_mulaw_format);
  141. register_avformat(&pcm_alaw_format);
  142. register_avformat(&rawvideo_format);
  143. #ifndef CONFIG_WIN32
  144. register_avformat(&ffm_format);
  145. #endif
  146. register_avformat(&pgm_format);
  147. register_avformat(&ppm_format);
  148. register_avformat(&pgmyuv_format);
  149. register_avformat(&imgyuv_format);
  150. register_avformat(&pgmpipe_format);
  151. register_avformat(&pgmyuvpipe_format);
  152. register_avformat(&ppmpipe_format);
  153. #ifdef CONFIG_GRAB
  154. register_avformat(&video_grab_device_format);
  155. register_avformat(&audio_device_format);
  156. #endif
  157. /* file protocols */
  158. register_protocol(&file_protocol);
  159. register_protocol(&pipe_protocol);
  160. #ifndef CONFIG_WIN32
  161. register_protocol(&udp_protocol);
  162. register_protocol(&http_protocol);
  163. #endif
  164. }
  165. /* memory handling */
  166. int av_new_packet(AVPacket *pkt, int size)
  167. {
  168. pkt->data = malloc(size);
  169. if (!pkt->data)
  170. return -ENOMEM;
  171. pkt->size = size;
  172. /* sane state */
  173. pkt->pts = 0;
  174. pkt->stream_index = 0;
  175. pkt->flags = 0;
  176. return 0;
  177. }
  178. void av_free_packet(AVPacket *pkt)
  179. {
  180. free(pkt->data);
  181. /* fail safe */
  182. pkt->data = NULL;
  183. pkt->size = 0;
  184. }
  185. /* fifo handling */
  186. int fifo_init(FifoBuffer *f, int size)
  187. {
  188. f->buffer = malloc(size);
  189. if (!f->buffer)
  190. return -1;
  191. f->end = f->buffer + size;
  192. f->wptr = f->rptr = f->buffer;
  193. return 0;
  194. }
  195. void fifo_free(FifoBuffer *f)
  196. {
  197. free(f->buffer);
  198. }
  199. int fifo_size(FifoBuffer *f, UINT8 *rptr)
  200. {
  201. int size;
  202. if (f->wptr >= rptr) {
  203. size = f->wptr - rptr;
  204. } else {
  205. size = (f->end - rptr) + (f->wptr - f->buffer);
  206. }
  207. return size;
  208. }
  209. /* get data from the fifo (return -1 if not enough data) */
  210. int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
  211. {
  212. UINT8 *rptr = *rptr_ptr;
  213. int size, len;
  214. if (f->wptr >= rptr) {
  215. size = f->wptr - rptr;
  216. } else {
  217. size = (f->end - rptr) + (f->wptr - f->buffer);
  218. }
  219. if (size < buf_size)
  220. return -1;
  221. while (buf_size > 0) {
  222. len = f->end - rptr;
  223. if (len > buf_size)
  224. len = buf_size;
  225. memcpy(buf, rptr, len);
  226. buf += len;
  227. rptr += len;
  228. if (rptr >= f->end)
  229. rptr = f->buffer;
  230. buf_size -= len;
  231. }
  232. *rptr_ptr = rptr;
  233. return 0;
  234. }
  235. void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
  236. {
  237. int len;
  238. UINT8 *wptr;
  239. wptr = *wptr_ptr;
  240. while (size > 0) {
  241. len = f->end - wptr;
  242. if (len > size)
  243. len = size;
  244. memcpy(wptr, buf, len);
  245. wptr += len;
  246. if (wptr >= f->end)
  247. wptr = f->buffer;
  248. buf += len;
  249. size -= len;
  250. }
  251. *wptr_ptr = wptr;
  252. }
  253. /* media file handling.
  254. 'filename' is the filename to open.
  255. 'format_name' is used to force the file format (NULL if auto guess).
  256. 'buf_size' is the optional buffer size (zero if default is OK).
  257. 'ap' are additionnal parameters needed when opening the file (NULL if default).
  258. */
  259. AVFormatContext *av_open_input_file(const char *filename,
  260. const char *format_name,
  261. int buf_size,
  262. AVFormatParameters *ap)
  263. {
  264. AVFormat *fmt;
  265. AVFormatContext *ic = NULL;
  266. int err;
  267. ic = av_mallocz(sizeof(AVFormatContext));
  268. if (!ic)
  269. goto fail;
  270. /* find format */
  271. if (format_name != NULL) {
  272. fmt = guess_format(format_name, NULL, NULL);
  273. } else {
  274. fmt = guess_format(NULL, filename, NULL);
  275. }
  276. if (!fmt || !fmt->read_header) {
  277. return NULL;
  278. }
  279. ic->format = fmt;
  280. /* if no file needed do not try to open one */
  281. if (!(fmt->flags & AVFMT_NOFILE)) {
  282. if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0)
  283. goto fail;
  284. if (buf_size > 0) {
  285. url_setbufsize(&ic->pb, buf_size);
  286. }
  287. }
  288. err = ic->format->read_header(ic, ap);
  289. if (err < 0) {
  290. if (!(fmt->flags & AVFMT_NOFILE)) {
  291. url_fclose(&ic->pb);
  292. }
  293. goto fail;
  294. }
  295. return ic;
  296. fail:
  297. if (ic)
  298. free(ic);
  299. return NULL;
  300. }
  301. int av_read_packet(AVFormatContext *s, AVPacket *pkt)
  302. {
  303. AVPacketList *pktl;
  304. pktl = s->packet_buffer;
  305. if (pktl) {
  306. /* read packet from packet buffer, if there is data */
  307. *pkt = pktl->pkt;
  308. s->packet_buffer = pktl->next;
  309. free(pktl);
  310. return 0;
  311. } else {
  312. return s->format->read_packet(s, pkt);
  313. }
  314. }
  315. void av_close_input_file(AVFormatContext *s)
  316. {
  317. int i;
  318. if (s->format->read_close)
  319. s->format->read_close(s);
  320. for(i=0;i<s->nb_streams;i++) {
  321. free(s->streams[i]);
  322. }
  323. if (s->packet_buffer) {
  324. AVPacketList *p, *p1;
  325. p = s->packet_buffer;
  326. while (p != NULL) {
  327. p1 = p->next;
  328. av_free_packet(&p->pkt);
  329. free(p);
  330. p = p1;
  331. }
  332. s->packet_buffer = NULL;
  333. }
  334. if (!(s->format->flags & AVFMT_NOFILE)) {
  335. url_fclose(&s->pb);
  336. }
  337. free(s);
  338. }
  339. int av_write_packet(AVFormatContext *s, AVPacket *pkt)
  340. {
  341. /* XXX: currently, an emulation because internal API must change */
  342. return s->format->write_packet(s, pkt->stream_index, pkt->data, pkt->size);
  343. }
  344. /* "user interface" functions */
  345. void dump_format(AVFormatContext *ic,
  346. int index,
  347. const char *url,
  348. int is_output)
  349. {
  350. int i;
  351. char buf[256];
  352. fprintf(stderr, "%s #%d, %s, %s '%s':\n",
  353. is_output ? "Output" : "Input",
  354. index, ic->format->name,
  355. is_output ? "to" : "from", url);
  356. for(i=0;i<ic->nb_streams;i++) {
  357. AVStream *st = ic->streams[i];
  358. avcodec_string(buf, sizeof(buf), &st->codec, is_output);
  359. fprintf(stderr, " Stream #%d.%d: %s\n", index, i, buf);
  360. }
  361. }
  362. typedef struct {
  363. const char *str;
  364. int width, height;
  365. } SizeEntry;
  366. static SizeEntry sizes[] = {
  367. { "sqcif", 128, 96 },
  368. { "qcif", 176, 144 },
  369. { "cif", 352, 288 },
  370. { "4cif", 704, 576 },
  371. };
  372. int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
  373. {
  374. int i;
  375. int n = sizeof(sizes) / sizeof(SizeEntry);
  376. const char *p;
  377. int frame_width = 0, frame_height = 0;
  378. for(i=0;i<n;i++) {
  379. if (!strcmp(sizes[i].str, str)) {
  380. frame_width = sizes[i].width;
  381. frame_height = sizes[i].height;
  382. break;
  383. }
  384. }
  385. if (i == n) {
  386. p = str;
  387. frame_width = strtol(p, (char **)&p, 10);
  388. if (*p)
  389. p++;
  390. frame_height = strtol(p, (char **)&p, 10);
  391. }
  392. if (frame_width <= 0 || frame_height <= 0)
  393. return -1;
  394. *width_ptr = frame_width;
  395. *height_ptr = frame_height;
  396. return 0;
  397. }
  398. INT64 gettime(void)
  399. {
  400. #ifdef CONFIG_WIN32
  401. struct _timeb tb;
  402. _ftime(&tb);
  403. return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000);
  404. #else
  405. struct timeval tv;
  406. gettimeofday(&tv,NULL);
  407. return (INT64)tv.tv_sec * 1000000 + tv.tv_usec;
  408. #endif
  409. }
  410. /* syntax: [YYYY-MM-DD ][[HH:]MM:]SS[.m...] . Return the date in micro seconds since 1970 */
  411. INT64 parse_date(const char *datestr, int duration)
  412. {
  413. const char *p;
  414. INT64 t;
  415. int sec;
  416. p = datestr;
  417. if (!duration) {
  418. static const UINT8 months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  419. int year, month, day, i;
  420. if (strlen(p) >= 5 && p[4] == '-') {
  421. year = strtol(p, (char **)&p, 10);
  422. if (*p)
  423. p++;
  424. month = strtol(p, (char **)&p, 10) - 1;
  425. if (*p)
  426. p++;
  427. day = strtol(p, (char **)&p, 10) - 1;
  428. if (*p)
  429. p++;
  430. day += (year - 1970) * 365;
  431. /* if >= March, take February of current year into account too */
  432. if (month >= 2)
  433. year++;
  434. for(i=1970;i<year;i++) {
  435. if ((i % 100) == 0) {
  436. if ((i % 400) == 0) day++;
  437. } else if ((i % 4) == 0) {
  438. day++;
  439. }
  440. }
  441. for(i=0;i<month;i++)
  442. day += months[i];
  443. } else {
  444. day = (time(NULL) / (3600 * 24));
  445. }
  446. t = day * (3600 * 24);
  447. } else {
  448. t = 0;
  449. }
  450. sec = 0;
  451. for(;;) {
  452. int val;
  453. val = strtol(p, (char **)&p, 10);
  454. sec = sec * 60 + val;
  455. if (*p != ':')
  456. break;
  457. p++;
  458. }
  459. t = (t + sec) * 1000000;
  460. if (*p == '.') {
  461. int val, n;
  462. p++;
  463. n = strlen(p);
  464. if (n > 6)
  465. n = 6;
  466. val = strtol(p, NULL, 10);
  467. while (n < 6) {
  468. val = val * 10;
  469. n++;
  470. }
  471. t += val;
  472. }
  473. return t;
  474. }
  475. /* syntax: '?tag1=val1&tag2=val2...'. No URL decoding is done. Return
  476. 1 if found */
  477. int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
  478. {
  479. const char *p;
  480. char tag[128], *q;
  481. p = info;
  482. if (*p == '?')
  483. p++;
  484. for(;;) {
  485. q = tag;
  486. while (*p != '\0' && *p != '=' && *p != '&') {
  487. if ((q - tag) < sizeof(tag) - 1)
  488. *q++ = *p;
  489. p++;
  490. }
  491. *q = '\0';
  492. q = arg;
  493. if (*p == '=') {
  494. p++;
  495. while (*p != '&' && *p != '\0') {
  496. if ((q - arg) < arg_size - 1)
  497. *q++ = *p;
  498. p++;
  499. }
  500. *q = '\0';
  501. }
  502. if (!strcmp(tag, tag1))
  503. return 1;
  504. if (*p != '&')
  505. break;
  506. }
  507. return 0;
  508. }
  509. /* Return in 'buf' the path with '%d' replaced by number. Also handles
  510. the '%0nd' format where 'n' is the total number of digits and
  511. '%%'. Return 0 if OK, and -1 if format error */
  512. int get_frame_filename(char *buf, int buf_size,
  513. const char *path, int number)
  514. {
  515. const char *p;
  516. char *q, buf1[20];
  517. int nd, len, c, percentd_found;
  518. q = buf;
  519. p = path;
  520. percentd_found = 0;
  521. for(;;) {
  522. c = *p++;
  523. if (c == '\0')
  524. break;
  525. if (c == '%') {
  526. nd = 0;
  527. while (*p >= '0' && *p <= '9') {
  528. nd = nd * 10 + *p++ - '0';
  529. }
  530. c = *p++;
  531. switch(c) {
  532. case '%':
  533. goto addchar;
  534. case 'd':
  535. if (percentd_found)
  536. goto fail;
  537. percentd_found = 1;
  538. snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
  539. len = strlen(buf1);
  540. if ((q - buf + len) > buf_size - 1)
  541. goto fail;
  542. memcpy(q, buf1, len);
  543. q += len;
  544. break;
  545. default:
  546. goto fail;
  547. }
  548. } else {
  549. addchar:
  550. if ((q - buf) < buf_size - 1)
  551. *q++ = c;
  552. }
  553. }
  554. if (!percentd_found)
  555. goto fail;
  556. *q = '\0';
  557. return 0;
  558. fail:
  559. *q = '\0';
  560. return -1;
  561. }