BeOS fix: NOT every ld likes undefined syms, include C++ objs, and link to libs neede...
[libav.git] / libavformat / utils.c
CommitLineData
de6d9b64
FB
1/*
2 * Various utilities for ffmpeg system
19720f15 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
de6d9b64 4 *
19720f15
FB
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.
de6d9b64 9 *
19720f15 10 * This library is distributed in the hope that it will be useful,
de6d9b64 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
de6d9b64 14 *
19720f15
FB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
de6d9b64 18 */
8be1c656 19#include "avformat.h"
c5510dd6 20#include <ctype.h>
f3ec2d46 21#ifdef CONFIG_WIN32
8be1c656
FB
22#define strcasecmp _stricmp
23#include <sys/types.h>
24#include <sys/timeb.h>
f3ec2d46
SG
25#elif defined(CONFIG_OS2)
26#include <string.h>
27#define strcasecmp stricmp
28#include <sys/time.h>
29#else
30#include <unistd.h>
31#include <fcntl.h>
32#include <sys/time.h>
8be1c656 33#endif
9235088f 34#include <time.h>
de6d9b64 35
c5510dd6
PG
36#ifndef HAVE_STRPTIME
37#include "strptime.h"
38#endif
39
b9a281db
FB
40AVInputFormat *first_iformat;
41AVOutputFormat *first_oformat;
87a0a681 42AVImageFormat *first_image_format;
de6d9b64 43
b9a281db 44void av_register_input_format(AVInputFormat *format)
de6d9b64 45{
b9a281db
FB
46 AVInputFormat **p;
47 p = &first_iformat;
48 while (*p != NULL) p = &(*p)->next;
49 *p = format;
50 format->next = NULL;
51}
52
53void av_register_output_format(AVOutputFormat *format)
54{
55 AVOutputFormat **p;
56 p = &first_oformat;
de6d9b64
FB
57 while (*p != NULL) p = &(*p)->next;
58 *p = format;
59 format->next = NULL;
60}
61
5b25dfa7 62int match_ext(const char *filename, const char *extensions)
de6d9b64
FB
63{
64 const char *ext, *p;
65 char ext1[32], *q;
66
67 ext = strrchr(filename, '.');
68 if (ext) {
69 ext++;
70 p = extensions;
71 for(;;) {
72 q = ext1;
73 while (*p != '\0' && *p != ',')
74 *q++ = *p++;
75 *q = '\0';
76 if (!strcasecmp(ext1, ext))
77 return 1;
78 if (*p == '\0')
79 break;
80 p++;
81 }
82 }
83 return 0;
84}
85
b9a281db
FB
86AVOutputFormat *guess_format(const char *short_name, const char *filename,
87 const char *mime_type)
de6d9b64 88{
b9a281db 89 AVOutputFormat *fmt, *fmt_found;
de6d9b64
FB
90 int score_max, score;
91
87a0a681 92 /* specific test for image sequences */
94d883e8
FB
93 if (!short_name && filename &&
94 filename_number_test(filename) >= 0 &&
95 guess_image_format(filename)) {
87a0a681
FB
96 return guess_format("image", NULL, NULL);
97 }
98
de6d9b64
FB
99 /* find the proper file type */
100 fmt_found = NULL;
101 score_max = 0;
b9a281db 102 fmt = first_oformat;
de6d9b64
FB
103 while (fmt != NULL) {
104 score = 0;
105 if (fmt->name && short_name && !strcmp(fmt->name, short_name))
106 score += 100;
107 if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
108 score += 10;
109 if (filename && fmt->extensions &&
110 match_ext(filename, fmt->extensions)) {
111 score += 5;
112 }
113 if (score > score_max) {
114 score_max = score;
115 fmt_found = fmt;
116 }
117 fmt = fmt->next;
118 }
119 return fmt_found;
120}
121
c5510dd6
PG
122AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
123 const char *mime_type)
124{
125 AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
126
127 if (fmt) {
128 AVOutputFormat *stream_fmt;
129 char stream_format_name[64];
130
131 snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
132 stream_fmt = guess_format(stream_format_name, NULL, NULL);
133
134 if (stream_fmt)
135 fmt = stream_fmt;
136 }
137
138 return fmt;
139}
140
b9a281db
FB
141AVInputFormat *av_find_input_format(const char *short_name)
142{
143 AVInputFormat *fmt;
144 for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
145 if (!strcmp(fmt->name, short_name))
146 return fmt;
147 }
148 return NULL;
149}
150
de6d9b64
FB
151/* memory handling */
152
b9a281db 153/**
6fa5a56c
FB
154 * Default packet destructor
155 */
156static void av_destruct_packet(AVPacket *pkt)
157{
158 av_free(pkt->data);
159 pkt->data = NULL; pkt->size = 0;
160}
161
162/**
b9a281db
FB
163 * Allocate the payload of a packet and intialized its fields to default values.
164 *
165 * @param pkt packet
166 * @param size wanted payload size
167 * @return 0 if OK. AVERROR_xxx otherwise.
168 */
de6d9b64
FB
169int av_new_packet(AVPacket *pkt, int size)
170{
6fa5a56c
FB
171 void *data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
172 if (!data)
b9a281db 173 return AVERROR_NOMEM;
6fa5a56c 174 memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
8cd5be98 175
6fa5a56c
FB
176 av_init_packet(pkt);
177 pkt->data = data;
178 pkt->size = size;
179 pkt->destruct = av_destruct_packet;
de6d9b64
FB
180 return 0;
181}
182
de6d9b64
FB
183/* fifo handling */
184
185int fifo_init(FifoBuffer *f, int size)
186{
1ea4f593 187 f->buffer = av_malloc(size);
de6d9b64
FB
188 if (!f->buffer)
189 return -1;
190 f->end = f->buffer + size;
191 f->wptr = f->rptr = f->buffer;
192 return 0;
193}
194
195void fifo_free(FifoBuffer *f)
196{
1ea4f593 197 av_free(f->buffer);
de6d9b64
FB
198}
199
0c1a9eda 200int fifo_size(FifoBuffer *f, uint8_t *rptr)
de6d9b64
FB
201{
202 int size;
203
204 if (f->wptr >= rptr) {
205 size = f->wptr - rptr;
206 } else {
207 size = (f->end - rptr) + (f->wptr - f->buffer);
208 }
209 return size;
210}
211
212/* get data from the fifo (return -1 if not enough data) */
0c1a9eda 213int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
de6d9b64 214{
0c1a9eda 215 uint8_t *rptr = *rptr_ptr;
de6d9b64
FB
216 int size, len;
217
218 if (f->wptr >= rptr) {
219 size = f->wptr - rptr;
220 } else {
221 size = (f->end - rptr) + (f->wptr - f->buffer);
222 }
223
224 if (size < buf_size)
225 return -1;
226 while (buf_size > 0) {
227 len = f->end - rptr;
228 if (len > buf_size)
229 len = buf_size;
230 memcpy(buf, rptr, len);
231 buf += len;
232 rptr += len;
233 if (rptr >= f->end)
234 rptr = f->buffer;
235 buf_size -= len;
236 }
237 *rptr_ptr = rptr;
238 return 0;
239}
240
0c1a9eda 241void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr)
de6d9b64
FB
242{
243 int len;
0c1a9eda 244 uint8_t *wptr;
de6d9b64
FB
245 wptr = *wptr_ptr;
246 while (size > 0) {
247 len = f->end - wptr;
248 if (len > size)
249 len = size;
250 memcpy(wptr, buf, len);
251 wptr += len;
252 if (wptr >= f->end)
253 wptr = f->buffer;
254 buf += len;
255 size -= len;
256 }
257 *wptr_ptr = wptr;
258}
259
b9a281db
FB
260int filename_number_test(const char *filename)
261{
262 char buf[1024];
263 return get_frame_filename(buf, sizeof(buf), filename, 1);
264}
265
266/* guess file format */
a25e098d 267AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
b9a281db
FB
268{
269 AVInputFormat *fmt1, *fmt;
270 int score, score_max;
271
272 fmt = NULL;
273 score_max = 0;
274 for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
275 if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
276 continue;
277 score = 0;
a8dbe951
PG
278 if (fmt1->read_probe) {
279 score = fmt1->read_probe(pd);
280 } else if (fmt1->extensions) {
b9a281db
FB
281 if (match_ext(pd->filename, fmt1->extensions)) {
282 score = 50;
283 }
a8dbe951 284 }
b9a281db
FB
285 if (score > score_max) {
286 score_max = score;
287 fmt = fmt1;
288 }
289 }
290 return fmt;
291}
292
293/************************************************************/
294/* input media file */
96baaa6a 295
b9a281db
FB
296#define PROBE_BUF_SIZE 2048
297
298/**
299 * Open a media file as input. The codec are not opened. Only the file
300 * header (if present) is read.
301 *
302 * @param ic_ptr the opened media file handle is put here
303 * @param filename filename to open.
304 * @param fmt if non NULL, force the file format to use
305 * @param buf_size optional buffer size (zero if default is OK)
306 * @param ap additionnal parameters needed when opening the file (NULL if default)
307 * @return 0 if OK. AVERROR_xxx otherwise.
308 */
309int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
310 AVInputFormat *fmt,
311 int buf_size,
312 AVFormatParameters *ap)
de6d9b64 313{
de6d9b64 314 AVFormatContext *ic = NULL;
de6d9b64 315 int err;
b9a281db
FB
316 char buf[PROBE_BUF_SIZE];
317 AVProbeData probe_data, *pd = &probe_data;
de6d9b64
FB
318
319 ic = av_mallocz(sizeof(AVFormatContext));
b9a281db
FB
320 if (!ic) {
321 err = AVERROR_NOMEM;
de6d9b64 322 goto fail;
de6d9b64 323 }
b9a281db
FB
324 pstrcpy(ic->filename, sizeof(ic->filename), filename);
325 pd->filename = ic->filename;
326 pd->buf = buf;
327 pd->buf_size = 0;
328
329 if (!fmt) {
330 /* guess format if no file can be opened */
a25e098d 331 fmt = av_probe_input_format(pd, 0);
de6d9b64 332 }
de6d9b64 333
b9a281db 334 if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
87a0a681 335 /* if no file needed do not try to open one */
b9a281db
FB
336 if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
337 err = AVERROR_IO;
96baaa6a 338 goto fail;
b9a281db 339 }
96baaa6a
FB
340 if (buf_size > 0) {
341 url_setbufsize(&ic->pb, buf_size);
342 }
5b25dfa7
FB
343 if (!fmt) {
344 /* read probe data */
345 pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
346 url_fseek(&ic->pb, 0, SEEK_SET);
347 }
96baaa6a
FB
348 }
349
b9a281db
FB
350 /* guess file format */
351 if (!fmt) {
a25e098d 352 fmt = av_probe_input_format(pd, 1);
b9a281db
FB
353 }
354
355 /* if still no format found, error */
356 if (!fmt) {
357 err = AVERROR_NOFMT;
a05c8d71 358 goto fail1;
de6d9b64 359 }
b9a281db 360
67d06418 361 /* XXX: suppress this hack for redirectors */
f3ec2d46 362#ifdef CONFIG_NETWORK
67d06418
FB
363 if (fmt == &redir_demux) {
364 err = redir_open(ic_ptr, &ic->pb);
365 url_fclose(&ic->pb);
366 av_free(ic);
367 return err;
368 }
9b2e001f 369#endif
67d06418 370
b9a281db 371 ic->iformat = fmt;
de6d9b64 372
87a0a681
FB
373 /* check filename in case of an image number is expected */
374 if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
375 if (filename_number_test(ic->filename) < 0) {
376 err = AVERROR_NUMEXPECTED;
377 goto fail1;
378 }
379 }
380
b9a281db 381 /* allocate private data */
98486a6b
RS
382 if (fmt->priv_data_size > 0) {
383 ic->priv_data = av_mallocz(fmt->priv_data_size);
384 if (!ic->priv_data) {
385 err = AVERROR_NOMEM;
a05c8d71 386 goto fail1;
98486a6b
RS
387 }
388 } else
389 ic->priv_data = NULL;
b9a281db 390
916c80e9
FB
391 /* default pts settings is MPEG like */
392 av_set_pts_info(ic, 33, 1, 90000);
393
b9a281db
FB
394 err = ic->iformat->read_header(ic, ap);
395 if (err < 0)
396 goto fail1;
397 *ic_ptr = ic;
398 return 0;
399 fail1:
a05c8d71 400 if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
b9a281db
FB
401 url_fclose(&ic->pb);
402 }
de6d9b64 403 fail:
b9a281db 404 if (ic) {
a8dbe951 405 av_freep(&ic->priv_data);
b9a281db 406 }
1ea4f593 407 av_free(ic);
b9a281db
FB
408 *ic_ptr = NULL;
409 return err;
de6d9b64
FB
410}
411
b9a281db
FB
412/**
413 * Read a packet from a media file
414 * @param s media file handle
415 * @param pkt is filled
416 * @return 0 if OK. AVERROR_xxx if error.
417 */
de6d9b64
FB
418int av_read_packet(AVFormatContext *s, AVPacket *pkt)
419{
420 AVPacketList *pktl;
421
422 pktl = s->packet_buffer;
423 if (pktl) {
424 /* read packet from packet buffer, if there is data */
425 *pkt = pktl->pkt;
426 s->packet_buffer = pktl->next;
1ea4f593 427 av_free(pktl);
de6d9b64
FB
428 return 0;
429 } else {
b9a281db
FB
430 return s->iformat->read_packet(s, pkt);
431 }
432}
433
434/* state for codec information */
435#define CSTATE_NOTFOUND 0
436#define CSTATE_DECODING 1
437#define CSTATE_FOUND 2
438
439static int has_codec_parameters(AVCodecContext *enc)
440{
441 int val;
442 switch(enc->codec_type) {
443 case CODEC_TYPE_AUDIO:
444 val = enc->sample_rate;
445 break;
446 case CODEC_TYPE_VIDEO:
447 val = enc->width;
448 break;
449 default:
450 val = 1;
451 break;
452 }
453 return (val != 0);
454}
455
456/**
457 * Read the beginning of a media file to get stream information. This
458 * is useful for file formats with no headers such as MPEG. This
459 * function also compute the real frame rate in case of mpeg2 repeat
460 * frame mode.
461 *
462 * @param ic media file handle
463 * @return >=0 if OK. AVERROR_xxx if error.
464 */
465int av_find_stream_info(AVFormatContext *ic)
466{
467 int i, count, ret, got_picture, size, read_size;
468 AVCodec *codec;
469 AVStream *st;
470 AVPacket *pkt;
492cd3a9 471 AVFrame picture;
b9a281db
FB
472 AVPacketList *pktl=NULL, **ppktl;
473 short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
0c1a9eda 474 uint8_t *ptr;
b9a281db
FB
475 int min_read_size, max_read_size;
476
477 /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
b530f842 478 Mbits. We read at most 0.2 second of file to find all streams */
b9a281db
FB
479
480 /* XXX: base it on stream bitrate when possible */
481 if (ic->iformat == &mpegts_demux) {
482 /* maximum number of bytes we accept to read to find all the streams
483 in a file */
b530f842 484 min_read_size = 6000000;
b9a281db 485 } else {
b530f842 486 min_read_size = 250000;
b9a281db
FB
487 }
488 /* max read size is 2 seconds of video max */
b530f842 489 max_read_size = min_read_size * 10;
b9a281db
FB
490
491 /* set initial codec state */
492 for(i=0;i<ic->nb_streams;i++) {
493 st = ic->streams[i];
494 if (has_codec_parameters(&st->codec))
495 st->codec_info_state = CSTATE_FOUND;
496 else
497 st->codec_info_state = CSTATE_NOTFOUND;
498 st->codec_info_nb_repeat_frames = 0;
499 st->codec_info_nb_real_frames = 0;
500 }
501
502 count = 0;
503 read_size = 0;
504 ppktl = &ic->packet_buffer;
505 for(;;) {
506 /* check if one codec still needs to be handled */
507 for(i=0;i<ic->nb_streams;i++) {
508 st = ic->streams[i];
509 if (st->codec_info_state != CSTATE_FOUND)
510 break;
511 }
512 if (i == ic->nb_streams) {
513 /* NOTE: if the format has no header, then we need to read
514 some packets to get most of the streams, so we cannot
515 stop here */
516 if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
517 read_size >= min_read_size) {
518 /* if we found the info for all the codecs, we can stop */
519 ret = count;
520 break;
521 }
522 } else {
523 /* we did not get all the codec info, but we read too much data */
524 if (read_size >= max_read_size) {
525 ret = count;
526 break;
527 }
528 }
529
530 pktl = av_mallocz(sizeof(AVPacketList));
531 if (!pktl) {
532 ret = AVERROR_NOMEM;
533 break;
534 }
535
536 /* add the packet in the buffered packet list */
537 *ppktl = pktl;
538 ppktl = &pktl->next;
539
540 /* NOTE: a new stream can be added there if no header in file
541 (AVFMT_NOHEADER) */
542 pkt = &pktl->pkt;
543 if (ic->iformat->read_packet(ic, pkt) < 0) {
544 /* EOF or error */
545 ret = -1; /* we could not have all the codec parameters before EOF */
546 if ((ic->iformat->flags & AVFMT_NOHEADER) &&
547 i == ic->nb_streams)
548 ret = 0;
549 break;
550 }
551 read_size += pkt->size;
552
553 /* open new codecs */
554 for(i=0;i<ic->nb_streams;i++) {
555 st = ic->streams[i];
556 if (st->codec_info_state == CSTATE_NOTFOUND) {
557 /* set to found in case of error */
558 st->codec_info_state = CSTATE_FOUND;
559 codec = avcodec_find_decoder(st->codec.codec_id);
560 if (codec) {
d7425f59
MN
561 if(codec->capabilities & CODEC_CAP_TRUNCATED)
562 st->codec.flags |= CODEC_FLAG_TRUNCATED;
563
b9a281db
FB
564 ret = avcodec_open(&st->codec, codec);
565 if (ret >= 0)
566 st->codec_info_state = CSTATE_DECODING;
567 }
568 }
569 }
570
571 st = ic->streams[pkt->stream_index];
572 if (st->codec_info_state == CSTATE_DECODING) {
573 /* decode the data and update codec parameters */
574 ptr = pkt->data;
575 size = pkt->size;
576 while (size > 0) {
577 switch(st->codec.codec_type) {
578 case CODEC_TYPE_VIDEO:
579 ret = avcodec_decode_video(&st->codec, &picture,
580 &got_picture, ptr, size);
581 break;
582 case CODEC_TYPE_AUDIO:
583 ret = avcodec_decode_audio(&st->codec, samples,
584 &got_picture, ptr, size);
585 break;
586 default:
587 ret = -1;
588 break;
589 }
590 if (ret < 0) {
591 /* if error, simply ignore because another packet
592 may be OK */
593 break;
594 }
595 if (got_picture) {
596 /* we got the parameters - now we can stop
597 examining this stream */
598 /* XXX: add a codec info so that we can decide if
599 the codec can repeat frames */
600 if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO &&
601 ic->iformat != &mpegts_demux &&
602 st->codec.sub_id == 2) {
603 /* for mpeg2 video, we want to know the real
604 frame rate, so we decode 40 frames. In mpeg
605 TS case we do not do it because it would be
606 too long */
607 st->codec_info_nb_real_frames++;
2ec23b6d 608 st->codec_info_nb_repeat_frames += st->codec.coded_frame->repeat_pict;
b9a281db
FB
609#if 0
610 /* XXX: testing */
611 if ((st->codec_info_nb_real_frames % 24) == 23) {
612 st->codec_info_nb_repeat_frames += 2;
613 }
614#endif
615 /* stop after 40 frames */
616 if (st->codec_info_nb_real_frames >= 40) {
14bea432
MN
617 av_reduce(
618 &st->r_frame_rate,
619 &st->r_frame_rate_base,
620 (int64_t)st->codec.frame_rate * st->codec_info_nb_real_frames,
e71ea8b2 621 (st->codec_info_nb_real_frames + (st->codec_info_nb_repeat_frames >> 1)) * st->codec.frame_rate_base,
14bea432 622 1<<30);
b9a281db
FB
623 goto close_codec;
624 }
625 } else {
626 close_codec:
627 st->codec_info_state = CSTATE_FOUND;
628 avcodec_close(&st->codec);
24f9709b 629 break;
b9a281db 630 }
b9a281db
FB
631 }
632 ptr += ret;
633 size -= ret;
634 }
635 }
636 count++;
637 }
638
639 /* close each codec if there are opened */
640 for(i=0;i<ic->nb_streams;i++) {
641 st = ic->streams[i];
642 if (st->codec_info_state == CSTATE_DECODING)
643 avcodec_close(&st->codec);
644 }
645
646 /* set real frame rate info */
647 for(i=0;i<ic->nb_streams;i++) {
648 st = ic->streams[i];
649 if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
14bea432
MN
650 if (!st->r_frame_rate){
651 st->r_frame_rate = st->codec.frame_rate;
652 st->r_frame_rate_base = st->codec.frame_rate_base;
653 }
b9a281db 654 }
de6d9b64 655 }
b9a281db
FB
656
657 return ret;
de6d9b64
FB
658}
659
b9a281db
FB
660/**
661 * Close a media file (but not its codecs)
662 *
663 * @param s media file handle
664 */
de6d9b64
FB
665void av_close_input_file(AVFormatContext *s)
666{
667 int i;
668
b9a281db
FB
669 if (s->iformat->read_close)
670 s->iformat->read_close(s);
de6d9b64 671 for(i=0;i<s->nb_streams;i++) {
1ea4f593 672 av_free(s->streams[i]);
de6d9b64
FB
673 }
674 if (s->packet_buffer) {
675 AVPacketList *p, *p1;
676 p = s->packet_buffer;
677 while (p != NULL) {
678 p1 = p->next;
679 av_free_packet(&p->pkt);
1ea4f593 680 av_free(p);
de6d9b64
FB
681 p = p1;
682 }
683 s->packet_buffer = NULL;
684 }
b9a281db 685 if (!(s->iformat->flags & AVFMT_NOFILE)) {
96baaa6a
FB
686 url_fclose(&s->pb);
687 }
a8dbe951 688 av_freep(&s->priv_data);
1ea4f593 689 av_free(s);
de6d9b64
FB
690}
691
b9a281db
FB
692/**
693 * Add a new stream to a media file. Can only be called in the
694 * read_header function. If the flag AVFMT_NOHEADER is in the format
695 * description, then new streams can be added in read_packet too.
696 *
697 *
698 * @param s media file handle
699 * @param id file format dependent stream id
700 */
701AVStream *av_new_stream(AVFormatContext *s, int id)
702{
703 AVStream *st;
704
705 if (s->nb_streams >= MAX_STREAMS)
706 return NULL;
707
708 st = av_mallocz(sizeof(AVStream));
709 if (!st)
710 return NULL;
1e491e29
MN
711 avcodec_get_context_defaults(&st->codec);
712
b9a281db
FB
713 st->index = s->nb_streams;
714 st->id = id;
715 s->streams[s->nb_streams++] = st;
716 return st;
717}
718
719/************************************************************/
720/* output media file */
de6d9b64 721
87a0a681
FB
722int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
723{
724 int ret;
98486a6b
RS
725
726 if (s->oformat->priv_data_size > 0) {
727 s->priv_data = av_mallocz(s->oformat->priv_data_size);
728 if (!s->priv_data)
729 return AVERROR_NOMEM;
730 } else
731 s->priv_data = NULL;
732
87a0a681
FB
733 if (s->oformat->set_parameters) {
734 ret = s->oformat->set_parameters(s, ap);
735 if (ret < 0)
736 return ret;
737 }
738 return 0;
739}
740
b9a281db
FB
741/**
742 * allocate the stream private data and write the stream header to an
743 * output media file
744 *
745 * @param s media file handle
746 * @return 0 if OK. AVERROR_xxx if error.
747 */
748int av_write_header(AVFormatContext *s)
749{
1e51d801
FB
750 int ret, i;
751 AVStream *st;
752
916c80e9
FB
753 /* default pts settings is MPEG like */
754 av_set_pts_info(s, 33, 1, 90000);
1e51d801
FB
755 ret = s->oformat->write_header(s);
756 if (ret < 0)
757 return ret;
758
759 /* init PTS generation */
760 for(i=0;i<s->nb_streams;i++) {
761 st = s->streams[i];
762
763 switch (st->codec.codec_type) {
764 case CODEC_TYPE_AUDIO:
765 av_frac_init(&st->pts, 0, 0,
0c1a9eda 766 (int64_t)s->pts_num * st->codec.sample_rate);
1e51d801
FB
767 break;
768 case CODEC_TYPE_VIDEO:
769 av_frac_init(&st->pts, 0, 0,
0c1a9eda 770 (int64_t)s->pts_num * st->codec.frame_rate);
1e51d801
FB
771 break;
772 default:
773 break;
774 }
775 }
776 return 0;
b9a281db
FB
777}
778
779/**
1e51d801
FB
780 * Write a packet to an output media file. The packet shall contain
781 * one audio or video frame.
b9a281db
FB
782 *
783 * @param s media file handle
1e51d801
FB
784 * @param stream_index stream index
785 * @param buf buffer containing the frame data
786 * @param size size of buffer
d4c0ff91 787 * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
b9a281db 788 */
1e51d801
FB
789int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf,
790 int size)
de6d9b64 791{
1e51d801 792 AVStream *st;
0c1a9eda 793 int64_t pts_mask;
7feb950a 794 int ret, frame_size;
1e51d801
FB
795
796 st = s->streams[stream_index];
797 pts_mask = (1LL << s->pts_wrap_bits) - 1;
798 ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size,
799 st->pts.val & pts_mask);
800 if (ret < 0)
801 return ret;
802
803 /* update pts */
804 switch (st->codec.codec_type) {
805 case CODEC_TYPE_AUDIO:
7feb950a
FB
806 if (st->codec.frame_size <= 1) {
807 frame_size = size / st->codec.channels;
808 /* specific hack for pcm codecs because no frame size is provided */
50d5d129 809 switch(st->codec.codec_id) {
7feb950a
FB
810 case CODEC_ID_PCM_S16LE:
811 case CODEC_ID_PCM_S16BE:
812 case CODEC_ID_PCM_U16LE:
813 case CODEC_ID_PCM_U16BE:
814 frame_size >>= 1;
815 break;
816 default:
817 break;
818 }
819 } else {
820 frame_size = st->codec.frame_size;
821 }
1e51d801 822 av_frac_add(&st->pts,
0c1a9eda 823 (int64_t)s->pts_den * frame_size);
1e51d801
FB
824 break;
825 case CODEC_TYPE_VIDEO:
826 av_frac_add(&st->pts,
14bea432 827 (int64_t)s->pts_den * st->codec.frame_rate_base);
1e51d801
FB
828 break;
829 default:
830 break;
831 }
d4c0ff91 832 return ret;
b9a281db
FB
833}
834
835/**
836 * write the stream trailer to an output media file and and free the
837 * file private data.
838 *
839 * @param s media file handle
840 * @return 0 if OK. AVERROR_xxx if error. */
841int av_write_trailer(AVFormatContext *s)
842{
843 int ret;
844 ret = s->oformat->write_trailer(s);
845 av_freep(&s->priv_data);
846 return ret;
de6d9b64
FB
847}
848
849/* "user interface" functions */
850
851void dump_format(AVFormatContext *ic,
852 int index,
853 const char *url,
854 int is_output)
855{
b9a281db 856 int i, flags;
de6d9b64
FB
857 char buf[256];
858
859 fprintf(stderr, "%s #%d, %s, %s '%s':\n",
860 is_output ? "Output" : "Input",
b9a281db
FB
861 index,
862 is_output ? ic->oformat->name : ic->iformat->name,
de6d9b64
FB
863 is_output ? "to" : "from", url);
864 for(i=0;i<ic->nb_streams;i++) {
865 AVStream *st = ic->streams[i];
866 avcodec_string(buf, sizeof(buf), &st->codec, is_output);
b9a281db
FB
867 fprintf(stderr, " Stream #%d.%d", index, i);
868 /* the pid is an important information, so we display it */
869 /* XXX: add a generic system */
870 if (is_output)
871 flags = ic->oformat->flags;
872 else
873 flags = ic->iformat->flags;
874 if (flags & AVFMT_SHOW_IDS) {
875 fprintf(stderr, "[0x%x]", st->id);
876 }
877 fprintf(stderr, ": %s\n", buf);
de6d9b64
FB
878 }
879}
880
881typedef struct {
445f1b83 882 const char *abv;
de6d9b64 883 int width, height;
445f1b83
RS
884 int frame_rate, frame_rate_base;
885} AbvEntry;
886
887static AbvEntry frame_abvs[] = {
888 { "ntsc", 352, 240, 30000, 1001 },
889 { "pal", 352, 288, 25, 1 },
890 { "film", 352, 240, 24, 1 },
891 { "ntsc-film", 352, 240, 24000, 1001 },
892 { "sqcif", 128, 96, 0, 0 },
893 { "qcif", 176, 144, 0, 0 },
894 { "cif", 352, 288, 0, 0 },
895 { "4cif", 704, 576, 0, 0 },
de6d9b64 896};
445f1b83 897
de6d9b64
FB
898int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
899{
900 int i;
445f1b83 901 int n = sizeof(frame_abvs) / sizeof(AbvEntry);
de6d9b64
FB
902 const char *p;
903 int frame_width = 0, frame_height = 0;
904
905 for(i=0;i<n;i++) {
445f1b83
RS
906 if (!strcmp(frame_abvs[i].abv, str)) {
907 frame_width = frame_abvs[i].width;
908 frame_height = frame_abvs[i].height;
de6d9b64
FB
909 break;
910 }
911 }
912 if (i == n) {
913 p = str;
914 frame_width = strtol(p, (char **)&p, 10);
915 if (*p)
916 p++;
917 frame_height = strtol(p, (char **)&p, 10);
918 }
919 if (frame_width <= 0 || frame_height <= 0)
920 return -1;
921 *width_ptr = frame_width;
922 *height_ptr = frame_height;
923 return 0;
924}
925
445f1b83
RS
926int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg)
927{
928 int i;
929 char* cp;
930
931 /* First, we check our abbreviation table */
932 for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i)
933 if (!strcmp(frame_abvs[i].abv, arg)) {
934 *frame_rate = frame_abvs[i].frame_rate;
935 *frame_rate_base = frame_abvs[i].frame_rate_base;
936 return 0;
937 }
938
939 /* Then, we try to parse it as fraction */
940 cp = strchr(arg, '/');
941 if (cp) {
942 char* cpp;
943 *frame_rate = strtol(arg, &cpp, 10);
944 if (cpp != arg || cpp == cp)
945 *frame_rate_base = strtol(cp+1, &cpp, 10);
946 else
947 *frame_rate = 0;
948 }
949 else {
950 /* Finally we give up and parse it as double */
951 *frame_rate_base = DEFAULT_FRAME_RATE_BASE;
952 *frame_rate = (int)(strtod(arg, 0) * (*frame_rate_base) + 0.5);
953 }
954 if (!*frame_rate || !*frame_rate_base)
955 return -1;
956 else
957 return 0;
958}
959
0c1a9eda 960int64_t av_gettime(void)
de6d9b64 961{
8be1c656
FB
962#ifdef CONFIG_WIN32
963 struct _timeb tb;
964 _ftime(&tb);
0c1a9eda 965 return ((int64_t)tb.time * int64_t_C(1000) + (int64_t)tb.millitm) * int64_t_C(1000);
8be1c656 966#else
de6d9b64
FB
967 struct timeval tv;
968 gettimeofday(&tv,NULL);
0c1a9eda 969 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
8be1c656 970#endif
de6d9b64
FB
971}
972
c5510dd6
PG
973static time_t mktimegm(struct tm *tm)
974{
975 time_t t;
976
977 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
978
979 if (m < 3) {
980 m += 12;
981 y--;
982 }
983
984 t = 86400 *
985 (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
986
987 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
988
989 return t;
990}
991
916c80e9
FB
992/* Syntax:
993 * - If not a duration:
994 * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
c5510dd6 995 * Time is localtime unless Z is suffixed to the end. In this case GMT
916c80e9
FB
996 * Return the date in micro seconds since 1970
997 * - If duration:
998 * HH[:MM[:SS[.m...]]]
999 * S+[.m...]
1000 */
0c1a9eda 1001int64_t parse_date(const char *datestr, int duration)
de6d9b64
FB
1002{
1003 const char *p;
0c1a9eda 1004 int64_t t;
2dbceb9f 1005 struct tm dt;
c5510dd6
PG
1006 int i;
1007 static const char *date_fmt[] = {
1008 "%Y-%m-%d",
1009 "%Y%m%d",
1010 };
1011 static const char *time_fmt[] = {
1012 "%H:%M:%S",
1013 "%H%M%S",
1014 };
1015 const char *q;
916c80e9 1016 int is_utc, len;
c5510dd6
PG
1017 char lastch;
1018 time_t now = time(0);
1019
916c80e9
FB
1020 len = strlen(datestr);
1021 if (len > 0)
1022 lastch = datestr[len - 1];
1023 else
1024 lastch = '\0';
c5510dd6 1025 is_utc = (lastch == 'z' || lastch == 'Z');
2dbceb9f
PG
1026
1027 memset(&dt, 0, sizeof(dt));
de6d9b64
FB
1028
1029 p = datestr;
916c80e9 1030 q = NULL;
de6d9b64 1031 if (!duration) {
c5510dd6
PG
1032 for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
1033 q = strptime(p, date_fmt[i], &dt);
1034 if (q) {
1035 break;
1036 }
1037 }
1038
1039 if (!q) {
1040 if (is_utc) {
1041 dt = *gmtime(&now);
1042 } else {
1043 dt = *localtime(&now);
1044 }
1045 dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
de6d9b64 1046 } else {
c5510dd6 1047 p = q;
de6d9b64 1048 }
c5510dd6
PG
1049
1050 if (*p == 'T' || *p == 't' || *p == ' ')
1051 p++;
c5510dd6 1052
916c80e9
FB
1053 for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
1054 q = strptime(p, time_fmt[i], &dt);
1055 if (q) {
1056 break;
1057 }
1058 }
1059 } else {
1060 q = strptime(p, time_fmt[0], &dt);
1061 if (!q) {
1062 dt.tm_sec = strtol(p, (char **)&q, 10);
1063 dt.tm_min = 0;
1064 dt.tm_hour = 0;
c5510dd6
PG
1065 }
1066 }
1067
1068 /* Now we have all the fields that we can get */
1069 if (!q) {
1070 if (duration)
1071 return 0;
1072 else
0c1a9eda 1073 return now * int64_t_C(1000000);
de6d9b64 1074 }
2dbceb9f
PG
1075
1076 if (duration) {
c5510dd6 1077 t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
2dbceb9f 1078 } else {
c5510dd6
PG
1079 dt.tm_isdst = -1; /* unknown */
1080 if (is_utc) {
1081 t = mktimegm(&dt);
1082 } else {
1083 t = mktime(&dt);
1084 }
de6d9b64 1085 }
2dbceb9f 1086
c5510dd6
PG
1087 t *= 1000000;
1088
1089 if (*q == '.') {
de6d9b64 1090 int val, n;
c5510dd6
PG
1091 q++;
1092 for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
1093 if (!isdigit(*q))
1094 break;
1095 val += n * (*q - '0');
de6d9b64
FB
1096 }
1097 t += val;
1098 }
1099 return t;
1100}
1101
2dbceb9f 1102/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return
de6d9b64
FB
1103 1 if found */
1104int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
1105{
1106 const char *p;
1107 char tag[128], *q;
1108
1109 p = info;
1110 if (*p == '?')
1111 p++;
1112 for(;;) {
1113 q = tag;
1114 while (*p != '\0' && *p != '=' && *p != '&') {
1115 if ((q - tag) < sizeof(tag) - 1)
1116 *q++ = *p;
1117 p++;
1118 }
1119 *q = '\0';
1120 q = arg;
1121 if (*p == '=') {
1122 p++;
1123 while (*p != '&' && *p != '\0') {
2dbceb9f
PG
1124 if ((q - arg) < arg_size - 1) {
1125 if (*p == '+')
1126 *q++ = ' ';
1127 else
1128 *q++ = *p;
1129 }
de6d9b64
FB
1130 p++;
1131 }
1132 *q = '\0';
1133 }
1134 if (!strcmp(tag, tag1))
1135 return 1;
1136 if (*p != '&')
1137 break;
8d1335ea 1138 p++;
de6d9b64
FB
1139 }
1140 return 0;
1141}
1142
9150f42e
FB
1143/* Return in 'buf' the path with '%d' replaced by number. Also handles
1144 the '%0nd' format where 'n' is the total number of digits and
1145 '%%'. Return 0 if OK, and -1 if format error */
1146int get_frame_filename(char *buf, int buf_size,
1147 const char *path, int number)
1148{
1149 const char *p;
1150 char *q, buf1[20];
1151 int nd, len, c, percentd_found;
1152
1153 q = buf;
1154 p = path;
1155 percentd_found = 0;
1156 for(;;) {
1157 c = *p++;
1158 if (c == '\0')
1159 break;
1160 if (c == '%') {
c9646fda
PG
1161 do {
1162 nd = 0;
1163 while (isdigit(*p)) {
1164 nd = nd * 10 + *p++ - '0';
1165 }
1166 c = *p++;
1167 if (c == '*' && nd > 0) {
1168 // The nd field is actually the modulus
1169 number = number % nd;
1170 c = *p++;
1171 nd = 0;
1172 }
1173 } while (isdigit(c));
1174
9150f42e
FB
1175 switch(c) {
1176 case '%':
1177 goto addchar;
1178 case 'd':
1179 if (percentd_found)
1180 goto fail;
1181 percentd_found = 1;
1182 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
1183 len = strlen(buf1);
1184 if ((q - buf + len) > buf_size - 1)
1185 goto fail;
1186 memcpy(q, buf1, len);
1187 q += len;
1188 break;
1189 default:
1190 goto fail;
1191 }
1192 } else {
1193 addchar:
1194 if ((q - buf) < buf_size - 1)
1195 *q++ = c;
1196 }
1197 }
1198 if (!percentd_found)
1199 goto fail;
1200 *q = '\0';
1201 return 0;
1202 fail:
1203 *q = '\0';
1204 return -1;
1205}
1206
b9a281db
FB
1207/**
1208 *
1209 * Print on stdout a nice hexa dump of a buffer
1210 * @param buf buffer
1211 * @param size buffer size
1212 */
0c1a9eda 1213void av_hex_dump(uint8_t *buf, int size)
b9a281db
FB
1214{
1215 int len, i, j, c;
1216
1217 for(i=0;i<size;i+=16) {
1218 len = size - i;
1219 if (len > 16)
1220 len = 16;
1221 printf("%08x ", i);
1222 for(j=0;j<16;j++) {
1223 if (j < len)
1224 printf(" %02x", buf[i+j]);
1225 else
1226 printf(" ");
1227 }
1228 printf(" ");
1229 for(j=0;j<len;j++) {
1230 c = buf[i+j];
1231 if (c < ' ' || c > '~')
1232 c = '.';
1233 printf("%c", c);
1234 }
1235 printf("\n");
1236 }
1237}
1238
a9a721da
FB
1239void url_split(char *proto, int proto_size,
1240 char *hostname, int hostname_size,
1241 int *port_ptr,
1242 char *path, int path_size,
1243 const char *url)
1244{
1245 const char *p;
1246 char *q;
1247 int port;
1248
1249 port = -1;
1250
1251 p = url;
1252 q = proto;
1253 while (*p != ':' && *p != '\0') {
1254 if ((q - proto) < proto_size - 1)
1255 *q++ = *p;
1256 p++;
1257 }
1258 if (proto_size > 0)
1259 *q = '\0';
1260 if (*p == '\0') {
1261 if (proto_size > 0)
1262 proto[0] = '\0';
1263 if (hostname_size > 0)
1264 hostname[0] = '\0';
1265 p = url;
1266 } else {
1267 p++;
1268 if (*p == '/')
1269 p++;
1270 if (*p == '/')
1271 p++;
1272 q = hostname;
1273 while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') {
1274 if ((q - hostname) < hostname_size - 1)
1275 *q++ = *p;
1276 p++;
1277 }
1278 if (hostname_size > 0)
1279 *q = '\0';
1280 if (*p == ':') {
1281 p++;
1282 port = strtoul(p, (char **)&p, 10);
1283 }
1284 }
1285 if (port_ptr)
1286 *port_ptr = port;
1287 pstrcpy(path, path_size, p);
1288}
1289
916c80e9
FB
1290/**
1291 * Set the pts for a given stream
1292 * @param s stream
1293 * @param pts_wrap_bits number of bits effectively used by the pts
1294 * (used for wrap control, 33 is the value for MPEG)
1295 * @param pts_num numerator to convert to seconds (MPEG: 1)
1296 * @param pts_den denominator to convert to seconds (MPEG: 90000)
1297 */
1298void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
1299 int pts_num, int pts_den)
1300{
1301 s->pts_wrap_bits = pts_wrap_bits;
1302 s->pts_num = pts_num;
1303 s->pts_den = pts_den;
1304}
1305
1306/* fraction handling */
1307
1308/**
1309 * f = val + (num / den) + 0.5. 'num' is normalized so that it is such
1310 * as 0 <= num < den.
1311 *
1312 * @param f fractional number
1313 * @param val integer value
1314 * @param num must be >= 0
1315 * @param den must be >= 1
1316 */
0c1a9eda 1317void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
916c80e9
FB
1318{
1319 num += (den >> 1);
1320 if (num >= den) {
1321 val += num / den;
1322 num = num % den;
1323 }
1324 f->val = val;
1325 f->num = num;
1326 f->den = den;
1327}
1328
1329/* set f to (val + 0.5) */
0c1a9eda 1330void av_frac_set(AVFrac *f, int64_t val)
916c80e9
FB
1331{
1332 f->val = val;
1333 f->num = f->den >> 1;
1334}
1335
1336/**
1337 * Fractionnal addition to f: f = f + (incr / f->den)
1338 *
1339 * @param f fractional number
1340 * @param incr increment, can be positive or negative
1341 */
0c1a9eda 1342void av_frac_add(AVFrac *f, int64_t incr)
916c80e9 1343{
0c1a9eda 1344 int64_t num, den;
916c80e9
FB
1345
1346 num = f->num + incr;
1347 den = f->den;
1348 if (num < 0) {
1349 f->val += num / den;
1350 num = num % den;
1351 if (num < 0) {
1352 num += den;
1353 f->val--;
1354 }
1355 } else if (num >= den) {
1356 f->val += num / den;
1357 num = num % den;
1358 }
1359 f->num = num;
1360}
87a0a681
FB
1361
1362/**
1363 * register a new image format
1364 * @param img_fmt Image format descriptor
1365 */
1366void av_register_image_format(AVImageFormat *img_fmt)
1367{
1368 AVImageFormat **p;
1369
1370 p = &first_image_format;
1371 while (*p != NULL) p = &(*p)->next;
1372 *p = img_fmt;
1373 img_fmt->next = NULL;
1374}
1375
1376/* guess image format */
1377AVImageFormat *av_probe_image_format(AVProbeData *pd)
1378{
1379 AVImageFormat *fmt1, *fmt;
1380 int score, score_max;
1381
1382 fmt = NULL;
1383 score_max = 0;
1384 for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1385 if (fmt1->img_probe) {
1386 score = fmt1->img_probe(pd);
1387 if (score > score_max) {
1388 score_max = score;
1389 fmt = fmt1;
1390 }
1391 }
1392 }
1393 return fmt;
1394}
1395
1396AVImageFormat *guess_image_format(const char *filename)
1397{
1398 AVImageFormat *fmt1;
1399
1400 for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) {
1401 if (fmt1->extensions && match_ext(filename, fmt1->extensions))
1402 return fmt1;
1403 }
1404 return NULL;
1405}
1406
1407/**
1408 * Read an image from a stream.
1409 * @param gb byte stream containing the image
1410 * @param fmt image format, NULL if probing is required
1411 */
1412int av_read_image(ByteIOContext *pb, const char *filename,
1413 AVImageFormat *fmt,
1414 int (*alloc_cb)(void *, AVImageInfo *info), void *opaque)
1415{
1416 char buf[PROBE_BUF_SIZE];
1417 AVProbeData probe_data, *pd = &probe_data;
1418 offset_t pos;
1419 int ret;
1420
1421 if (!fmt) {
5c91a675 1422 pd->filename = filename;
87a0a681
FB
1423 pd->buf = buf;
1424 pos = url_ftell(pb);
1425 pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE);
1426 url_fseek(pb, pos, SEEK_SET);
1427 fmt = av_probe_image_format(pd);
1428 }
1429 if (!fmt)
1430 return AVERROR_NOFMT;
1431 ret = fmt->img_read(pb, alloc_cb, opaque);
1432 return ret;
1433}
1434
1435/**
1436 * Write an image to a stream.
1437 * @param pb byte stream for the image output
1438 * @param fmt image format
1439 * @param img image data and informations
1440 */
1441int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img)
1442{
1443 return fmt->img_write(pb, img);
1444}
1445