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 "demux.h"
31 #include "evc.h"
32 #include "internal.h"
33 
34 
35 #define RAW_PACKET_SIZE 1024
36 
37 typedef struct EVCDemuxContext {
38  const AVClass *class;
40 
42 
44 
45 #define DEC AV_OPT_FLAG_DECODING_PARAM
46 #define OFFSET(x) offsetof(EVCDemuxContext, x)
47 static const AVOption evc_options[] = {
48  { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC},
49  { NULL },
50 };
51 #undef OFFSET
52 
53 static const AVClass evc_demuxer_class = {
54  .class_name = "EVC Annex B demuxer",
55  .item_name = av_default_item_name,
56  .option = evc_options,
57  .version = LIBAVUTIL_VERSION_INT,
58 };
59 
60 static int annexb_probe(const AVProbeData *p)
61 {
62  int nalu_type;
63  size_t nalu_size;
64  int got_sps = 0, got_pps = 0, got_idr = 0, got_nonidr = 0;
65  const unsigned char *bits = p->buf;
66  int bytes_to_read = p->buf_size;
67 
68  while (bytes_to_read > EVC_NALU_LENGTH_PREFIX_SIZE) {
69 
71  if (nalu_size == 0) break;
72 
74  bytes_to_read -= EVC_NALU_LENGTH_PREFIX_SIZE;
75 
76  if(bytes_to_read < nalu_size) break;
77 
78  nalu_type = evc_get_nalu_type(bits, bytes_to_read);
79 
80  if (nalu_type == EVC_SPS_NUT)
81  got_sps++;
82  else if (nalu_type == EVC_PPS_NUT)
83  got_pps++;
84  else if (nalu_type == EVC_IDR_NUT )
85  got_idr++;
86  else if (nalu_type == EVC_NOIDR_NUT)
87  got_nonidr++;
88 
89  bits += nalu_size;
90  bytes_to_read -= nalu_size;
91  }
92 
93  if (got_sps && got_pps && (got_idr || got_nonidr > 3))
94  return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
95 
96  return 0;
97 }
98 
100 {
101  AVStream *st;
102  FFStream *sti;
103  const AVBitStreamFilter *filter = av_bsf_get_by_name("evc_frame_merge");
104  EVCDemuxContext *c = s->priv_data;
105  int ret = 0;
106 
107  if (!filter)
108  return AVERROR_BUG;
109 
110  st = avformat_new_stream(s, NULL);
111  if (!st) {
112  ret = AVERROR(ENOMEM);
113  goto fail;
114  }
115  sti = ffstream(st);
116 
119 
120  // This causes sending to the parser full frames, not chunks of data
121  // The flag PARSER_FLAG_COMPLETE_FRAMES will be set in demux.c (demux.c: 1316)
123 
124  st->avg_frame_rate = c->framerate;
125 
126  // taken from rawvideo demuxers
127  avpriv_set_pts_info(st, 64, 1, 1200000);
128 
129  ret = av_bsf_alloc(filter, &c->bsf);
130  if (ret < 0)
131  return ret;
132 
133  ret = avcodec_parameters_copy(c->bsf->par_in, st->codecpar);
134  if (ret < 0)
135  return ret;
136 
137  ret = av_bsf_init(c->bsf);
138  if (ret < 0)
139  return ret;
140 
141 fail:
142  return ret;
143 }
144 
146 {
147  int ret;
148  uint32_t nalu_size;
149  int au_end_found = 0;
150  EVCDemuxContext *const c = s->priv_data;
151 
152  while(!au_end_found) {
153  uint8_t buf[EVC_NALU_LENGTH_PREFIX_SIZE];
154 
155  if (avio_feof(s->pb))
156  goto end;
157 
159  if (ret < 0)
160  return ret;
161 
163  if (ret < 0)
164  return ret;
166  return AVERROR_INVALIDDATA;
167 
169  if (!nalu_size || nalu_size > INT_MAX)
170  return AVERROR_INVALIDDATA;
171 
172  avio_seek(s->pb, -EVC_NALU_LENGTH_PREFIX_SIZE, SEEK_CUR);
173 
174  ret = av_get_packet(s->pb, pkt, nalu_size + EVC_NALU_LENGTH_PREFIX_SIZE);
175  if (ret < 0)
176  return ret;
177  if (ret != (nalu_size + EVC_NALU_LENGTH_PREFIX_SIZE))
178  return AVERROR_INVALIDDATA;
179 
180 end:
181  ret = av_bsf_send_packet(c->bsf, pkt);
182  if (ret < 0) {
183  av_log(s, AV_LOG_ERROR, "Failed to send packet to "
184  "evc_frame_merge filter\n");
185  return ret;
186  }
187 
188  ret = av_bsf_receive_packet(c->bsf, pkt);
189  if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
190  av_log(s, AV_LOG_ERROR, "evc_frame_merge filter failed to "
191  "send output packet\n");
192 
193  if (ret != AVERROR(EAGAIN))
194  au_end_found = 1;
195  }
196 
197  return ret;
198 }
199 
201 {
202  EVCDemuxContext *const c = s->priv_data;
203 
204  av_bsf_free(&c->bsf);
205  return 0;
206 }
207 
209  .p.name = "evc",
210  .p.long_name = NULL_IF_CONFIG_SMALL("EVC Annex B"),
211  .p.extensions = "evc",
213  .p.priv_class = &evc_demuxer_class,
214  .read_probe = annexb_probe,
215  .read_header = evc_read_header, // annexb_read_header
216  .read_packet = evc_read_packet, // annexb_read_packet
217  .read_close = evc_read_close,
218  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
219  .raw_codec_id = AV_CODEC_ID_EVC,
220  .priv_data_size = sizeof(EVCDemuxContext),
221 };
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
Underlying C type is AVRational.
Definition: opt.h:315
AVFMT_NOTIMESTAMPS
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:478
AVOption
AVOption.
Definition: opt.h:429
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
evc_get_nalu_type
static int evc_get_nalu_type(const uint8_t *p, int bits_size)
Definition: evc.h:32
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
EVCDemuxContext::framerate
AVRational framerate
Definition: evcdec.c:39
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
ff_evc_demuxer
const FFInputFormat ff_evc_demuxer
Definition: evcdec.c:208
AVBSFContext
The bitstream filter state.
Definition: bsf.h:68
evc_demuxer_class
static const AVClass evc_demuxer_class
Definition: evcdec.c:53
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:779
bsf.h
evc_options
static const AVOption evc_options[]
Definition: evcdec.c:47
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:362
fail
#define fail()
Definition: checkasm.h:216
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:479
annexb_probe
static int annexb_probe(const AVProbeData *p)
Definition: evcdec.c:60
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
evc_read_packet
static int evc_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: evcdec.c:145
evc_read_header
static int evc_read_header(AVFormatContext *s)
Definition: evcdec.c:99
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CODEC_ID_EVC
@ AV_CODEC_ID_EVC
Definition: codec_id.h:325
DEC
#define DEC
Definition: evcdec.c:45
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
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
FF_INFMT_FLAG_INIT_CLEANUP
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: demux.h:35
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
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:76
NULL
#define NULL
Definition: coverity.c:32
OFFSET
#define OFFSET(x)
Definition: evcdec.c:46
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:242
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
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:461
evc_read_close
static int evc_read_close(AVFormatContext *s)
Definition: evcdec.c:200
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:94
FFStream
Definition: internal.h:128
av_bsf_send_packet
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:202
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:51
EVCDemuxContext
Definition: evcdec.c:37
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:1026
EVC_NALU_LENGTH_PREFIX_SIZE
#define EVC_NALU_LENGTH_PREFIX_SIZE
Definition: evc.h:26
avio_internal.h
demux.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:98
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:236
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:81
AVSTREAM_PARSE_HEADERS
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition: avformat.h:590
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:615
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
EVC_SPS_NUT
@ EVC_SPS_NUT
Definition: evc.h:58
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
EVCDemuxContext::bsf
AVBSFContext * bsf
Definition: evcdec.c:41
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:565
FFInputFormat
Definition: demux.h:47
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
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:107
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:349
av_bsf_get_by_name
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
Definition: bitstream_filters.c:91