History

avcodec/evc_decoder: Provided support for EVC decoder

- Added EVC decoder wrapper - Changes in project configuration file and libavcodec Makefile - Added documentation for xevd wrapper

Dawid Kozinski committed 3 years ago

Commit cfe29471 parent c59a96f6 files · +579 −3Browse files

Unified · Split

6 files
  1. configure +4 −0
  2. doc/decoders.texi +24 −0
  3. doc/general_contents.texi +11 −3
  4. libavcodec/Makefile +1 −0
  5. libavcodec/allcodecs.c +1 −0
  6. libavcodec/libxevd.c +538 −0
configure+4−0
@@ -290,6 +290,7 @@ External library support: · 289 unmodified lines
290 --enable-libx264 enable H.264 encoding via x264 [no]290 --enable-libx264 enable H.264 encoding via x264 [no]
291 --enable-libx265 enable HEVC encoding via x265 [no]291 --enable-libx265 enable HEVC encoding via x265 [no]
292 --enable-libxeve enable EVC encoding via libxeve [no]292 --enable-libxeve enable EVC encoding via libxeve [no]
293 --enable-libxevd enable EVC decoding via libxevd [no]
293 --enable-libxavs enable AVS encoding via xavs [no]294 --enable-libxavs enable AVS encoding via xavs [no]
294 --enable-libxavs2 enable AVS2 encoding via xavs2 [no]295 --enable-libxavs2 enable AVS2 encoding via xavs2 [no]
295 --enable-libxcb enable X11 grabbing using XCB [autodetect]296 --enable-libxcb enable X11 grabbing using XCB [autodetect]
@@ -1902,6 +1903,7 @@ EXTERNAL_LIBRARY_LIST=" · 1606 unmodified lines
1902 libvorbis1903 libvorbis
1903 libvpx1904 libvpx
1904 libwebp1905 libwebp
1906 libxevd
1905 libxeve1907 libxeve
1906 libxml21908 libxml2
1907 libzimg1909 libzimg
@@ -3460,6 +3462,7 @@ libx265_encoder_deps="libx265" · 1552 unmodified lines
3460libx265_encoder_select="atsc_a53"3462libx265_encoder_select="atsc_a53"
3461libxavs_encoder_deps="libxavs"3463libxavs_encoder_deps="libxavs"
3462libxavs2_encoder_deps="libxavs2"3464libxavs2_encoder_deps="libxavs2"
3465libxevd_decoder_deps="libxevd"
3463libxeve_encoder_deps="libxeve"3466libxeve_encoder_deps="libxeve"
3464libxvid_encoder_deps="libxvid"3467libxvid_encoder_deps="libxvid"
3465libzvbi_teletext_decoder_deps="libzvbi"3468libzvbi_teletext_decoder_deps="libzvbi"
@@ -6875,6 +6878,7 @@ enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get · 3409 unmodified lines
6875 require_cpp_condition libx265 x265.h "X265_BUILD >= 89"6878 require_cpp_condition libx265 x265.h "X265_BUILD >= 89"
6876enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs"6879enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs"
6877enabled libxavs2 && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get6880enabled libxavs2 && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get
6881enabled libxevd && require_pkg_config libxevd "xevd >= 0.4.1" "xevd.h" xevd_decode
6878enabled libxeve && require_pkg_config libxeve "xeve >= 0.4.3" "xeve.h" xeve_encode6882enabled libxeve && require_pkg_config libxeve "xeve >= 0.4.3" "xeve.h" xeve_encode
6879enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore6883enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
6880enabled libzimg && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version6884enabled libzimg && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version
doc/decoders.texi+24−0
@@ -130,6 +130,30 @@ Set amount of frame threads to use during decoding. The default value is 0 (auto · 129 unmodified lines
130 130
131@end table131@end table
132 132
133@section libxevd
134
135eXtra-fast Essential Video Decoder (XEVD) MPEG-5 EVC decoder wrapper.
136
137This decoder requires the presence of the libxevd headers and library
138during configuration. You need to explicitly configure the build with
139@option{--enable-libxevd}.
140
141The xevd project website is at @url{https://github.com/mpeg5/xevd}.
142
143@subsection Options
144
145The following options are supported by the libxevd wrapper.
146The xevd-equivalent options or values are listed in parentheses for easy migration.
147
148To get a more accurate and extensive documentation of the libxevd options,
149invoke the command @code{xevd_app --help} or consult the libxevd documentation.
150
151@table @option
152@item threads (@emph{threads})
153Force to use a specific number of threads
154
155@end table
156
133@section QSV Decoders157@section QSV Decoders
134 158
135The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,159The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
doc/general_contents.texi+11−3
@@ -351,6 +351,14 @@ Go to @url{https://github.com/mpeg5/xeve} and follow the instructions for · 350 unmodified lines
351installing the XEVE library. Then pass @code{--enable-libxeve} to configure to351installing the XEVE library. Then pass @code{--enable-libxeve} to configure to
352enable it.352enable it.
353 353
354@section eXtra-fast Essential Video Decoder (XEVD)
355
356FFmpeg can make use of the XEVD library for EVC video decoding.
357
358Go to @url{https://github.com/mpeg5/xevd} and follow the instructions for
359installing the XEVD library. Then pass @code{--enable-libxevd} to configure to
360enable it.
361
354@section ZVBI362@section ZVBI
355 363
356ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB364ZVBI is a VBI decoding library which can be used by FFmpeg to decode DVB
@@ -606,7 +614,7 @@ library: · 249 unmodified lines
606@item raw DTS @tab X @tab X614@item raw DTS @tab X @tab X
607@item raw DTS-HD @tab @tab X615@item raw DTS-HD @tab @tab X
608@item raw E-AC-3 @tab X @tab X616@item raw E-AC-3 @tab X @tab X
609@item raw EVC @tab X @tab617@item raw EVC @tab X @tab X
610@item raw FLAC @tab X @tab X618@item raw FLAC @tab X @tab X
611@item raw GSM @tab @tab X619@item raw GSM @tab @tab X
612@item raw H.261 @tab X @tab X620@item raw H.261 @tab X @tab X
@@ -953,8 +961,8 @@ following image formats are supported: · 340 unmodified lines
953@item Electronic Arts TQI video @tab @tab X961@item Electronic Arts TQI video @tab @tab X
954@item Escape 124 @tab @tab X962@item Escape 124 @tab @tab X
955@item Escape 130 @tab @tab X963@item Escape 130 @tab @tab X
956@item EVC / MPEG-5 Part 1 @tab E @tab964@item EVC / MPEG-5 Part 1 @tab E @tab E
957 @tab encoding supported through external library libxeve965 @tab encoding and decoding supported through external libraries libxeve and libxevd
958@item FFmpeg video codec #1 @tab X @tab X966@item FFmpeg video codec #1 @tab X @tab X
959 @tab lossless codec (fourcc: FFV1)967 @tab lossless codec (fourcc: FFV1)
960@item Flash Screen Video v1 @tab X @tab X968@item Flash Screen Video v1 @tab X @tab X
libavcodec/Makefile+1−0
@@ -1149,6 +1149,7 @@ OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o · 1148 unmodified lines
1149OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o1149OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
1150OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o1150OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
1151OBJS-$(CONFIG_LIBXAVS2_ENCODER) += libxavs2.o1151OBJS-$(CONFIG_LIBXAVS2_ENCODER) += libxavs2.o
1152OBJS-$(CONFIG_LIBXEVD_DECODER) += libxevd.o
1152OBJS-$(CONFIG_LIBXEVE_ENCODER) += libxeve.o1153OBJS-$(CONFIG_LIBXEVE_ENCODER) += libxeve.o
1153OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o1154OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
1154OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o1155OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o
libavcodec/allcodecs.c+1−0
@@ -822,6 +822,7 @@ extern LIBX264_CONST FFCodec ff_libx264_encoder; · 821 unmodified lines
822extern const FFCodec ff_libx264rgb_encoder;822extern const FFCodec ff_libx264rgb_encoder;
823extern FFCodec ff_libx265_encoder;823extern FFCodec ff_libx265_encoder;
824extern const FFCodec ff_libxeve_encoder;824extern const FFCodec ff_libxeve_encoder;
825extern const FFCodec ff_libxevd_decoder;
825extern const FFCodec ff_libxavs_encoder;826extern const FFCodec ff_libxavs_encoder;
826extern const FFCodec ff_libxavs2_encoder;827extern const FFCodec ff_libxavs2_encoder;
827extern const FFCodec ff_libxvid_encoder;828extern const FFCodec ff_libxvid_encoder;
libavcodec/libxevd.c+538−0
@@ -0,0 +1,538 @@
1/*
2 * libxevd decoder
3 * EVC (MPEG-5 Essential Video Coding) decoding using XEVD MPEG-5 EVC decoder library
4 *
5 * Copyright (C) 2021 Dawid Kozinski <d.kozinski@samsung.com>
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <float.h>
25#include <stdlib.h>
26
27#include <xevd.h>
28
29#include "libavutil/internal.h"
30#include "libavutil/common.h"
31#include "libavutil/opt.h"
32#include "libavutil/pixdesc.h"
33#include "libavutil/pixfmt.h"
34#include "libavutil/imgutils.h"
35#include "libavutil/cpu.h"
36
37#include "avcodec.h"
38#include "internal.h"
39#include "packet_internal.h"
40#include "codec_internal.h"
41#include "profiles.h"
42#include "decode.h"
43
44#define XEVD_PARAM_BAD_NAME -1
45#define XEVD_PARAM_BAD_VALUE -2
46
47#define EVC_NAL_HEADER_SIZE 2 /* byte */
48
49/**
50 * The structure stores all the states associated with the instance of Xeve MPEG-5 EVC decoder
51 */
52typedef struct XevdContext {
53 const AVClass *class;
54
55 XEVD id; // XEVD instance identifier @see xevd.h
56 XEVD_CDSC cdsc; // decoding parameters @see xevd.h
57
58 // If end of stream occurs it is required "flushing" (aka draining) the codec,
59 // as the codec might buffer multiple frames or packets internally.
60 int draining_mode; // The flag is set if codec enters draining mode.
61
62 AVPacket *pkt; // access unit (a set of NAL units that are consecutive in decoding order and containing exactly one encoded image)
63} XevdContext;
64
65/**
66 * The function populates the XEVD_CDSC structure.
67 * XEVD_CDSC contains all decoder parameters that should be initialized before its use.
68 *
69 * @param[in] avctx codec context
70 * @param[out] cdsc contains all decoder parameters that should be initialized before its use
71 *
72 */
73static void get_conf(AVCodecContext *avctx, XEVD_CDSC *cdsc)
74{
75 int cpu_count = av_cpu_count();
76
77 /* clear XEVS_CDSC structure */
78 memset(cdsc, 0, sizeof(XEVD_CDSC));
79
80 /* init XEVD_CDSC */
81 if (avctx->thread_count <= 0)
82 cdsc->threads = (cpu_count < XEVD_MAX_TASK_CNT) ? cpu_count : XEVD_MAX_TASK_CNT;
83 else if (avctx->thread_count > XEVD_MAX_TASK_CNT)
84 cdsc->threads = XEVD_MAX_TASK_CNT;
85 else
86 cdsc->threads = avctx->thread_count;
87}
88
89/**
90 * Read NAL unit length
91 * @param bs input data (bitstream)
92 * @return the length of NAL unit on success, 0 value on failure
93 */
94static uint32_t read_nal_unit_length(const uint8_t *bs, int bs_size, AVCodecContext *avctx)
95{
96 uint32_t len = 0;
97 XEVD_INFO info;
98 int ret;
99
100 if (bs_size == XEVD_NAL_UNIT_LENGTH_BYTE) {
101 ret = xevd_info((void *)bs, XEVD_NAL_UNIT_LENGTH_BYTE, 1, &info);
102 if (XEVD_FAILED(ret)) {
103 av_log(avctx, AV_LOG_ERROR, "Cannot get bitstream information\n");
104 return 0;
105 }
106 len = info.nalu_len;
107 if (len == 0) {
108 av_log(avctx, AV_LOG_ERROR, "Invalid bitstream size! [%d]\n", bs_size);
109 return 0;
110 }
111 }
112
113 return len;
114}
115
116/**
117 * @param[in] xectx the structure that stores all the state associated with the instance of Xeve MPEG-5 EVC decoder
118 * @param[out] avctx codec context
119 * @return 0 on success, negative value on failure
120 */
121static int export_stream_params(const XevdContext *xectx, AVCodecContext *avctx)
122{
123 int ret;
124 int size;
125 int color_space;
126
127 avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
128
129 size = 4;
130 ret = xevd_config(xectx->id, XEVD_CFG_GET_CODED_WIDTH, &avctx->coded_width, &size);
131 if (XEVD_FAILED(ret)) {
132 av_log(avctx, AV_LOG_ERROR, "Failed to get coded_width\n");
133 return AVERROR_EXTERNAL;
134 }
135
136 ret = xevd_config(xectx->id, XEVD_CFG_GET_CODED_HEIGHT, &avctx->coded_height, &size);
137 if (XEVD_FAILED(ret)) {
138 av_log(avctx, AV_LOG_ERROR, "Failed to get coded_height\n");
139 return AVERROR_EXTERNAL;
140 }
141
142 ret = xevd_config(xectx->id, XEVD_CFG_GET_WIDTH, &avctx->width, &size);
143 if (XEVD_FAILED(ret)) {
144 av_log(avctx, AV_LOG_ERROR, "Failed to get width\n");
145 return AVERROR_EXTERNAL;
146 }
147
148 ret = xevd_config(xectx->id, XEVD_CFG_GET_HEIGHT, &avctx->height, &size);
149 if (XEVD_FAILED(ret)) {
150 av_log(avctx, AV_LOG_ERROR, "Failed to get height\n");
151 return AVERROR_EXTERNAL;
152 }
153
154 ret = xevd_config(xectx->id, XEVD_CFG_GET_COLOR_SPACE, &color_space, &size);
155 if (XEVD_FAILED(ret)) {
156 av_log(avctx, AV_LOG_ERROR, "Failed to get color_space\n");
157 return AVERROR_EXTERNAL;
158 }
159 switch(color_space) {
160 case XEVD_CS_YCBCR400_10LE:
161 avctx->pix_fmt = AV_PIX_FMT_GRAY10LE;
162 break;
163 case XEVD_CS_YCBCR420_10LE:
164 avctx->pix_fmt = AV_PIX_FMT_YUV420P10LE;
165 break;
166 case XEVD_CS_YCBCR422_10LE:
167 avctx->pix_fmt = AV_PIX_FMT_YUV422P10LE;
168 break;
169 case XEVD_CS_YCBCR444_10LE:
170 avctx->pix_fmt = AV_PIX_FMT_YUV444P10LE;
171 break;
172 default:
173 av_log(avctx, AV_LOG_ERROR, "Unknown color space\n");
174 avctx->pix_fmt = AV_PIX_FMT_NONE;
175 return AVERROR_INVALIDDATA;
176 }
177
178 // the function returns sps->num_reorder_pics
179 ret = xevd_config(xectx->id, XEVD_CFG_GET_MAX_CODING_DELAY, &avctx->max_b_frames, &size);
180 if (XEVD_FAILED(ret)) {
181 av_log(avctx, AV_LOG_ERROR, "Failed to get max_coding_delay\n");
182 return AVERROR_EXTERNAL;
183 }
184
185 avctx->has_b_frames = (avctx->max_b_frames) ? 1 : 0;
186
187 return 0;
188}
189
190/**
191 * @brief Copy image in imgb to frame.
192 *
193 * @param avctx codec context
194 * @param[in] imgb
195 * @param[out] frame
196 * @return 0 on success, negative value on failure
197 */
198static int libxevd_image_copy(struct AVCodecContext *avctx, XEVD_IMGB *imgb, struct AVFrame *frame)
199{
200 int ret;
201 if (imgb->cs != XEVD_CS_YCBCR420_10LE) {
202 av_log(avctx, AV_LOG_ERROR, "Not supported pixel format: %s\n", av_get_pix_fmt_name(avctx->pix_fmt));
203 return AVERROR_INVALIDDATA;
204 }
205
206 if (imgb->w[0] != avctx->width || imgb->h[0] != avctx->height) { // stream resolution changed
207 if (ff_set_dimensions(avctx, imgb->w[0], imgb->h[0]) < 0) {
208 av_log(avctx, AV_LOG_ERROR, "Cannot set new dimension\n");
209 return AVERROR_INVALIDDATA;
210 }
211 }
212
213 if (ret = ff_get_buffer(avctx, frame, 0) < 0)
214 return ret;
215
216 av_image_copy(frame->data, frame->linesize, (const uint8_t **)imgb->a,
217 imgb->s, avctx->pix_fmt,
218 imgb->w[0], imgb->h[0]);
219
220 return 0;
221}
222
223/**
224 * Initialize decoder
225 * Create a decoder instance and allocate all the needed resources
226 *
227 * @param avctx codec context
228 * @return 0 on success, negative error code on failure
229 */
230static av_cold int libxevd_init(AVCodecContext *avctx)
231{
232 XevdContext *xectx = avctx->priv_data;
233 XEVD_CDSC *cdsc = &(xectx->cdsc);
234
235 /* read configurations and set values for created descriptor (XEVD_CDSC) */
236 get_conf(avctx, cdsc);
237
238 /* create decoder */
239 xectx->id = xevd_create(&(xectx->cdsc), NULL);
240 if (xectx->id == NULL) {
241 av_log(avctx, AV_LOG_ERROR, "Cannot create XEVD encoder\n");
242 return AVERROR_EXTERNAL;
243 }
244
245 xectx->draining_mode = 0;
246 xectx->pkt = av_packet_alloc();
247 if (!xectx->pkt) {
248 av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory for AVPacket\n");
249 return AVERROR(ENOMEM);
250 }
251
252 return 0;
253}
254
255/**
256 * Decode frame with decoupled packet/frame dataflow
257 *
258 * @param avctx codec context
259 * @param[out] frame decoded frame
260 *
261 * @return 0 on success, negative error code on failure
262 */
263static int libxevd_receive_frame(AVCodecContext *avctx, AVFrame *frame)
264{
265 XevdContext *xectx = avctx->priv_data;
266 AVPacket *pkt = xectx->pkt;
267 XEVD_IMGB *imgb = NULL;
268
269 int xevd_ret = 0;
270 int ret = 0;
271
272 // obtain access unit (input data) - a set of NAL units that are consecutive in decoding order and containing exactly one encoded image
273 ret = ff_decode_get_packet(avctx, pkt);
274 if (ret < 0 && ret != AVERROR_EOF) {
275 av_packet_unref(pkt);
276
277 return ret;
278 } else if(ret == AVERROR_EOF && xectx->draining_mode == 0) { // End of stream situations. Enter draining mode
279
280 xectx->draining_mode = 1;
281 av_packet_unref(pkt);
282 }
283
284 if (pkt->size > 0) {
285 int bs_read_pos = 0;
286 XEVD_STAT stat;
287 XEVD_BITB bitb;
288 int nalu_size;
289 AVPacket* pkt_au;
290 imgb = NULL;
291
292 pkt_au = av_packet_clone(pkt);
293 if (!pkt_au) {
294 av_log(avctx, AV_LOG_ERROR, "Cannot clone AVPacket\n");
295 av_packet_unref(pkt);
296 return AVERROR(ENOMEM);
297 }
298
299 av_packet_unref(pkt);
300
301 // get all nal units from AU
302 while(pkt_au->size > (bs_read_pos + XEVD_NAL_UNIT_LENGTH_BYTE)) {
303 memset(&stat, 0, sizeof(XEVD_STAT));
304
305 nalu_size = read_nal_unit_length(pkt_au->data + bs_read_pos, XEVD_NAL_UNIT_LENGTH_BYTE, avctx);
306 if (nalu_size == 0) {
307 av_log(avctx, AV_LOG_ERROR, "Invalid bitstream\n");
308 av_packet_free(&pkt_au);
309 ret = AVERROR_INVALIDDATA;
310
311 return ret;
312 }
313 bs_read_pos += XEVD_NAL_UNIT_LENGTH_BYTE;
314
315 bitb.addr = pkt_au->data + bs_read_pos;
316 bitb.ssize = nalu_size;
317 bitb.pdata[0] = pkt_au;
318 bitb.ts[XEVD_TS_DTS] = pkt_au->dts;
319
320 /* main decoding block */
321 xevd_ret = xevd_decode(xectx->id, &bitb, &stat);
322 if (XEVD_FAILED(xevd_ret)) {
323 av_log(avctx, AV_LOG_ERROR, "Failed to decode bitstream\n");
324 av_packet_free(&pkt_au);
325
326 return AVERROR_EXTERNAL;
327 }
328
329 bs_read_pos += nalu_size;
330
331 if (stat.nalu_type == XEVD_NUT_SPS) { // EVC stream parameters changed
332 if ((ret = export_stream_params(xectx, avctx)) != 0) {
333 av_log(avctx, AV_LOG_ERROR, "Failed to export stream params\n");
334 av_packet_free(&pkt_au);
335
336 return ret;
337 }
338 }
339
340 if (stat.read != nalu_size)
341 av_log(avctx, AV_LOG_INFO, "Different reading of bitstream (in:%d, read:%d)\n,", nalu_size, stat.read);
342
343 // stat.fnum - has negative value if the decoded data is not frame
344 if (stat.fnum >= 0) {
345
346 xevd_ret = xevd_pull(xectx->id, &imgb); // The function returns a valid image only if the return code is XEVD_OK
347
348 if (XEVD_FAILED(xevd_ret)) {
349 av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded image (xevd error code: %d, frame#=%d)\n", xevd_ret, stat.fnum);
350
351 av_packet_free(&pkt_au);
352
353 return AVERROR_EXTERNAL;
354 } else if (xevd_ret == XEVD_OK_FRM_DELAYED) {
355 if(bs_read_pos == pkt_au->size) {
356 return AVERROR(EAGAIN);
357 }
358 } else { // XEVD_OK
359 if (!imgb) {
360 if(bs_read_pos == pkt_au->size) {
361 av_log(avctx, AV_LOG_ERROR, "Invalid decoded image data\n");
362
363 av_packet_free(&pkt_au);
364 return AVERROR(EAGAIN);
365 }
366 } else {
367 // got frame
368 AVPacket* pkt_au_imgb = (AVPacket*)imgb->pdata[0];
369 if(!pkt_au_imgb) {
370 av_log(avctx, AV_LOG_ERROR, "Invalid data needed to fill frame properties\n");
371
372 av_packet_free(&pkt_au);
373 av_frame_unref(frame);
374
375 imgb->release(imgb);
376 imgb = NULL;
377
378 return AVERROR_INVALIDDATA;
379 }
380
381 ret = libxevd_image_copy(avctx, imgb, frame);
382 if(ret < 0) {
383 av_log(avctx, AV_LOG_ERROR, "Image copying error\n");
384
385 av_packet_free(&pkt_au_imgb);
386 av_frame_unref(frame);
387
388 imgb->release(imgb);
389 imgb = NULL;
390
391 return ret;
392 }
393
394 // use ff_decode_frame_props_from_pkt() to fill frame properties
395 ret = ff_decode_frame_props_from_pkt(avctx, frame, pkt_au_imgb);
396 if (ret < 0) {
397 av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props_from_pkt error\n");
398
399 av_packet_free(&pkt_au_imgb);
400 av_frame_unref(frame);
401
402 imgb->release(imgb);
403 imgb = NULL;
404
405 return ret;
406 }
407
408 frame->pkt_dts = imgb->ts[XEVD_TS_DTS];
409 frame->pts = imgb->ts[XEVD_TS_PTS];
410
411 av_packet_free(&pkt_au_imgb);
412
413 // xevd_pull uses pool of objects of type XEVD_IMGB.
414 // The pool size is equal MAX_PB_SIZE (26), so release object when it is no more needed
415 imgb->release(imgb);
416 imgb = NULL;
417 }
418 }
419 }
420 }
421 } else { // decoder draining mode handling
422
423 xevd_ret = xevd_pull(xectx->id, &imgb);
424
425 if (xevd_ret == XEVD_ERR_UNEXPECTED) { // draining process completed
426 av_log(avctx, AV_LOG_DEBUG, "Draining process completed\n");
427
428 return AVERROR_EOF;
429 } else if (XEVD_FAILED(xevd_ret)) { // handle all other errors
430 av_log(avctx, AV_LOG_ERROR, "Failed to pull the decoded image (xevd error code: %d)\n", xevd_ret);
431
432 return AVERROR_EXTERNAL;
433 } else { // XEVD_OK
434 AVPacket* pkt_au_imgb;
435 if (!imgb) {
436 av_log(avctx, AV_LOG_ERROR, "Invalid decoded image data\n");
437
438 return AVERROR_EXTERNAL;
439 }
440
441 pkt_au_imgb = (AVPacket*)imgb->pdata[0];
442 if(!pkt_au_imgb) {
443 av_log(avctx, AV_LOG_ERROR, "Invalid data needed to fill frame properties\n");
444
445 imgb->release(imgb);
446 imgb = NULL;
447
448 av_frame_unref(frame);
449
450 return AVERROR_INVALIDDATA;
451 }
452
453 // got frame
454 ret = libxevd_image_copy(avctx, imgb, frame);
455 if(ret < 0) {
456 av_packet_free(&pkt_au_imgb);
457 av_frame_unref(frame);
458
459 imgb->release(imgb);
460 imgb = NULL;
461
462 return ret;
463 }
464 // use ff_decode_frame_props_from_pkt() to fill frame properties
465 ret = ff_decode_frame_props_from_pkt(avctx, frame, pkt_au_imgb);
466 if (ret < 0) {
467 av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props_from_pkt error\n");
468
469 av_packet_free(&pkt_au_imgb);
470 av_frame_unref(frame);
471
472 imgb->release(imgb);
473 imgb = NULL;
474
475 return ret;
476 }
477
478 frame->pkt_dts = imgb->ts[XEVD_TS_DTS];
479 frame->pts = imgb->ts[XEVD_TS_PTS];
480
481 av_packet_free(&pkt_au_imgb);
482
483 // xevd_pull uses pool of objects of type XEVD_IMGB.
484 // The pool size is equal MAX_PB_SIZE (26), so release object when it is no more needed
485 imgb->release(imgb);
486 imgb = NULL;
487
488 return 0;
489 }
490 }
491
492 return ret;
493}
494
495/**
496 * Destroy decoder
497 *
498 * @param avctx codec context
499 * @return 0 on success
500 */
501static av_cold int libxevd_close(AVCodecContext *avctx)
502{
503 XevdContext *xectx = avctx->priv_data;
504 if (xectx->id) {
505 xevd_delete(xectx->id);
506 xectx->id = NULL;
507 }
508
509 xectx->draining_mode = 0;
510 av_packet_free(&xectx->pkt);
511
512 return 0;
513}
514
515#define OFFSET(x) offsetof(XevdContext, x)
516#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
517
518static const AVClass libxevd_class = {
519 .class_name = "libxevd",
520 .item_name = av_default_item_name,
521 .version = LIBAVUTIL_VERSION_INT,
522};
523
524const FFCodec ff_libxevd_decoder = {
525 .p.name = "evc",
526 .p.long_name = NULL_IF_CONFIG_SMALL("EVC / MPEG-5 Essential Video Coding (EVC)"),
527 .p.type = AVMEDIA_TYPE_VIDEO,
528 .p.id = AV_CODEC_ID_EVC,
529 .init = libxevd_init,
530 FF_CODEC_RECEIVE_FRAME_CB(libxevd_receive_frame),
531 .close = libxevd_close,
532 .priv_data_size = sizeof(XevdContext),
533 .p.priv_class = &libxevd_class,
534 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_CAP_AVOID_PROBING,
535 .p.profiles = NULL_IF_CONFIG_SMALL(ff_evc_profiles),
536 .p.wrapper_name = "libxevd",
537 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_NOT_INIT_THREADSAFE | FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_SETS_FRAME_PROPS
538};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t