FFmpeg
evcdec.c
Go to the documentation of this file.
1 /*
2  * RAW EVC video demuxer
3  *
4  * Copyright (c) 2021 Dawid Kozinski <d.kozinski@samsung.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavcodec/evc.h"
24 #include "libavcodec/bsf.h"
25 
26 #include "libavutil/opt.h"
27 
28 #include "avformat.h"
29 #include "avio_internal.h"
30 #include "evc.h"
31 #include "internal.h"
32 
33 
34 #define RAW_PACKET_SIZE 1024
35 
36 typedef struct EVCDemuxContext {
37  const AVClass *class;
39 
41 
43 
44 #define DEC AV_OPT_FLAG_DECODING_PARAM
45 #define OFFSET(x) offsetof(EVCDemuxContext, x)
46 static const AVOption evc_options[] = {
47  { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
48  { NULL },
49 };
50 #undef OFFSET
51 
52 static const AVClass evc_demuxer_class = {
53  .class_name = "EVC Annex B demuxer",
54  .item_name = av_default_item_name,
55  .option = evc_options,
56  .version = LIBAVUTIL_VERSION_INT,
57 };
58 
59 static int annexb_probe(const AVProbeData *p)
60 {
61  int nalu_type;
62  size_t nalu_size;
63  int got_sps = 0, got_pps = 0, got_idr = 0, got_nonidr = 0;
64  const unsigned char *bits = p->buf;
65  int bytes_to_read = p->buf_size;
66 
67  while (bytes_to_read > EVC_NALU_LENGTH_PREFIX_SIZE) {
68 
70  if (nalu_size == 0) break;
71 
73  bytes_to_read -= EVC_NALU_LENGTH_PREFIX_SIZE;
74 
75  if(bytes_to_read < nalu_size) break;
76 
77  nalu_type = evc_get_nalu_type(bits, bytes_to_read);
78 
79  if (nalu_type == EVC_SPS_NUT)
80  got_sps++;
81  else if (nalu_type == EVC_PPS_NUT)
82  got_pps++;
83  else if (nalu_type == EVC_IDR_NUT )
84  got_idr++;
85  else if (nalu_type == EVC_NOIDR_NUT)
86  got_nonidr++;
87 
88  bits += nalu_size;
89  bytes_to_read -= nalu_size;
90  }
91 
92  if (got_sps && got_pps && (got_idr || got_nonidr > 3))
93  return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
94 
95  return 0;
96 }
97 
99 {
100  AVStream *st;
101  FFStream *sti;
102  const AVBitStreamFilter *filter = av_bsf_get_by_name("evc_frame_merge");
103  EVCDemuxContext *c = s->priv_data;
104  int ret = 0;
105 
106  st = avformat_new_stream(s, NULL);
107  if (!st) {
108  ret = AVERROR(ENOMEM);
109  goto fail;
110  }
111  sti = ffstream(st);
112 
115 
116  // This causes sending to the parser full frames, not chunks of data
117  // The flag PARSER_FLAG_COMPLETE_FRAMES will be set in demux.c (demux.c: 1316)
119 
120  st->avg_frame_rate = c->framerate;
121 
122  // taken from rawvideo demuxers
123  avpriv_set_pts_info(st, 64, 1, 1200000);
124 
125  ret = av_bsf_alloc(filter, &c->bsf);
126  if (ret < 0)
127  return ret;
128 
129  ret = avcodec_parameters_copy(c->bsf->par_in, st->codecpar);
130  if (ret < 0)
131  return ret;
132 
133  ret = av_bsf_init(c->bsf);
134  if (ret < 0)
135  return ret;
136 
137 fail:
138  return ret;
139 }
140 
142 {
143  int ret;
144  uint32_t nalu_size;
145  int au_end_found = 0;
146  EVCDemuxContext *const c = s->priv_data;
147 
148  while(!au_end_found) {
149  uint8_t buf[EVC_NALU_LENGTH_PREFIX_SIZE];
150 
151  if (avio_feof(s->pb))
152  goto end;
153 
155  if (ret < 0)
156  return ret;
157 
159  if (ret < 0)
160  return ret;
162  return AVERROR_INVALIDDATA;
163 
165  if (!nalu_size || nalu_size > INT_MAX)
166  return AVERROR_INVALIDDATA;
167 
168  avio_seek(s->pb, -EVC_NALU_LENGTH_PREFIX_SIZE, SEEK_CUR);
169 
170  ret = av_get_packet(s->pb, pkt, nalu_size + EVC_NALU_LENGTH_PREFIX_SIZE);
171  if (ret < 0)
172  return ret;
173  if (ret != (nalu_size + EVC_NALU_LENGTH_PREFIX_SIZE))
174  return AVERROR_INVALIDDATA;
175 
176 end:
177  ret = av_bsf_send_packet(c->bsf, pkt);
178  if (ret < 0) {
179  av_log(s, AV_LOG_ERROR, "Failed to send packet to "
180  "evc_frame_merge filter\n");
181  return ret;
182  }
183 
184  ret = av_bsf_receive_packet(c->bsf, pkt);
185  if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
186  av_log(s, AV_LOG_ERROR, "evc_frame_merge filter failed to "
187  "send output packet\n");
188 
189  if (ret != AVERROR(EAGAIN))
190  au_end_found = 1;
191  }
192 
193  return ret;
194 }
195 
197 {
198  EVCDemuxContext *const c = s->priv_data;
199 
200  av_bsf_free(&c->bsf);
201  return 0;
202 }
203 
205  .name = "evc",
206  .long_name = NULL_IF_CONFIG_SMALL("EVC Annex B"),
207  .read_probe = annexb_probe,
208  .read_header = evc_read_header, // annexb_read_header
209  .read_packet = evc_read_packet, // annexb_read_packet
210  .read_close = evc_read_close,
211  .extensions = "evc",
213  .flags_internal = FF_FMT_INIT_CLEANUP,
214  .raw_codec_id = AV_CODEC_ID_EVC,
215  .priv_data_size = sizeof(EVCDemuxContext),
216  .priv_class = &evc_demuxer_class,
217 };
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an AVInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:46
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
Definition: opt.h:238
AVFMT_NOTIMESTAMPS
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:480
AVOption
AVOption.
Definition: opt.h:251
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:930
evc_get_nalu_type
static int evc_get_nalu_type(const uint8_t *p, int bits_size)
Definition: evc.h:32
EVCDemuxContext::framerate
AVRational framerate
Definition: evcdec.c:38
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:455
av_bsf_free
void av_bsf_free(AVBSFContext **pctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition: bsf.c:52
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
evc_demuxer_class
static const AVClass evc_demuxer_class
Definition: evcdec.c:52
EVC_IDR_NUT
@ EVC_IDR_NUT
Definition: evc.h:35
EVC_NOIDR_NUT
@ EVC_NOIDR_NUT
Definition: evc.h:34
avpriv_set_pts_info
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:761
bsf.h
evc_options
static const AVOption evc_options[]
Definition: evcdec.c:46
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:420
fail
#define fail()
Definition: checkasm.h:138
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:481
annexb_probe
static int annexb_probe(const AVProbeData *p)
Definition: evcdec.c:59
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
evc_read_packet
static int evc_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: evcdec.c:141
AVInputFormat
Definition: avformat.h:549
evc_read_header
static int evc_read_header(AVFormatContext *s)
Definition: evcdec.c:98
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:324
DEC
#define DEC
Definition: evcdec.c:44
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:554
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:454
ff_evc_demuxer
const AVInputFormat ff_evc_demuxer
Definition: evcdec.c:204
bits
uint8_t bits
Definition: vp3data.h:128
av_bsf_alloc
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:104
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:391
AVFormatContext
Format I/O context.
Definition: avformat.h:1115
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:864
framerate
float framerate
Definition: av1_levels.c:29
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
av_bsf_init
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:149
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
OFFSET
#define OFFSET(x)
Definition: evcdec.c:45
av_bsf_receive_packet
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:230
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:452
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:462
evc_read_close
static int evc_read_close(AVFormatContext *s)
Definition: evcdec.c:196
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
FFStream
Definition: internal.h:199
av_bsf_send_packet
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:202
EVCDemuxContext
Definition: evcdec.c:36
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1071
EVC_NALU_LENGTH_PREFIX_SIZE
#define EVC_NALU_LENGTH_PREFIX_SIZE
Definition: evc.h:26
avio_internal.h
EVC_PPS_NUT
@ EVC_PPS_NUT
Definition: evc.h:59
av_get_packet
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:103
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:841
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:278
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:692
avformat.h
AVBitStreamFilter
Definition: bsf.h:111
evc_read_nal_unit_length
static uint32_t evc_read_nal_unit_length(const uint8_t *bits, int bits_size, void *logctx)
Definition: evc_parse.h:83
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:659
EVC_SPS_NUT
@ EVC_SPS_NUT
Definition: evc.h:58
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
EVCDemuxContext::bsf
AVBSFContext * bsf
Definition: evcdec.c:40
evc.h
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:468
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:393
av_bsf_get_by_name
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
Definition: bitstream_filters.c:86