FFmpeg
Loading...
Searching...
No Matches
mods.c
Go to the documentation of this file.
1/*
2 * MODS demuxer
3 * Copyright (c) 2015-2016 Florian Nouwt
4 * Copyright (c) 2017 Adib Surani
5 * Copyright (c) 2020 Paul B Mahol
6 * Copyright (c) 2026 Link Mauve
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
26
27#include "avformat.h"
28#include "demux.h"
29#include "internal.h"
30
31typedef struct MODSDemuxContext {
32 uint32_t index_pos;
34
35static int mods_probe(const AVProbeData *p)
36{
37 if (memcmp(p->buf, "MODSN3\x0a\x00", 8))
38 return 0;
39 if (AV_RB32(p->buf + 8) == 0)
40 return 0;
41 if (AV_RB32(p->buf + 12) == 0)
42 return 0;
43 if (AV_RB32(p->buf + 16) == 0)
44 return 0;
45 return AVPROBE_SCORE_MAX;
46}
47
49{
50 AVIOContext *pb = s->pb;
51 MODSDemuxContext *ctx = s->priv_data;
52 AVRational fps;
54 int64_t timestamp;
55 int num_keyframes;
56 const AVIndexEntry *e;
57
59 if (!st)
60 return AVERROR(ENOMEM);
61
62 avio_skip(pb, 8);
63
64 st->nb_frames = avio_rl32(pb);
65 st->duration = st->nb_frames;
68 st->codecpar->width = avio_rl32(pb);
69 st->codecpar->height = avio_rl32(pb);
70
71 fps.num = avio_rl32(pb);
72 fps.den = 0x1000000;
73 avpriv_set_pts_info(st, 64, fps.den, fps.num);
74
75 avio_skip(pb, 16);
76
77 pos = avio_rl32(pb);
78 num_keyframes = avio_rl32(pb);
79 avio_seek(pb, pos, SEEK_SET);
80 ctx->index_pos = pos;
81
82 for (int i = 0; i < num_keyframes; ++i) {
83 timestamp = avio_rl32(pb);
84 pos = avio_rl32(pb);
85 if (avio_feof(pb))
87
88 av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
89 }
90
91 e = avformat_index_get_entry(st, 0);
92 if (!e)
94
96 avio_seek(pb, e->pos, SEEK_SET);
97
98 return 0;
99}
100
102{
103 AVIOContext *pb = s->pb;
104 MODSDemuxContext *ctx = s->priv_data;
105 AVStream *st = s->streams[0];
106 unsigned size;
107 int64_t pos;
108 int ret;
109 const AVIndexEntry *e;
110
111 if (avio_feof(pb))
112 return AVERROR_EOF;
113
114 /* This assumes the keyframes index directly follows the last packet. */
115 pos = avio_tell(pb);
116 if (pos == ctx->index_pos)
117 return AVERROR_EOF;
118
119 size = avio_rl32(pb) >> 14;
120 ret = av_get_packet(pb, pkt, size);
121 if (ret < 0)
122 return ret;
123 pkt->pos = pos;
124 pkt->stream_index = 0;
125
126 e = avformat_index_get_entry_from_timestamp(st, ffstream(st)->cur_dts, 0);
127 if (e && e->pos == pos) {
128 pkt->flags |= AV_PKT_FLAG_KEY;
129 pkt->pts = pkt->dts = e->timestamp;
130 }
131
132 return ret;
133}
134
136 .p.name = "mods",
137 .p.long_name = NULL_IF_CONFIG_SMALL("MobiClip MODS"),
138 .p.extensions = "mods",
139 .p.flags = AVFMT_GENERIC_INDEX,
140 .priv_data_size = sizeof(MODSDemuxContext),
144};
const FFInputFormat ff_mods_demuxer
Definition mods.c:135
static AVFormatContext * ctx
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVINDEX_KEYFRAME
Definition avformat.h:628
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition utils.c:98
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
unsigned int avio_rl32(AVIOContext *s)
Definition aviobuf.c:733
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
void avpriv_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
Update cur_dts of all streams based on the given timestamp and AVStream.
Definition seek.c:37
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ AV_CODEC_ID_MOBICLIP
Definition codec_id.h:299
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add an index entry into a sorted list.
Definition seek.c:122
const AVIndexEntry * avformat_index_get_entry(AVStream *st, int idx)
Get the AVIndexEntry corresponding to the given index.
Definition seek.c:257
const AVIndexEntry * avformat_index_get_entry_from_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
Get the AVIndexEntry corresponding to the given timestamp.
Definition seek.c:266
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_RB32(p)
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:365
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static int mods_probe(const AVProbeData *p)
Definition mods.c:35
static int mods_read_header(AVFormatContext *s)
Definition mods.c:48
static int mods_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition mods.c:101
unsigned int pos
Definition spdifenc.c:431
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int width
The width of the video frame in pixels.
Definition codec_par.h:143
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
int64_t pos
Definition avformat.h:621
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition avformat.h:622
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int64_t nb_frames
number of frames in this stream if known or 0
Definition avformat.h:827
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
uint32_t index_pos
Definition mods.c:32
int size