FFmpeg
libuavs3d.c
Go to the documentation of this file.
1 /*
2  * RAW AVS3-P2/IEEE1857.10 video demuxer
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/avassert.h"
25 #include "libavutil/avutil.h"
26 #include "libavutil/common.h"
27 #include "libavutil/imgutils.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/opt.h"
30 #include "avcodec.h"
31 #include "avs3.h"
32 #include "internal.h"
33 #include "uavs3d.h"
34 
35 typedef struct uavs3d_context {
37  void *dec_handle;
40  uavs3d_io_frm_t dec_frame;
42 
43 #define UAVS3D_CHECK_START_CODE(data_ptr, PIC_START_CODE) \
44  (AV_RL32(data_ptr) != (PIC_START_CODE << 24) + AVS3_NAL_START_CODE)
45 static int uavs3d_find_next_start_code(const unsigned char *bs_data, int bs_len, int *left)
46 {
47  const unsigned char *data_ptr = bs_data + 4;
48  int count = bs_len - 4;
49 
50  while (count >= 4 &&
56  data_ptr++;
57  count--;
58  }
59 
60  if (count >= 4) {
61  *left = count;
62  return 1;
63  }
64 
65  return 0;
66 }
67 
68 static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame) {
69  uavs3d_io_frm_t frm_out;
70  AVFrame *frm = (AVFrame *)dec_frame->priv;
71  int i;
72 
73  if (!frm || !frm->data[0]) {
74  dec_frame->got_pic = 0;
75  av_log(NULL, AV_LOG_ERROR, "Invalid AVFrame in uavs3d output.\n");
76  return;
77  }
78 
79  frm->pts = dec_frame->pts;
80  frm->pkt_dts = dec_frame->dts;
81  frm->pkt_pos = dec_frame->pkt_pos;
82  frm->pkt_size = dec_frame->pkt_size;
83  frm->coded_picture_number = dec_frame->dtr;
84  frm->display_picture_number = dec_frame->ptr;
85 
86  if (dec_frame->type < 0 || dec_frame->type >= 4) {
87  av_log(NULL, AV_LOG_WARNING, "Error frame type in uavs3d: %d.\n", dec_frame->type);
88  }
89 
90  frm->pict_type = ff_avs3_image_type[dec_frame->type];
91  frm->key_frame = (frm->pict_type == AV_PICTURE_TYPE_I);
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 
104 {
105  uavs3d_context *h = avctx->priv_data;
106  uavs3d_cfg_t cdsc;
107 
108  cdsc.frm_threads = avctx->thread_count > 0 ? avctx->thread_count : av_cpu_count();
109  cdsc.check_md5 = 0;
110  h->dec_handle = uavs3d_create(&cdsc, uavs3d_output_callback, NULL);
111  h->got_seqhdr = 0;
112 
113  if (!h->dec_handle) {
114  return AVERROR(ENOMEM);
115  }
116 
117  return 0;
118 }
119 
121 {
122  uavs3d_context *h = avctx->priv_data;
123 
124  if (h->dec_handle) {
125  uavs3d_flush(h->dec_handle, NULL);
126  uavs3d_delete(h->dec_handle);
127  h->dec_handle = NULL;
128  }
129  h->got_seqhdr = 0;
130 
131  return 0;
132 }
133 
135 {
136  uavs3d_context *h = avctx->priv_data;
137 
138  if (h->dec_handle) {
139  uavs3d_reset(h->dec_handle);
140  }
141 }
142 
143 #define UAVS3D_CHECK_INVALID_RANGE(v, l, r) ((v)<(l)||(v)>(r))
144 static int libuavs3d_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
145 {
146  uavs3d_context *h = avctx->priv_data;
147  const uint8_t *buf = avpkt->data;
148  int buf_size = avpkt->size;
149  const uint8_t *buf_end;
150  const uint8_t *buf_ptr;
151  AVFrame *frm = data;
152  int left_bytes;
153  int ret, finish = 0;
154 
155  *got_frame = 0;
156  frm->pts = -1;
158 
159  if (!buf_size) {
160  if (h->got_seqhdr) {
161  if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
162  return ret;
163  }
164  h->dec_frame.priv = data; // AVFrame
165  }
166  do {
167  ret = uavs3d_flush(h->dec_handle, &h->dec_frame);
168  } while (ret > 0 && !h->dec_frame.got_pic);
169  } else {
170  uavs3d_io_frm_t *frm_dec = &h->dec_frame;
171 
172  buf_ptr = buf;
173  buf_end = buf + buf_size;
174  frm_dec->pkt_pos = avpkt->pos;
175  frm_dec->pkt_size = avpkt->size;
176 
177  while (!finish) {
178  int bs_len;
179 
180  if (h->got_seqhdr) {
181  if (!frm->data[0] && (ret = ff_get_buffer(avctx, frm, 0)) < 0) {
182  return ret;
183  }
184  h->dec_frame.priv = data; // AVFrame
185  }
186 
187  if (uavs3d_find_next_start_code(buf_ptr, buf_end - buf_ptr, &left_bytes)) {
188  bs_len = buf_end - buf_ptr - left_bytes;
189  } else {
190  bs_len = buf_end - buf_ptr;
191  finish = 1;
192  }
193  frm_dec->bs = (unsigned char *)buf_ptr;
194  frm_dec->bs_len = bs_len;
195  frm_dec->pts = avpkt->pts;
196  frm_dec->dts = avpkt->dts;
197  uavs3d_decode(h->dec_handle, frm_dec);
198  buf_ptr += bs_len;
199 
200  if (frm_dec->nal_type == NAL_SEQ_HEADER) {
201  struct uavs3d_com_seqh_t *seqh = frm_dec->seqhdr;
202  if (UAVS3D_CHECK_INVALID_RANGE(seqh->frame_rate_code, 0, 15)) {
203  av_log(avctx, AV_LOG_ERROR, "Invalid frame rate code: %d.\n", seqh->frame_rate_code);
204  seqh->frame_rate_code = 3; // default 25 fps
205  } else {
206  avctx->framerate.num = ff_avs3_frame_rate_tab[seqh->frame_rate_code].num;
207  avctx->framerate.den = ff_avs3_frame_rate_tab[seqh->frame_rate_code].den;
208  }
209  avctx->has_b_frames = !seqh->low_delay;
210  avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE;
211  ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size);
212  h->got_seqhdr = 1;
213 
214  if (seqh->colour_description) {
215  if (UAVS3D_CHECK_INVALID_RANGE(seqh->colour_primaries, 0, 9) ||
216  UAVS3D_CHECK_INVALID_RANGE(seqh->transfer_characteristics, 0, 14) ||
217  UAVS3D_CHECK_INVALID_RANGE(seqh->matrix_coefficients, 0, 11)) {
218  av_log(avctx, AV_LOG_ERROR,
219  "Invalid colour description: primaries: %d"
220  "transfer characteristics: %d"
221  "matrix coefficients: %d.\n",
222  seqh->colour_primaries,
223  seqh->transfer_characteristics,
224  seqh->matrix_coefficients);
225  } else {
226  avctx->color_primaries = ff_avs3_color_primaries_tab[seqh->colour_primaries];
227  avctx->color_trc = ff_avs3_color_transfer_tab [seqh->transfer_characteristics];
228  avctx->colorspace = ff_avs3_color_matrix_tab [seqh->matrix_coefficients];
229  }
230  }
231  }
232  if (frm_dec->got_pic) {
233  break;
234  }
235  }
236  }
237 
238  *got_frame = h->dec_frame.got_pic;
239 
240  if (!(*got_frame)) {
241  av_frame_unref(frm);
242  }
243 
244  return buf_ptr - buf;
245 }
246 
248  .name = "libuavs3d",
249  .long_name = NULL_IF_CONFIG_SMALL("libuavs3d AVS3-P2/IEEE1857.10"),
250  .type = AVMEDIA_TYPE_VIDEO,
251  .id = AV_CODEC_ID_AVS3,
252  .priv_data_size = sizeof(uavs3d_context),
253  .init = libuavs3d_init,
254  .close = libuavs3d_end,
258  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
260  AV_PIX_FMT_NONE },
261  .wrapper_name = "libuavs3d",
262 };
#define AVS3_FIRST_SLICE_START_CODE
Definition: avs3.h:35
static const int ff_avs3_color_transfer_tab[15]
Definition: avs3.h:78
#define NULL
Definition: coverity.c:32
AVRational framerate
Definition: avcodec.h:2084
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
#define AVS3_SEQ_END_CODE
Definition: avs3.h:28
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void flush(AVCodecContext *avctx)
int av_cpu_count(void)
Definition: cpu.c:275
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:159
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:585
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:383
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:106
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static const AVRational ff_avs3_frame_rate_tab[16]
Definition: avs3.h:46
int num
Numerator.
Definition: rational.h:59
int size
Definition: packet.h:364
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
Convenience header that includes libavutil&#39;s core.
#define AV_CODEC_CAP_AUTO_THREADS
Codec supports avctx->thread_count == 0 (auto).
Definition: codec.h:118
AVCodec.
Definition: codec.h:190
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static const int ff_avs3_color_matrix_tab[12]
Definition: avs3.h:96
Undefined.
Definition: avutil.h:273
#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:75
static enum AVPictureType ff_avs3_image_type[4]
Definition: avs3.h:111
uint8_t
#define av_cold
Definition: attributes.h:88
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:407
static void finish(void)
Definition: movenc.c:345
uint8_t * data
Definition: packet.h:363
#define AVS3_INTRA_PIC_START_CODE
Definition: avs3.h:30
static int libuavs3d_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: libuavs3d.c:144
#define av_log(a,...)
AVCodec ff_libuavs3d_decoder
Definition: libuavs3d.c:247
static av_cold int libuavs3d_end(AVCodecContext *avctx)
Definition: libuavs3d.c:120
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:821
static int uavs3d_find_next_start_code(const unsigned char *bs_data, int bs_len, int *left)
Definition: libuavs3d.c:45
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: codec.h:197
GLsizei count
Definition: opengl_enc.c:108
static void libuavs3d_flush(AVCodecContext *avctx)
Definition: libuavs3d.c:134
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:397
int display_picture_number
picture number in display order
Definition: frame.h:432
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:1145
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
Definition: avcodec.h:1790
if(ret)
#define UAVS3D_CHECK_INVALID_RANGE(v, l, r)
Definition: libuavs3d.c:143
#define UAVS3D_CHECK_START_CODE(data_ptr, PIC_START_CODE)
Definition: libuavs3d.c:43
int coded_picture_number
picture number in bitstream order
Definition: frame.h:428
Libavcodec external API header.
void * dec_handle
Definition: libuavs3d.c:37
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
main external API structure.
Definition: avcodec.h:531
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1876
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2]...the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so...,+,-,+,-,+,+,-,+,-,+,...hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32-hcoeff[1]-hcoeff[2]-...a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2}an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||.........intra?||||:Block01:yes no||||:Block02:.................||||:Block03::y DC::ref index:||||:Block04::cb DC::motion x:||||.........:cr DC::motion y:||||.................|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------------------------------|||Y subbands||Cb subbands||Cr subbands||||------||------||------|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||------||------||------||||------||------||------|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||------||------||------||||------||------||------|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||------||------||------||||------||------||------|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------------------------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction------------|\Dequantization-------------------\||Reference frames|\IDWT|--------------|Motion\|||Frame 0||Frame 1||Compensation.OBMC v-------|--------------|--------------.\------> Frame n output Frame Frame<----------------------------------/|...|-------------------Range Coder:============Binary Range Coder:-------------------The implemented range coder is an adapted version based upon"Range encoding: an algorithm for removing redundancy from a digitised message."by G.N.N.Martin.The symbols encoded by the Snow range coder are bits(0|1).The associated probabilities are not fix but change depending on the symbol mix seen so far.bit seen|new state---------+-----------------------------------------------0|256-state_transition_table[256-old_state];1|state_transition_table[old_state];state_transition_table={0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:-------------------------FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1.the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:206
AVCodecContext * avctx
Definition: libuavs3d.c:36
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1159
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:1152
#define AVS3_SEQ_START_CODE
Definition: avs3.h:27
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
#define AVS3_INTER_PIC_START_CODE
Definition: avs3.h:33
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:423
int frame_threads
Definition: libuavs3d.c:38
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
static void uavs3d_output_callback(uavs3d_io_frm_t *dec_frame)
Definition: libuavs3d.c:68
common internal api header.
common internal and external API header
int den
Denominator.
Definition: rational.h:60
void * priv_data
Definition: avcodec.h:558
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:392
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: packet.h:362
static const int ff_avs3_color_primaries_tab[10]
Definition: avs3.h:65
static av_cold int libuavs3d_init(AVCodecContext *avctx)
Definition: libuavs3d.c:103
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
int pkt_size
size of the corresponding packet containing the compressed frame.
Definition: frame.h:629
uavs3d_io_frm_t dec_frame
Definition: libuavs3d.c:40
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: packet.h:340
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:356
int i
Definition: input.c:407