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.

536 lines
12KB

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