2 * Various muxing utility functions
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/dict.h"
23 #include "libavutil/internal.h"
24 #include "libavutil/log.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/parseutils.h"
32 int avformat_query_codec(const AVOutputFormat
*ofmt
, enum AVCodecID codec_id
,
36 unsigned int codec_tag
;
37 if (ffofmt(ofmt
)->query_codec
)
38 return ffofmt(ofmt
)->query_codec(codec_id
, std_compliance
);
39 else if (ofmt
->codec_tag
)
40 return !!av_codec_get_tag2(ofmt
->codec_tag
, codec_id
, &codec_tag
);
41 else if (codec_id
!= AV_CODEC_ID_NONE
&&
42 (codec_id
== ofmt
->video_codec
||
43 codec_id
== ofmt
->audio_codec
||
44 codec_id
== ofmt
->subtitle_codec
))
46 else if (ffofmt(ofmt
)->flags_internal
& FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
)
48 else if (ffofmt(ofmt
)->flags_internal
& FF_OFMT_FLAG_MAX_ONE_OF_EACH
) {
49 enum AVMediaType type
= avcodec_get_type(codec_id
);
51 case AVMEDIA_TYPE_AUDIO
:
52 if (ofmt
->audio_codec
== AV_CODEC_ID_NONE
)
55 case AVMEDIA_TYPE_VIDEO
:
56 if (ofmt
->video_codec
== AV_CODEC_ID_NONE
)
59 case AVMEDIA_TYPE_SUBTITLE
:
60 if (ofmt
->subtitle_codec
== AV_CODEC_ID_NONE
)
68 return AVERROR_PATCHWELCOME
;
71 int ff_format_shift_data(AVFormatContext
*s
, int64_t read_start
, int shift_size
)
75 uint8_t *buf
, *read_buf
[2];
80 buf
= av_malloc_array(shift_size
, 2);
82 return AVERROR(ENOMEM
);
84 read_buf
[1] = buf
+ shift_size
;
86 /* Shift the data: the AVIO context of the output can only be used for
87 * writing, so we re-open the same output, but for reading. It also avoids
88 * a read/seek/write/seek back and forth. */
90 ret
= s
->io_open(s
, &read_pb
, s
->url
, AVIO_FLAG_READ
, NULL
);
92 av_log(s
, AV_LOG_ERROR
, "Unable to re-open %s output file for shifting data\n", s
->url
);
96 /* mark the end of the shift to up to the last data we wrote, and get ready
98 pos_end
= avio_tell(s
->pb
);
99 avio_seek(s
->pb
, read_start
+ shift_size
, SEEK_SET
);
101 avio_seek(read_pb
, read_start
, SEEK_SET
);
102 pos
= avio_tell(read_pb
);
104 #define READ_BLOCK do { \
105 read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
109 /* shift data by chunk of at most shift_size */
114 n
= read_size
[read_buf_id
];
117 avio_write(s
->pb
, read_buf
[read_buf_id
], n
);
119 } while (pos
< pos_end
);
120 ret
= ff_format_io_close(s
, &read_pb
);
127 int ff_format_output_open(AVFormatContext
*s
, const char *url
, AVDictionary
**options
)
130 return AVERROR(EINVAL
);
132 if (!(s
->oformat
->flags
& AVFMT_NOFILE
))
133 return s
->io_open(s
, &s
->pb
, url
, AVIO_FLAG_WRITE
, options
);
137 int ff_parse_creation_time_metadata(AVFormatContext
*s
, int64_t *timestamp
, int return_seconds
)
139 AVDictionaryEntry
*entry
;
140 int64_t parsed_timestamp
;
142 if ((entry
= av_dict_get(s
->metadata
, "creation_time", NULL
, 0))) {
143 if ((ret
= av_parse_time(&parsed_timestamp
, entry
->value
, 0)) >= 0) {
144 *timestamp
= return_seconds
? parsed_timestamp
/ 1000000 : parsed_timestamp
;
147 av_log(s
, AV_LOG_WARNING
, "Failed to parse creation_time %s\n", entry
->value
);
154 int ff_standardize_creation_time(AVFormatContext
*s
)
157 int ret
= ff_parse_creation_time_metadata(s
, ×tamp
, 0);
159 return ff_dict_set_timestamp(&s
->metadata
, "creation_time", timestamp
);