FFmpeg
Loading...
Searching...
No Matches
libuavs3d.c
Go to the documentation of this file.
1/*
2 * AVS3-P2/IEEE1857.10 video decoder (using the uavs3d library)
3 * Copyright (c) 2020 Zhenyu Wang <wangzhenyu@pkusz.edu.cn>
4 * Bingjie Han <hanbj@pkusz.edu.cn>
5 * Huiwen Ren <hwrenx@gmail.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 "libavutil/avutil.h"
25#include "libavutil/common.h"
26#include "libavutil/cpu.h"
27#include "libavutil/imgutils.h"
29#include "libavutil/opt.h"
30#include "avcodec.h"
31#include "avs3.h"
32#include "codec_internal.h"
33#include "decode.h"
34#include "uavs3d.h"
35
43
44#define UAVS3D_CHECK_START_CODE(data_ptr, PIC_START_CODE) \
45 (AV_RL32(data_ptr) != (PIC_START_CODE << 24) + AVS3_NAL_START_CODE)
46static int uavs3d_find_next_start_code(const unsigned char *bs_data, int bs_len, int *left)
47{
48 const unsigned char *data_ptr = bs_data + 4;
49 int count = bs_len - 4;
50
51 while (count >= 4 &&
57 data_ptr++;
58 count--;
59 }
60
61 if (count >= 4) {
62 *left = count;
63 return 1;
64 }
65
66 return 0;
67}
68
69static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame) {
70 uavs3d_io_frm_t frm_out;
71 AVFrame *frm = (AVFrame *)dec_frame->priv;
72 int i;
73
74 if (!frm || !frm->data[0]) {
75 dec_frame->got_pic = 0;
76 av_log(NULL, AV_LOG_ERROR, "Invalid AVFrame in uavs3d output.\n");
77 return;
78 }
79
80 frm->pts = dec_frame->pts;
81 frm->pkt_dts = dec_frame->dts;
82
83 if (dec_frame->type < 0 || dec_frame->type >= FF_ARRAY_ELEMS(ff_avs3_image_type)) {
84 av_log(NULL, AV_LOG_WARNING, "Error frame type in uavs3d: %d.\n", dec_frame->type);
85 } else {
86 frm->pict_type = ff_avs3_image_type[dec_frame->type];
87 if (frm->pict_type == AV_PICTURE_TYPE_I)
89 else
91 }
92
93 for (i = 0; i < 3; i++) {
94 frm_out.width [i] = dec_frame->width[i];
95 frm_out.height[i] = dec_frame->height[i];
96 frm_out.stride[i] = frm->linesize[i];
97 frm_out.buffer[i] = frm->data[i];
98 }
99
100 uavs3d_img_cpy_cvt(&frm_out, dec_frame, dec_frame->bit_depth);
101}
102
103#define UAVS3D_CHECK_INVALID_RANGE(v, l, r) ((v)<(l)||(v)>(r))
104
106{
107 uavs3d_context *h = avctx->priv_data;
108 uavs3d_io_frm_t *frm_dec = &h->dec_frame;
109 struct uavs3d_com_seqh_t *seqh = frm_dec->seqhdr;
110 int ret;
111
112 if (UAVS3D_CHECK_INVALID_RANGE(seqh->frame_rate_code, 0, 15)) {
113 av_log(avctx, AV_LOG_ERROR, "Invalid frame rate code: %d.\n", seqh->frame_rate_code);
114 seqh->frame_rate_code = 3; // default 25 fps
115 } else {
116 avctx->framerate.num = ff_avs3_frame_rate_tab[seqh->frame_rate_code].num;
117 avctx->framerate.den = ff_avs3_frame_rate_tab[seqh->frame_rate_code].den;
118 }
119 avctx->has_b_frames = seqh->output_reorder_delay;
120 avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10;
121 ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size);
122 if (ret < 0)
123 return ret;
124 h->got_seqhdr = 1;
125
126 if (seqh->colour_description) {
127 if (UAVS3D_CHECK_INVALID_RANGE(seqh->colour_primaries, 0, 9) ||
128 UAVS3D_CHECK_INVALID_RANGE(seqh->transfer_characteristics, 0, 14) ||
129 UAVS3D_CHECK_INVALID_RANGE(seqh->matrix_coefficients, 0, 11)) {
130 av_log(avctx, AV_LOG_ERROR,
131 "Invalid colour description: primaries: %d"
132 "transfer characteristics: %d"
133 "matrix coefficients: %d.\n",
134 seqh->colour_primaries,
135 seqh->transfer_characteristics,
136 seqh->matrix_coefficients);
137 } else {
138 avctx->color_primaries = ff_avs3_color_primaries_tab[seqh->colour_primaries];
139 avctx->color_trc = ff_avs3_color_transfer_tab [seqh->transfer_characteristics];
140 avctx->colorspace = ff_avs3_color_matrix_tab [seqh->matrix_coefficients];
141 }
142 }
143
144 return 0;
145}
146
148{
149 uavs3d_context *h = avctx->priv_data;
150 uint8_t *header = avctx->extradata;
151 int header_size = avctx->extradata_size;
152 uavs3d_io_frm_t *frm_dec = &h->dec_frame;
153
154 if (avctx->extradata_size < 4) {
155 av_log(avctx, AV_LOG_WARNING, "Invalid extradata size %d\n",
156 avctx->extradata_size);
157 return 0;
158 }
159
160 if (header[0] == 1) {
161 // Skip configurationVersion and sequence_header_length
162 header += 3;
163 // Also remove library_dependency_idc at the end
164 header_size -= 4;
165 }
166
167 frm_dec->nal_type = 0;
168 frm_dec->pkt_pos = 0;
169 frm_dec->pkt_size = header_size;
170 frm_dec->bs = header;
171 frm_dec->bs_len = header_size;
172 frm_dec->pts = 0;
173 frm_dec->dts = 0;
174 uavs3d_decode(h->dec_handle, frm_dec);
175 if (frm_dec->nal_type == NAL_SEQ_HEADER) {
176 int ret = libuavs3d_on_seq_header(avctx);
177 if (ret < 0)
178 av_log(avctx, AV_LOG_WARNING,
179 "Process sequence header failed, %s\n", av_err2str(ret));
180 } else {
181 av_log(avctx, AV_LOG_WARNING,
182 "Missing sequence header in extradata\n");
183 }
184
185 return 0;
186}
187
189{
190 uavs3d_context *h = avctx->priv_data;
191 uavs3d_cfg_t cdsc;
192
193 cdsc.frm_threads = avctx->thread_count > 0 ? avctx->thread_count : av_cpu_count();
194 cdsc.check_md5 = 0;
195 h->dec_handle = uavs3d_create(&cdsc, uavs3d_output_callback, NULL);
196 h->got_seqhdr = 0;
197
198 if (!h->dec_handle) {
199 return AVERROR(ENOMEM);
200 }
201
202 if (avctx->extradata)
203 return libuavs3d_decode_extradata(avctx);
204
205 return 0;
206}
207
209{
210 uavs3d_context *h = avctx->priv_data;
211
212 if (h->dec_handle) {
213 uavs3d_flush(h->dec_handle, NULL);
214 uavs3d_delete(h->dec_handle);
215 h->dec_handle = NULL;
216 }
217 h->got_seqhdr = 0;
218
219 return 0;
220}
221
222static void libuavs3d_flush(AVCodecContext * avctx)
223{
224 uavs3d_context *h = avctx->priv_data;
225
226 if (h->dec_handle) {
227 uavs3d_reset(h->dec_handle);
228 }
229}
230
232 int *got_frame, AVPacket *avpkt)
233{
234 uavs3d_context *h = avctx->priv_data;
235 const uint8_t *buf = avpkt->data;
236 int buf_size = avpkt->size;
237 const uint8_t *buf_end;
238 const uint8_t *buf_ptr = buf;
239 int left_bytes;
240 int ret, finish = 0;
241
242 *got_frame = 0;
243 frm->pts = -1;
245
246 if (!buf_size) {
247 if (h->got_seqhdr) {
248 if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
249 return ret;
250 }
251 h->dec_frame.priv = frm; // AVFrame
252 }
253 do {
254 ret = uavs3d_flush(h->dec_handle, &h->dec_frame);
255 } while (ret > 0 && !h->dec_frame.got_pic);
256 } else {
257 uavs3d_io_frm_t *frm_dec = &h->dec_frame;
258
259 buf_end = buf + buf_size;
260
261 while (!finish) {
262 int bs_len;
263
264 if (h->got_seqhdr) {
265 if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
266 return ret;
267 }
268 h->dec_frame.priv = frm; // AVFrame
269 }
270
271 if (uavs3d_find_next_start_code(buf_ptr, buf_end - buf_ptr, &left_bytes)) {
272 bs_len = buf_end - buf_ptr - left_bytes;
273 } else {
274 bs_len = buf_end - buf_ptr;
275 finish = 1;
276 }
277 frm_dec->bs = (unsigned char *)buf_ptr;
278 frm_dec->bs_len = bs_len;
279 frm_dec->pts = avpkt->pts;
280 frm_dec->dts = avpkt->dts;
281 uavs3d_decode(h->dec_handle, frm_dec);
282 buf_ptr += bs_len;
283
284 if (frm_dec->nal_type == NAL_SEQ_HEADER) {
285 ret = libuavs3d_on_seq_header(avctx);
286 if (ret < 0)
287 return ret;
288 }
289 if (frm_dec->got_pic) {
290 break;
291 }
292 }
293 }
294
295 *got_frame = h->dec_frame.got_pic;
296
297 if (!(*got_frame)) {
298 av_frame_unref(frm);
299 }
300
301 return buf_ptr - buf;
302}
303
305 .p.name = "libuavs3d",
306 CODEC_LONG_NAME("libuavs3d AVS3-P2/IEEE1857.10"),
307 .p.type = AVMEDIA_TYPE_VIDEO,
308 .p.id = AV_CODEC_ID_AVS3,
309 .priv_data_size = sizeof(uavs3d_context),
314 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
316 .flush = libuavs3d_flush,
317 .p.wrapper_name = "libuavs3d",
318};
const FFCodec ff_libuavs3d_decoder
Definition libuavs3d.c:304
static void finish(void)
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
static const AVRational ff_avs3_frame_rate_tab[16]
Definition avs3.h:46
#define AVS3_INTRA_PIC_START_CODE
Definition avs3.h:30
#define AVS3_FIRST_SLICE_START_CODE
Definition avs3.h:35
#define AVS3_SEQ_START_CODE
Definition avs3.h:27
#define AVS3_INTER_PIC_START_CODE
Definition avs3.h:33
static const int ff_avs3_color_primaries_tab[10]
Definition avs3.h:65
static const int ff_avs3_color_transfer_tab[15]
Definition avs3.h:78
static enum AVPictureType ff_avs3_image_type[4]
Definition avs3.h:111
static const int ff_avs3_color_matrix_tab[12]
Definition avs3.h:96
#define AVS3_SEQ_END_CODE
Definition avs3.h:28
Convenience header that includes libavutil's core.
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
common internal and external API header
#define NULL
Definition coverity.c:32
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition codec.h:112
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_AVS3
Definition codec_id.h:245
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_NONE
Undefined.
Definition avutil.h:277
misc image utilities
#define av_cold
Definition attributes.h:117
int av_cpu_count(void)
Definition cpu.c:228
static void libuavs3d_flush(AVCodecContext *avctx)
Definition libuavs3d.c:222
static av_cold int libuavs3d_init(AVCodecContext *avctx)
Definition libuavs3d.c:188
static av_cold int libuavs3d_end(AVCodecContext *avctx)
Definition libuavs3d.c:208
static int libuavs3d_on_seq_header(AVCodecContext *avctx)
Definition libuavs3d.c:105
static int libuavs3d_decode_extradata(AVCodecContext *avctx)
Definition libuavs3d.c:147
#define UAVS3D_CHECK_INVALID_RANGE(v, l, r)
Definition libuavs3d.c:103
#define UAVS3D_CHECK_START_CODE(data_ptr, PIC_START_CODE)
Definition libuavs3d.c:44
static int libuavs3d_decode_frame(AVCodecContext *avctx, AVFrame *frm, int *got_frame, AVPacket *avpkt)
Definition libuavs3d.c:231
static int uavs3d_find_next_start_code(const unsigned char *bs_data, int bs_len, int *left)
Definition libuavs3d.c:46
static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame)
Definition libuavs3d.c:69
AVOptions.
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
static const uint8_t header[24]
Definition sdr2.c:68
#define FF_ARRAY_ELEMS(a)
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
AVRational framerate
Definition avcodec.h:563
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition avcodec.h:709
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition frame.h:574
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition frame.h:581
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
enum AVPictureType pict_type
Picture type of the frame.
Definition frame.h:564
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition packet.h:602
uint8_t * data
Definition packet.h:603
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVCodecContext * avctx
Definition libuavs3d.c:37
uavs3d_io_frm_t dec_frame
Definition libuavs3d.c:41
void * dec_handle
Definition libuavs3d.c:38
#define av_log(a,...)