2 * Various utility demuxing 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/mem.h"
24 #include "libavutil/avassert.h"
25 #include "libavcodec/bytestream.h"
26 #include "libavcodec/packet_internal.h"
28 #include "avformat_internal.h"
29 #include "avio_internal.h"
33 struct AVCodecParserContext
*av_stream_get_parser(const AVStream
*st
)
35 return cffstream(st
)->parser
;
38 void avpriv_stream_set_need_parsing(AVStream
*st
, enum AVStreamParseType type
)
40 ffstream(st
)->need_parsing
= type
;
43 AVChapter
*avpriv_new_chapter(AVFormatContext
*s
, int64_t id
, AVRational time_base
,
44 int64_t start
, int64_t end
, const char *title
)
46 FormatContextInternal
*const fci
= ff_fc_internal(s
);
47 AVChapter
*chapter
= NULL
;
50 if (end
!= AV_NOPTS_VALUE
&& start
> end
) {
51 av_log(s
, AV_LOG_ERROR
, "Chapter end time %"PRId64
" before start %"PRId64
"\n", end
, start
);
55 if (!s
->nb_chapters
) {
56 fci
->chapter_ids_monotonic
= 1;
57 } else if (!fci
->chapter_ids_monotonic
|| s
->chapters
[s
->nb_chapters
-1]->id
>= id
) {
58 for (unsigned i
= 0; i
< s
->nb_chapters
; i
++)
59 if (s
->chapters
[i
]->id
== id
)
60 chapter
= s
->chapters
[i
];
62 fci
->chapter_ids_monotonic
= 0;
66 chapter
= av_mallocz(sizeof(*chapter
));
69 ret
= av_dynarray_add_nofree(&s
->chapters
, &s
->nb_chapters
, chapter
);
75 av_dict_set(&chapter
->metadata
, "title", title
, 0);
77 chapter
->time_base
= time_base
;
78 chapter
->start
= start
;
84 int avformat_queue_attached_pictures(AVFormatContext
*s
)
86 FormatContextInternal
*const fci
= ff_fc_internal(s
);
88 for (unsigned i
= 0; i
< s
->nb_streams
; i
++)
89 if (s
->streams
[i
]->disposition
& AV_DISPOSITION_ATTACHED_PIC
&&
90 s
->streams
[i
]->discard
< AVDISCARD_ALL
) {
91 if (s
->streams
[i
]->attached_pic
.size
<= 0) {
92 av_log(s
, AV_LOG_WARNING
,
93 "Attached picture on stream %d has invalid size, "
98 ret
= avpriv_packet_list_put(&fci
->raw_packet_buffer
,
99 &s
->streams
[i
]->attached_pic
,
107 int ff_add_attached_pic(AVFormatContext
*s
, AVStream
*st0
, AVIOContext
*pb
,
108 AVBufferRef
**buf
, int size
)
114 if (!st
&& !(st
= avformat_new_stream(s
, NULL
)))
115 return AVERROR(ENOMEM
);
116 pkt
= &st
->attached_pic
;
119 av_packet_unref(pkt
);
121 pkt
->data
= (*buf
)->data
;
122 pkt
->size
= (*buf
)->size
- AV_INPUT_BUFFER_PADDING_SIZE
;
125 ret
= av_get_packet(pb
, pkt
, size
);
129 st
->disposition
|= AV_DISPOSITION_ATTACHED_PIC
;
130 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
132 pkt
->stream_index
= st
->index
;
133 pkt
->flags
|= AV_PKT_FLAG_KEY
;
138 ff_remove_stream(s
, st
);
142 int ff_add_param_change(AVPacket
*pkt
, int32_t channels
,
143 uint64_t channel_layout
, int32_t sample_rate
,
144 int32_t width
, int32_t height
)
150 return AVERROR(EINVAL
);
154 flags
|= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE
;
156 if (width
|| height
) {
158 flags
|= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS
;
160 data
= av_packet_new_side_data(pkt
, AV_PKT_DATA_PARAM_CHANGE
, size
);
162 return AVERROR(ENOMEM
);
163 bytestream_put_le32(&data
, flags
);
165 bytestream_put_le32(&data
, sample_rate
);
166 if (width
|| height
) {
167 bytestream_put_le32(&data
, width
);
168 bytestream_put_le32(&data
, height
);
173 int av_read_play(AVFormatContext
*s
)
175 if (ffifmt(s
->iformat
)->read_play
)
176 return ffifmt(s
->iformat
)->read_play(s
);
178 return avio_pause(s
->pb
, 0);
179 return AVERROR(ENOSYS
);
182 int av_read_pause(AVFormatContext
*s
)
184 if (ffifmt(s
->iformat
)->read_pause
)
185 return ffifmt(s
->iformat
)->read_pause(s
);
187 return avio_pause(s
->pb
, 1);
188 return AVERROR(ENOSYS
);
191 int ff_generate_avci_extradata(AVStream
*st
)
193 static const uint8_t avci100_1080p_extradata
[] = {
195 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
196 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
197 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
198 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
199 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
200 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
201 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
202 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
203 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
208 static const uint8_t avci100_1080i_extradata
[] = {
210 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
211 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
212 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
213 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
214 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
215 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
216 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
217 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
218 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
219 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
220 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
222 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
225 static const uint8_t avci50_1080p_extradata
[] = {
227 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
228 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
229 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
230 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
231 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
232 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
233 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
234 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
235 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
240 static const uint8_t avci50_1080i_extradata
[] = {
242 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
243 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
244 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
245 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
246 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
247 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
248 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
249 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
250 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
251 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
252 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
254 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
257 static const uint8_t avci100_720p_extradata
[] = {
259 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
260 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
261 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
262 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
263 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
264 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
265 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
266 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
267 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
268 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
273 static const uint8_t avci50_720p_extradata
[] = {
275 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
276 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
277 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
278 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
279 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
280 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
281 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
282 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
283 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
289 const uint8_t *data
= NULL
;
292 if (st
->codecpar
->width
== 1920) {
293 if (st
->codecpar
->field_order
== AV_FIELD_PROGRESSIVE
) {
294 data
= avci100_1080p_extradata
;
295 size
= sizeof(avci100_1080p_extradata
);
297 data
= avci100_1080i_extradata
;
298 size
= sizeof(avci100_1080i_extradata
);
300 } else if (st
->codecpar
->width
== 1440) {
301 if (st
->codecpar
->field_order
== AV_FIELD_PROGRESSIVE
) {
302 data
= avci50_1080p_extradata
;
303 size
= sizeof(avci50_1080p_extradata
);
305 data
= avci50_1080i_extradata
;
306 size
= sizeof(avci50_1080i_extradata
);
308 } else if (st
->codecpar
->width
== 1280) {
309 data
= avci100_720p_extradata
;
310 size
= sizeof(avci100_720p_extradata
);
311 } else if (st
->codecpar
->width
== 960) {
312 data
= avci50_720p_extradata
;
313 size
= sizeof(avci50_720p_extradata
);
319 if ((ret
= ff_alloc_extradata(st
->codecpar
, size
)) < 0)
321 memcpy(st
->codecpar
->extradata
, data
, size
);
326 int ff_get_extradata(void *logctx
, AVCodecParameters
*par
, AVIOContext
*pb
, int size
)
328 int ret
= ff_alloc_extradata(par
, size
);
331 ret
= ffio_read_size(pb
, par
->extradata
, size
);
333 av_freep(&par
->extradata
);
334 par
->extradata_size
= 0;
335 av_log(logctx
, AV_LOG_ERROR
, "Failed to read extradata of size %d\n", size
);
342 int ff_find_stream_index(const AVFormatContext
*s
, int id
)
344 for (unsigned i
= 0; i
< s
->nb_streams
; i
++)
345 if (s
->streams
[i
]->id
== id
)