FFmpeg
Loading...
Searching...
No Matches
apvdec.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "libavutil/opt.h"
20
21#include "libavcodec/apv.h"
23
24#include "avformat.h"
25#include "avio_internal.h"
26#include "demux.h"
27#include "internal.h"
28
29typedef struct APVDemuxerContext {
30 const AVClass *class; /**< Class for private options. */
31 AVRational framerate; /**< AVRational describing framerate, set by a private option. */
33
34typedef struct APVHeaderInfo {
35 uint8_t pbu_type;
36 uint16_t group_id;
37
38 uint8_t profile_idc;
39 uint8_t level_idc;
40 uint8_t band_idc;
41
44
47
49{
50 APVHeaderInfo header, *info = &header;
51 int zero, byte;
52
53 info->pbu_type = bytestream2_get_byte(gbc);
54 info->group_id = bytestream2_get_be16(gbc);
55
56 zero = bytestream2_get_byte(gbc);
57 if (zero != 0)
59
61 unsigned int num_frames = bytestream2_get_be16(gbc);
62
63 if (num_frames < 1)
65
66 info->pbu_type = bytestream2_get_byte(gbc);
67 if (info->pbu_type != APV_PBU_PRIMARY_FRAME &&
71
72 bytestream2_skip(gbc, 2); // group_id
73 zero = bytestream2_get_byte(gbc);
74 if (zero != 0)
76 } else if (info->pbu_type != APV_PBU_PRIMARY_FRAME)
78
79 info->profile_idc = bytestream2_get_byte(gbc);
80 info->level_idc = bytestream2_get_byte(gbc);
81
82 byte = bytestream2_get_byte(gbc);
83 info->band_idc = byte >> 3;
84 zero = byte & 7;
85 if (zero != 0)
87
88 info->frame_width = bytestream2_get_be24(gbc);
89 info->frame_height = bytestream2_get_be24(gbc);
90 if (info->frame_width < 1 || info->frame_width > 65536 ||
91 info->frame_height < 1 || info->frame_height > 65536)
93
94 byte = bytestream2_get_byte(gbc);
95 info->bit_depth_minus8 = byte & 0xf;
96
97 if (info->bit_depth_minus8 > 8) {
99 }
100 if (info->bit_depth_minus8 % 2) {
101 // Odd bit depths are technically valid but not useful here.
102 return AVERROR_INVALIDDATA;
103 }
104
105 // Ignore capture_time_distance.
106 bytestream2_skip(gbc, 1);
107
108 zero = bytestream2_get_byte(gbc);
109 if (zero != 0)
110 return AVERROR_INVALIDDATA;
111
112 return 1;
113}
114
115static int apv_probe(const AVProbeData *p)
116{
117 GetByteContext gbc;
118 uint32_t au_size, signature, pbu_size;
119 int err;
120
121 if (p->buf_size < 28) {
122 // Too small to fit an APV header.
123 return 0;
124 }
125
126 bytestream2_init(&gbc, p->buf, p->buf_size);
127
128 au_size = bytestream2_get_be32(&gbc);
129 if (au_size < 24) {
130 // Too small.
131 return 0;
132 }
133 signature = bytestream2_get_be32(&gbc);
134 if (signature != APV_SIGNATURE) {
135 // Signature is mandatory.
136 return 0;
137 }
138 pbu_size = bytestream2_get_be32(&gbc);
139 if (pbu_size < 16) {
140 // Too small.
141 return 0;
142 }
143
144 err = apv_extract_header_info(&gbc);
145 if (err < 0) {
146 // Header does not look like APV.
147 return 0;
148 }
149 return AVPROBE_SCORE_MAX;
150}
151
153{
154 APVDemuxerContext *apv = s->priv_data;
155 AVStream *st;
156 GetByteContext gbc;
157 uint8_t buffer[12];
158 uint32_t au_size, signature, pbu_size;
159 int err, size;
160
161 err = ffio_ensure_seekback(s->pb, sizeof(buffer));
162 if (err < 0)
163 return err;
164 size = ffio_read_size(s->pb, buffer, sizeof(buffer));
165 if (size < 0)
166 return size;
167
168 bytestream2_init(&gbc, buffer, sizeof(buffer));
169
170 au_size = bytestream2_get_be32(&gbc);
171 if (au_size < 24) {
172 // Too small.
173 return AVERROR_INVALIDDATA;
174 }
175 signature = bytestream2_get_be32(&gbc);
176 if (signature != APV_SIGNATURE) {
177 // Signature is mandatory.
178 return AVERROR_INVALIDDATA;
179 }
180 pbu_size = bytestream2_get_be32(&gbc);
181 if (pbu_size < 16) {
182 // Too small.
183 return AVERROR_INVALIDDATA;
184 }
185
187 if (!st)
188 return AVERROR(ENOMEM);
189
192
194 st->avg_frame_rate = apv->framerate;
195 avpriv_set_pts_info(st, 64, apv->framerate.den, apv->framerate.num);
196
197 avio_seek(s->pb, -size, SEEK_CUR);
198
199 return 0;
200}
201
203{
204 uint32_t au_size, signature;
205 int ret;
206
207 au_size = avio_rb32(s->pb);
208 if (au_size == 0 && avio_feof(s->pb))
209 return AVERROR_EOF;
210 if (au_size < 24 || au_size > 1 << 26) {
212 "APV AU has invalid size: %"PRIu32"\n", au_size);
213 return AVERROR_INVALIDDATA;
214 }
215
216 ret = av_get_packet(s->pb, pkt, au_size);
217 if (ret < 0)
218 return ret;
219 pkt->pos -= 4;
220 pkt->flags = AV_PKT_FLAG_KEY;
221
222 signature = AV_RB32(pkt->data);
223 if (signature != APV_SIGNATURE) {
224 av_log(s, AV_LOG_ERROR, "APV AU has invalid signature.\n");
225 return AVERROR_INVALIDDATA;
226 }
227
228 return 0;
229}
230
231#define OFFSET(x) offsetof(APVDemuxerContext, x)
232#define DEC AV_OPT_FLAG_DECODING_PARAM
233static const AVOption apv_options[] = {
234 { "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "30" }, 0, INT_MAX, DEC },
235 { NULL },
236};
237
239 .class_name = "apv demuxer",
240 .item_name = av_default_item_name,
241 .option = apv_options,
242 .version = LIBAVUTIL_VERSION_INT,
243};
244
246 .p.name = "apv",
247 .p.long_name = NULL_IF_CONFIG_SMALL("APV raw bitstream"),
248 .p.extensions = "apv",
250 .p.priv_class = &apv_demuxer_class,
251 .priv_data_size = sizeof(APVDemuxerContext),
255};
const FFInputFormat ff_apv_demuxer
Definition apvdec.c:245
static int apv_read_header(AVFormatContext *s)
Definition apvdec.c:152
static int apv_probe(const AVProbeData *p)
Definition apvdec.c:115
static int apv_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition apvdec.c:202
static const AVClass apv_demuxer_class
Definition apvdec.c:238
#define OFFSET(x)
Definition apvdec.c:231
static const AVOption apv_options[]
Definition apvdec.c:233
static int apv_extract_header_info(GetByteContext *gbc)
Definition apvdec.c:48
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 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
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition avformat.h:498
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:612
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
unsigned int avio_rb32(AVIOContext *s)
Definition aviobuf.c:764
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition aviobuf.c:1026
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL byte
Definition bytestream.h:99
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
#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
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
Definition opt.h:314
@ AV_CODEC_ID_APV
Definition codec_id.h:323
#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.
#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
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
#define AV_RB32(p)
static const char signature[]
Definition ipmovie.c:592
@ APV_PBU_ALPHA_FRAME
Definition apv.h:31
@ APV_PBU_PRIMARY_FRAME
Definition apv.h:27
@ APV_PBU_PREVIEW_FRAME
Definition apv.h:29
@ APV_PBU_NON_PRIMARY_FRAME
Definition apv.h:28
@ APV_PBU_ACCESS_UNIT_INFORMATION
Definition apv.h:32
#define APV_SIGNATURE
Definition apv.h:23
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
#define DEC
Definition librsvgdec.c:149
AVOptions.
static const uint8_t header[24]
Definition sdr2.c:68
AVRational framerate
AVRational describing framerate, set by a private option.
Definition apvdec.c:31
uint8_t band_idc
Definition apvdec.c:40
uint8_t pbu_type
Definition apvdec.c:35
int frame_width
Definition apvdec.c:42
uint8_t bit_depth_minus8
Definition apvdec.c:45
int frame_height
Definition apvdec.c:43
uint16_t group_id
Definition apvdec.c:36
uint8_t profile_idc
Definition apvdec.c:38
uint8_t level_idc
Definition apvdec.c:39
Describe the class of an AVClass context structure.
Definition log.h:76
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
AVOption.
Definition opt.h:428
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
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
enum AVStreamParseType need_parsing
Definition internal.h:321
#define av_log(a,...)
float framerate
Definition av1_levels.c:29
static char buffer[20]
Definition seek.c:32
int size