FFmpeg
Loading...
Searching...
No Matches
jpegmpfenc.c
Go to the documentation of this file.
1/*
2 * JPEG Multi-Picture Format muxer
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * Muxes several JPEG images into a single JPEG Multi-Picture Format file.
24 */
25
26#include <stdio.h>
27#include <string.h>
28#include <stddef.h>
29
30#include "libavutil/avassert.h"
31#include "libavutil/avstring.h"
32#include "libavutil/gain_map.h"
33#include "libavutil/internal.h"
34#include "libavutil/mem.h"
35
37#include "libavcodec/exif.h"
38#include "libavcodec/gain_map.h"
39#include "libavcodec/mjpeg.h"
40
41#include "avformat.h"
42#include "avio_internal.h"
43#include "jpegmpf.h"
44#include "mux.h"
45
52
53static const struct {
54 const char *name;
57 [MPF_ROLE_PRIMARY] = { "primary image", MPF_TYPE_PRIMARY },
58 [MPF_ROLE_GAIN_MAP] = { "gain map image", MPF_TYPE_GAIN_MAP },
59};
60
61typedef struct MPFImage MPFImage;
62struct MPFImage {
64 int index;
66
67 /* Relative to the packet data (before splicing) */
68 int app2; /* offset to role-specific APP2 header */
69 int has_xmp; /* image already carries an XMP packet */
70 int has_hdrgm; /* .. containing Ultra HDR gain map metadata */
71 int splice_pos; /* where in `packet->data` to splice our segments */
72
73 /* Relative to the output file (after splicing) */
74 int64_t start, end; /* start and end of this image in the output stream */
75 int64_t ext_size[MPF_EXT_NB]; /* APP2 payload sizes */
76
77 /* Image dependency metadata */
79 MPFImage *rev_deps[2]; /* maximum 2 permissible by the spec */
81};
82
83typedef struct MPFMuxContext {
85
86 /* Holds the XMP GContainer; if needed */
87#define XMP_GCONTAINER_MAX_LEN 1024 /* see XMP_GCONTAINER_TEMPLATE */
88 char xmp_gcontainer[1024];
89 int xmp_len; /* or 0 */
91
93{
94 if (base->nb_rev_deps == FF_ARRAY_ELEMS(base->rev_deps)) {
95 av_log(ctx, AV_LOG_ERROR, "Stream %d cannot depend on %d, maximum "
96 "number of dependents reached (%d).\n", img->index, base->index,
97 (int) FF_ARRAY_ELEMS(base->rev_deps));
98 return AVERROR(EINVAL);
99 }
100
101 base->rev_deps[base->nb_rev_deps++] = img;
102 img->dep = base;
103 return 0;
104}
105
107{
108 MPFMuxContext *s = ctx->priv_data;
110 if (sg->nb_entries != 2 || lv->el_index >= sg->nb_entries)
111 return AVERROR(EINVAL);
112
115 return AVERROR(EINVAL);
116
117 const AVStream *bl = sg->entries[!lv->el_index]->stream;
118 const AVStream *el = sg->entries[lv->el_index]->stream;
119 MPFImage *base = &s->images[bl->index];
120 MPFImage *gain = &s->images[el->index];
121
122 if (base->index != 0) {
123 av_log(ctx, AV_LOG_ERROR, "Stream group %u: the gain map base layer must "
124 "be the primary image (stream 0), got stream %d\n",
125 sg->index, base->index);
126 return AVERROR(EINVAL);
127 }
128
129 if (gain->role != MPF_ROLE_UNKNOWN) {
130 av_log(ctx, AV_LOG_ERROR, "Stream group %u: stream %d already used "
131 "as %s for a different stream group.\n", sg->index, gain->index,
132 mpf_roles[gain->role].name);
133 return AVERROR(EINVAL);
134 }
135
136 for (int i = 0; i < base->nb_rev_deps; i++) {
137 const MPFImage *other = base->rev_deps[i];
138 if (other->role == MPF_ROLE_GAIN_MAP) {
139 av_log(ctx, AV_LOG_ERROR, "Stream group %u: stream %d already "
140 "specified as a gain map for stream %d.\n", sg->index,
141 other->index, base->index);
142 return AVERROR(EINVAL);
143 }
144 }
145
146 gain->role = MPF_ROLE_GAIN_MAP;
147 return register_dep(ctx, gain, base);
148}
149
151{
152 int ret;
153
154 MPFMuxContext *s = ctx->priv_data;
155 if (ctx->nb_streams < 2)
156 av_log(ctx, AV_LOG_WARNING, "Specified only a single stream (no-op)\n");
157
158 s->images = av_calloc(ctx->nb_streams, sizeof(*s->images));
159 if (!s->images)
160 return AVERROR(ENOMEM);
161
162 for (int i = 0; i < ctx->nb_streams; i++) {
163 MPFImage *img = &s->images[i];
164 img->index = i;
165 img->start = img->end = -1;
166 for (int n = 0; n < MPF_EXT_NB; n++)
167 img->ext_size[n] = -1;
168 img->packet = av_packet_alloc();
169 if (!img->packet)
170 return AVERROR(ENOMEM);
171 }
172
173 /* Classify streams by their role */
174 s->images[0].role = MPF_ROLE_PRIMARY;
175
176 for (unsigned i = 0; i < ctx->nb_stream_groups; i++) {
177 const AVStreamGroup *sg = ctx->stream_groups[i];
178 switch (sg->type) {
180 if ((ret = init_gain_map(ctx, sg)) < 0)
181 return ret;
182 break;
183
184 default:
185 av_log(ctx, AV_LOG_ERROR, "Stream group %u: unknown type '%s'\n", i,
187 return AVERROR(EINVAL);
188 }
189 }
190
191 for (int i = 0; i < ctx->nb_streams; i++) {
192 if (s->images[i].role == MPF_ROLE_UNKNOWN) {
193 av_log(ctx, AV_LOG_ERROR, "Missing stream group for stream %d.\n", i);
194 return AVERROR(EINVAL);
195 }
196 }
197
198 return 0;
199}
200
201static void parse_app1(MPFImage *img, const GetByteContext *gb, int len)
202{
203 if (len < sizeof(FF_GAIN_MAP_XMP_IDENT) ||
205 return; /* not an XMP packet; e.g. Exif */
206
207 img->has_xmp = 1;
208 img->has_hdrgm = !!av_strnstr(gb->buffer, FF_GAIN_MAP_XMP_NAMESPACE, len);
209}
210
212 const GetByteContext *gb, int len)
213{
214#define CHECK_IDENT(strc) (len >= sizeof(strc) && !memcmp(gb->buffer, strc, sizeof(strc)))
215 switch (img->role) {
218 if (img->app2) {
219 av_log(ctx, AV_LOG_ERROR, "Stream %d: multiple ISO 21496-1 "
220 "APP2 segments\n", img->index);
221 return AVERROR_INVALIDDATA;
222 }
223
224 if (len < sizeof(AV_ISO21496_IDENTIFIER) + sizeof(uint16_t[2])) {
225 av_log(ctx, AV_LOG_ERROR, "Stream %d: ISO 21496-1 payload too "
226 "short\n", img->index);
227 return AVERROR_INVALIDDATA;
228 }
229 img->app2 = bytestream2_tell(gb);
230 }
231 break;
232 }
233#undef CHECK_IDENT
234
235 return 0;
236}
237
239{
240 int ret;
241 MPFMuxContext *s = ctx->priv_data;
242 MPFImage *img = &s->images[pkt->stream_index];
243 if (img->packet->size) {
244 av_log(ctx, AV_LOG_ERROR, "Stream %d: expected a single JPEG image\n", img->index);
245 return AVERROR(EINVAL);
246 }
247
249 bytestream2_init(&gb, pkt->data, pkt->size);
250 if (bytestream2_get_bytes_left(&gb) < 2 ||
251 bytestream2_get_be16(&gb) != (0xFF00 | SOI))
252 {
253 av_log(ctx, AV_LOG_ERROR, "Stream %d: not a JPEG image (no SOI)\n", img->index);
254 return AVERROR_INVALIDDATA;
255 }
256
257 /* Walk the JPEG marker sections up until the start of entropy coded data */
258 while (bytestream2_get_bytes_left(&gb) >= 4) {
259 const int pos = bytestream2_tell(&gb);
260 if (bytestream2_get_byte(&gb) != 0xFF) {
261 av_log(ctx, AV_LOG_ERROR, "Stream %d: malformed JPEG marker at 0x%x\n",
262 img->index, pos);
263 return AVERROR_INVALIDDATA;
264 }
265
266 int marker = bytestream2_get_byte(&gb);
267 while (marker == 0xFF) /* fill bytes */
268 marker = bytestream2_get_byte(&gb);
269 if (marker == SOS || marker == TEM || (marker >= RST0 && marker <= EOI)) {
270 if (!img->splice_pos)
271 img->splice_pos = pos;
272 break; /* start of entropy coded data */
273 }
274
275 int len = bytestream2_get_be16(&gb) - 2;
277 av_log(ctx, AV_LOG_ERROR, "Stream %d: truncated marker segment at "
278 "0x%x\n", img->index, pos);
279 return AVERROR_INVALIDDATA;
280 }
281
282 switch (marker) {
283 case APP0:
284 break; /* ignored */
285 case APP1:
286 parse_app1(img, &gb, len);
287 break; /* not spliced past */
288 case APP2:
289 ret = parse_app2(ctx, img, &gb, len);
290 if (ret < 0)
291 return ret;
293 default:
294 /**
295 * Splice position for the MPF metadata shall be the first segment
296 * position after any SOI, APP0 or APP1 (cf. CIPA DC-007)
297 */
298 if (!img->splice_pos)
299 img->splice_pos = pos;
300 break;
301 }
302
303 bytestream2_skip(&gb, len);
304 }
305
306 /* Verify completeness of all needed information */
307 switch (img->role) {
308 case MPF_ROLE_PRIMARY:
309 if (!img->splice_pos) {
310 av_log(ctx, AV_LOG_ERROR, "Stream %d: truncated JPEG data\n", img->index);
311 return AVERROR_INVALIDDATA;
312 }
313 break;
315 if (!img->app2) {
316 av_log(ctx, AV_LOG_ERROR, "Stream %d was declared as a gain map "
317 "but is missing ISO 21496-1 metadata\n", img->index);
318 return AVERROR_INVALIDDATA;
319 }
320 break;
321 }
322
323 return av_packet_ref(img->packet, pkt);
324}
325
327{
328 int64_t val = avio_tell(pb) - base;
329 av_assert0(val >= 0);
330 av_assert0(*offset < 0 || *offset == val);
331 *offset = val;
332}
333
334#define XMP_GCONTAINER_TEMPLATE \
335 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 5.1.2\">\n" \
336 " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n" \
337 " <rdf:Description\n" \
338 " xmlns:Container=\"" XMP_CONTAINER_NS "\"\n" \
339 " xmlns:Item=\"" XMP_ITEM_NS "\"\n" \
340 " xmlns:hdrgm=\"" FF_GAIN_MAP_XMP_NAMESPACE "\"\n" \
341 " hdrgm:Version=\"1.0\">\n" \
342 " <Container:Directory>\n" \
343 " <rdf:Seq>\n" \
344 " <rdf:li rdf:parseType=\"Resource\">\n" \
345 " <Container:Item\n" \
346 " Item:Semantic=\"Primary\"\n" \
347 " Item:Mime=\"image/jpeg\"/>\n" \
348 " </rdf:li>\n" \
349 " <rdf:li rdf:parseType=\"Resource\">\n" \
350 " <Container:Item\n" \
351 " Item:Semantic=\"GainMap\"\n" \
352 " Item:Mime=\"image/jpeg\"\n" \
353 " Item:Length=\"%d\"/>\n" \
354 " </rdf:li>\n" \
355 " </rdf:Seq>\n" \
356 " </Container:Directory>\n" \
357 " </rdf:Description>\n" \
358 " </rdf:RDF>\n" \
359 "</x:xmpmeta>"
360
361static_assert(XMP_GCONTAINER_MAX_LEN > sizeof(XMP_GCONTAINER_TEMPLATE) + 10,
362 "XMP buffer too small for template and values");
363
365{
366 MPFMuxContext *s = ctx->priv_data;
367 const MPFImage *base = &s->images[0];
368 const MPFImage *gain = NULL;
369 for (int i = 0; i < base->nb_rev_deps; i++) {
370 if (base->rev_deps[i]->role == MPF_ROLE_GAIN_MAP)
371 gain = base->rev_deps[i];
372 }
373
374 if (!gain || !gain->has_hdrgm)
375 return 0;
376
377 if (base->has_xmp) {
378 av_log(ctx, AV_LOG_WARNING, "The primary image already carries an XMP "
379 "packet; omitting the GContainer directory, as a JPEG file may "
380 "only contain one.\n");
381 return 0;
382 }
383
384 int ret = snprintf(s->xmp_gcontainer, sizeof(s->xmp_gcontainer),
386 if (ret < 0 || ret >= sizeof(s->xmp_gcontainer))
387 return AVERROR_BUG;
388
389 s->xmp_len = ret;
390 return 0;
391}
392
394{
395 const MPFMuxContext *s = ctx->priv_data;
396
397 avio_w8(pb, 0xFF);
398 avio_w8(pb, APP1);
399
400 const int64_t start = avio_tell(pb);
401 avio_wb16(pb, img->ext_size[MPF_EXT_XMP]);
403 avio_write(pb, s->xmp_gcontainer, s->xmp_len);
404
405 update_offset(pb, start, &img->ext_size[MPF_EXT_XMP]);
406}
407
409 MPFImage *img)
410{
411 const MPFMuxContext *s = ctx->priv_data;
412
413 avio_w8(pb, 0xFF);
414 avio_w8(pb, APP2);
415 const int64_t app2_start = avio_tell(pb) - base;
416 avio_wb16(pb, img->ext_size[MPF_EXT_INDEX]);
417 avio_write(pb, "MPF\0", 4);
418
419 /* every offset below is relative to this byte */
420 int64_t tiff_base = avio_tell(pb) - base;
421#define RELPOS(x) (avio_tell(pb) - base - tiff_base + (x))
422
423 avio_write(pb, "MM\0*", 4); /* big endian */
424 avio_wb32(pb, RELPOS(4)); /* offset to first IFD */
425
426 /* First (and only) IFD */
427 const int nb_tags = 3; /* MPFVersion, NumberOfImages, MPEntry */
428 avio_wb16(pb, nb_tags); /* number of IFD tags */
429
430 /* MPFVersion tag */
433 avio_wb32(pb, 4); /* count */
434 avio_write(pb, "0100", 4);
435
436 /* NumberOfImages tag */
439 avio_wb32(pb, 1);
440 avio_wb32(pb, ctx->nb_streams);
441
442 /* MPEntry tag */
443 const int64_t entry_size = sizeof(int32_t[3]) + sizeof(int16_t[2]);
446 avio_wb32(pb, ctx->nb_streams * entry_size);
447 avio_wb32(pb, RELPOS(4 + 4)); /* offset to MPEntry data */
448 avio_wb32(pb, 0); /* no MP Attribute IFD, per DC-007 6.1.1.1 */
449
450 for (int i = 0; i < ctx->nb_streams; i++) {
451 const MPFImage *entry = &s->images[i];
452 int64_t size = entry->end - entry->start;
453 av_assert0(size <= UINT32_MAX); /* would overflow null buffer anyways */
454 uint32_t attr = MPF_FORMAT_JPEG | mpf_roles[entry->role].type;
455 if (entry->nb_rev_deps)
456 attr |= MPF_DEPENDENT_PARENT;
457 if (entry->dep)
458 attr |= MPF_DEPENDENT_CHILD;
459
460 avio_wb32(pb, attr);
461 avio_wb32(pb, size);
462
463 /* The data offset of the First Individual Image is always zero */
464 int64_t offset = i ? entry->start - tiff_base : 0;
465 av_assert0(offset <= UINT32_MAX);
466 avio_wb32(pb, offset);
467
468 /* Indices are 1-based; 0 means "no dependent image" */
469 for (int j = 0; j < FF_ARRAY_ELEMS(entry->rev_deps); j++) {
470 const MPFImage *rdep = entry->rev_deps[j];
471 avio_wb16(pb, rdep ? rdep->index + 1 : 0);
472 }
473 }
474#undef RELPOS
475
476 update_offset(pb, base + app2_start, &img->ext_size[MPF_EXT_INDEX]);
477 return 0;
478}
479
481{
482 avio_w8(pb, 0xFF);
483 avio_w8(pb, APP2);
484
485 const int64_t start = avio_tell(pb);
486 avio_wb16(pb, src->ext_size[MPF_EXT_ISO21496]);
487
488 /* The primary image contains a subset of the ISO 21496-1 struct, carrying
489 * just the version header (two 16-bit integers), but no payload */
491 avio_write(pb, src->packet->data + src->app2 + sizeof(AV_ISO21496_IDENTIFIER),
492 sizeof(uint16_t[2]));
493
494 update_offset(pb, start, &src->ext_size[MPF_EXT_ISO21496]);
495}
496
499{
500 MPFMuxContext *s = ctx->priv_data;
501 int ret;
502
503 switch (img->role) {
504 case MPF_ROLE_PRIMARY:
505 /* The GContainer directory goes ahead of the MP Extensions, so that
506 * the latter still directly follow the APP1 segments (DC-007 Fig. 1) */
507 if (s->xmp_len)
508 mpf_write_xmp(ctx, pb, img);
509 if (ctx->nb_streams > 1) {
510 ret = mpf_write_index(ctx, pb, base, img);
511 if (ret < 0)
512 return ret;
513 }
514 break;
515 }
516
517 for (int i = 0; i < img->nb_rev_deps; i++) {
518 MPFImage *rdep = img->rev_deps[i];
519 switch (rdep->role) {
521 mpf_write_iso21496(pb, rdep);
522 break;
523 }
524 }
525
526 return 0;
527}
528
530{
531 MPFMuxContext *s = ctx->priv_data;
532 const int64_t base = avio_tell(pb);
533 int ret;
534
535 for (int i = 0; i < ctx->nb_streams; i++) {
536 MPFImage *img = &s->images[i];
537 const AVPacket *pkt = img->packet;
538
539 update_offset(pb, base, &img->start);
540 avio_write(pb, pkt->data, img->splice_pos);
541 if ((ret = mpf_write_extensions(ctx, pb, base, img)) < 0)
542 return ret;
543 avio_write(pb, pkt->data + img->splice_pos, pkt->size - img->splice_pos);
544 update_offset(pb, base, &img->end);
545 }
546
547 return 0;
548}
549
551{
552 MPFMuxContext *s = ctx->priv_data;
553 int ret;
554
555 for (int i = 0; i < ctx->nb_streams; i++) {
556 if (!s->images[i].packet->size) {
557 av_log(ctx, AV_LOG_ERROR, "No image was supplied on stream %d\n", i);
558 return AVERROR(EINVAL);
559 }
560 }
561
562 if ((ret = mpf_build_gcontainer_xmp(ctx)) < 0)
563 return ret;
564
565 /* Write the whole file once to a null buffer to settle offsets/sizes */
566 AVIOContext *null;
567 if ((ret = ffio_open_null_buf(&null)) < 0)
568 return ret;
569 ret = mpf_write(ctx, null);
570 int size = ffio_close_null_buf(null);
571 if (ret < 0)
572 return ret;
573 else if (size < 0)
574 return size;
575
576 for (int i = 0; i < ctx->nb_streams; i++) {
577 MPFImage *img = &s->images[i];
578 for (int j = 0; j < MPF_EXT_NB; j++) {
579 if (img->ext_size[j] > UINT16_MAX) {
580 av_log(ctx, AV_LOG_ERROR, "Stream %d: APP2 segment %d is too "
581 "large (%"PRId64" bytes)\n", img->index, j, img->ext_size[j]);
582 return AVERROR(EINVAL);
583 }
584 }
585 }
586
587 return mpf_write(ctx, ctx->pb);
588}
589
591{
592 MPFMuxContext *s = ctx->priv_data;
593 if (!s->images)
594 return;
595
596 for (int i = 0; i < ctx->nb_streams; i++)
597 av_packet_free(&s->images[i].packet);
598
599 av_freep(&s->images);
600}
601
603 .p.name = "jpeg_mpf",
604 .p.long_name = NULL_IF_CONFIG_SMALL("JPEG Multi-Picture Format"),
605 .p.mime_type = "image/jpeg",
606 .p.extensions = "jpg,jpeg",
607 .priv_data_size = sizeof(MPFMuxContext),
609 .p.video_codec = AV_CODEC_ID_MJPEG,
610 .flags_internal = FF_OFMT_FLAG_ONLY_DEFAULT_CODECS,
611 .init = mpf_init,
612 .deinit = mpf_uninit,
613 .write_packet = mpf_write_packet,
614 .write_trailer = mpf_write_trailer,
615 .interleave_packet = ff_interleave_packet_passthrough,
616};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFOutputFormat ff_jpeg_mpf_muxer
Definition jpegmpfenc.c:602
#define entry
static AVFormatContext * ctx
int32_t
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Main libavformat public API header.
@ AV_STREAM_GROUP_ENTRY_STREAM
Definition avformat.h:1173
#define AVFMT_NODIMENSIONS
Format does not need width/height.
Definition avformat.h:504
@ AV_STREAM_GROUP_PARAMS_GAIN_MAP
Definition avformat.h:1165
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition avformat.h:500
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
void avio_wb16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:446
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:507
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
int ffio_open_null_buf(AVIOContext **s)
Open a write-only fake memory stream.
Definition aviobuf.c:1430
int ffio_close_null_buf(AVIOContext *s)
Close a null buffer.
Definition aviobuf.c:1440
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define EOI
End Of Image marker.
Definition cpia.c:43
static AVPacket * pkt
EXIF metadata parser.
@ AV_TIFF_LONG
Definition exif.h:45
@ AV_TIFF_UNDEFINED
Definition exif.h:48
int ret
Definition ffplay.c:391
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition packet.c:443
const char * avformat_stream_group_name(enum AVStreamGroupParamsType type)
Definition avformat.c:284
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
char * av_strnstr(const char *haystack, const char *needle, size_t hay_length)
Locate the first occurrence of the string needle in the string haystack where not more than hay_lengt...
Definition avstring.c:71
Shared definitions for JPEG Multi-Picture Format (CIPA DC-007).
@ MPF_EXT_NB
Definition jpegmpf.h:76
@ MPF_EXT_ISO21496
Definition jpegmpf.h:75
@ MPF_EXT_XMP
Definition jpegmpf.h:73
@ MPF_EXT_INDEX
Definition jpegmpf.h:74
@ MPF_DEPENDENT_PARENT
Definition jpegmpf.h:31
@ MPF_FORMAT_JPEG
Definition jpegmpf.h:36
@ MPF_DEPENDENT_CHILD
Definition jpegmpf.h:32
@ MPF_TAG_MPFVersion
Definition jpegmpf.h:66
@ MPF_TAG_NumberOfImages
Definition jpegmpf.h:67
@ MPF_TAG_MPEntry
Definition jpegmpf.h:68
MPFType
Definition jpegmpf.h:40
@ MPF_TYPE_PRIMARY
Definition jpegmpf.h:44
@ MPF_TYPE_GAIN_MAP
Definition jpegmpf.h:46
static int mpf_build_gcontainer_xmp(AVFormatContext *ctx)
Definition jpegmpfenc.c:364
static int mpf_write_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition jpegmpfenc.c:238
static int mpf_write_trailer(AVFormatContext *ctx)
Definition jpegmpfenc.c:550
static int register_dep(AVFormatContext *ctx, MPFImage *img, MPFImage *base)
Definition jpegmpfenc.c:92
enum MPFType type
Definition jpegmpfenc.c:55
static int mpf_write(AVFormatContext *ctx, AVIOContext *pb)
Definition jpegmpfenc.c:529
static int mpf_write_index(AVFormatContext *ctx, AVIOContext *pb, int64_t base, MPFImage *img)
Definition jpegmpfenc.c:408
static int init_gain_map(AVFormatContext *ctx, const AVStreamGroup *sg)
Definition jpegmpfenc.c:106
static void mpf_write_xmp(AVFormatContext *ctx, AVIOContext *pb, MPFImage *img)
Definition jpegmpfenc.c:393
#define XMP_GCONTAINER_TEMPLATE
Definition jpegmpfenc.c:334
static const struct @351235250060104351276150033220250051201364246176 mpf_roles[MPF_ROLE_NB]
#define XMP_GCONTAINER_MAX_LEN
Definition jpegmpfenc.c:87
static void parse_app1(MPFImage *img, const GetByteContext *gb, int len)
Definition jpegmpfenc.c:201
static int mpf_write_extensions(AVFormatContext *ctx, AVIOContext *pb, int64_t base, MPFImage *img)
Definition jpegmpfenc.c:497
#define CHECK_IDENT(strc)
static int parse_app2(AVFormatContext *ctx, MPFImage *img, const GetByteContext *gb, int len)
Definition jpegmpfenc.c:211
static void update_offset(AVIOContext *pb, int64_t base, int64_t *offset)
Definition jpegmpfenc.c:326
MPFRole
Definition jpegmpfenc.c:46
@ MPF_ROLE_GAIN_MAP
Definition jpegmpfenc.c:49
@ MPF_ROLE_UNKNOWN
Definition jpegmpfenc.c:47
@ MPF_ROLE_PRIMARY
Definition jpegmpfenc.c:48
@ MPF_ROLE_NB
Definition jpegmpfenc.c:50
#define RELPOS(x)
static int mpf_init(AVFormatContext *ctx)
Definition jpegmpfenc.c:150
static void mpf_write_iso21496(AVIOContext *pb, MPFImage *src)
Definition jpegmpfenc.c:480
static void mpf_uninit(AVFormatContext *ctx)
Definition jpegmpfenc.c:590
unsigned offset
Definition libaomenc.c:763
Serialization of AVGainMapParams into the metadata blobs that image formats carry it in,...
#define FF_GAIN_MAP_XMP_IDENT
Definition gain_map.h:36
#define FF_GAIN_MAP_XMP_NAMESPACE
Definition gain_map.h:37
int ff_interleave_packet_passthrough(AVFormatContext *s, AVPacket *pkt, int flush, int has_packet)
Interleave packets directly in the order in which they arrive without any sort of buffering.
Definition mux.c:1066
#define av_fallthrough
Definition attributes.h:67
#define AV_ISO21496_IDENTIFIER
Definition gain_map.h:28
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:97
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
MJPEG encoder and decoder.
@ RST0
Definition mjpeg.h:61
@ APP1
Definition mjpeg.h:80
@ APP2
Definition mjpeg.h:81
@ SOS
Definition mjpeg.h:72
@ APP0
Definition mjpeg.h:79
@ TEM
Definition mjpeg.h:113
@ SOI
Definition mjpeg.h:70
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
If this flag is set, then the only permitted audio/video/subtitle codec ids are AVOutputFormat....
Definition mux.h:59
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
unsigned int pos
Definition spdifenc.c:431
Format I/O context.
Definition avformat.h:1401
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:587
int size
Definition packet.h:611
enum AVStreamGroupEntryType type
Definition avformat.h:1178
AVStream * stream
Definition avformat.h:1180
AVStreamGroupLayeredVideo is meant to define the relation between a base layer video stream and a sep...
Definition avformat.h:1104
unsigned int el_index
Index of the enhancement layer stream in AVStreamGroup.
Definition avformat.h:1113
unsigned int nb_entries
Number of elements in AVStreamGroup.entries.
Definition avformat.h:1286
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1212
AVStreamGroupEntry ** entries
A list of streams or child groups in the group.
Definition avformat.h:1299
unsigned int index
Group index in AVFormatContext.
Definition avformat.h:1196
union AVStreamGroup::@313244315204024013007202273061153315146016101155 params
Group type-specific parameters.
struct AVStreamGroupLayeredVideo * layered_video
Definition avformat.h:1221
Stream structure.
Definition avformat.h:768
int index
stream index in AVFormatContext
Definition avformat.h:774
const uint8_t * buffer
Definition bytestream.h:34
int index
Definition jpegmpfenc.c:64
AVPacket * packet
Definition jpegmpfenc.c:63
int64_t ext_size[MPF_EXT_NB]
Definition jpegmpfenc.c:75
MPFImage * rev_deps[2]
Definition jpegmpfenc.c:79
int splice_pos
Definition jpegmpfenc.c:71
int has_xmp
Definition jpegmpfenc.c:69
int has_hdrgm
Definition jpegmpfenc.c:70
int64_t end
Definition jpegmpfenc.c:74
MPFImage * dep
Definition jpegmpfenc.c:78
int nb_rev_deps
Definition jpegmpfenc.c:80
MPFRole role
Definition jpegmpfenc.c:65
int64_t start
Definition jpegmpfenc.c:74
MPFImage * images
Definition jpegmpfenc.c:84
char xmp_gcontainer[1024]
Definition jpegmpfenc.c:88
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
int size
#define img
int len
uint8_t base
Definition vp3data.h:128