FFmpeg
escape130.c
Go to the documentation of this file.
1 /*
2  * Escape 130 video decoder
3  * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/attributes.h"
23 #include "libavutil/mem.h"
24 
25 #define BITSTREAM_READER_LE
26 #include "avcodec.h"
27 #include "codec_internal.h"
28 #include "decode.h"
29 #include "get_bits.h"
30 
31 typedef struct Escape130Context {
32  uint8_t *old_y_avg;
33 
34  uint8_t *new_y, *old_y;
35  uint8_t *new_u, *old_u;
36  uint8_t *new_v, *old_v;
37 
38  uint8_t *buf1, *buf2;
39  int linesize[3];
41 
42 static const uint8_t offset_table[] = { 2, 4, 10, 20 };
43 static const int8_t sign_table[64][4] = {
44  { 0, 0, 0, 0 },
45  { -1, 1, 0, 0 },
46  { 1, -1, 0, 0 },
47  { -1, 0, 1, 0 },
48  { -1, 1, 1, 0 },
49  { 0, -1, 1, 0 },
50  { 1, -1, 1, 0 },
51  { -1, -1, 1, 0 },
52  { 1, 0, -1, 0 },
53  { 0, 1, -1, 0 },
54  { 1, 1, -1, 0 },
55  { -1, 1, -1, 0 },
56  { 1, -1, -1, 0 },
57  { -1, 0, 0, 1 },
58  { -1, 1, 0, 1 },
59  { 0, -1, 0, 1 },
60 
61  { 0, 0, 0, 0 },
62  { 1, -1, 0, 1 },
63  { -1, -1, 0, 1 },
64  { -1, 0, 1, 1 },
65  { -1, 1, 1, 1 },
66  { 0, -1, 1, 1 },
67  { 1, -1, 1, 1 },
68  { -1, -1, 1, 1 },
69  { 0, 0, -1, 1 },
70  { 1, 0, -1, 1 },
71  { -1, 0, -1, 1 },
72  { 0, 1, -1, 1 },
73  { 1, 1, -1, 1 },
74  { -1, 1, -1, 1 },
75  { 0, -1, -1, 1 },
76  { 1, -1, -1, 1 },
77 
78  { 0, 0, 0, 0 },
79  { -1, -1, -1, 1 },
80  { 1, 0, 0, -1 },
81  { 0, 1, 0, -1 },
82  { 1, 1, 0, -1 },
83  { -1, 1, 0, -1 },
84  { 1, -1, 0, -1 },
85  { 0, 0, 1, -1 },
86  { 1, 0, 1, -1 },
87  { -1, 0, 1, -1 },
88  { 0, 1, 1, -1 },
89  { 1, 1, 1, -1 },
90  { -1, 1, 1, -1 },
91  { 0, -1, 1, -1 },
92  { 1, -1, 1, -1 },
93  { -1, -1, 1, -1 },
94 
95  { 0, 0, 0, 0 },
96  { 1, 0, -1, -1 },
97  { 0, 1, -1, -1 },
98  { 1, 1, -1, -1 },
99  { -1, 1, -1, -1 },
100  { 1, -1, -1, -1 }
101 };
102 
103 static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
104 
105 static const int8_t chroma_adjust[2][8] = {
106  { 1, 1, 0, -1, -1, -1, 0, 1 },
107  { 0, 1, 1, 1, 0, -1, -1, -1 }
108 };
109 
110 static const uint8_t chroma_vals[] = {
111  20, 28, 36, 44, 52, 60, 68, 76,
112  84, 92, 100, 106, 112, 116, 120, 124,
113  128, 132, 136, 140, 144, 150, 156, 164,
114  172, 180, 188, 196, 204, 212, 220, 228
115 };
116 
118 {
119  Escape130Context *s = avctx->priv_data;
120  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
121 
122  if ((avctx->width & 1) || (avctx->height & 1)) {
123  av_log(avctx, AV_LOG_ERROR,
124  "Dimensions should be a multiple of two.\n");
125  return AVERROR_INVALIDDATA;
126  }
127 
128  s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
129  s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2);
130  s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2);
131  if (!s->old_y_avg || !s->buf1 || !s->buf2) {
132  av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
133  return AVERROR(ENOMEM);
134  }
135 
136  s->linesize[0] = avctx->width;
137  s->linesize[1] =
138  s->linesize[2] = avctx->width / 2;
139 
140  s->new_y = s->buf1;
141  s->new_u = s->new_y + avctx->width * avctx->height;
142  s->new_v = s->new_u + avctx->width * avctx->height / 4;
143  s->old_y = s->buf2;
144  s->old_u = s->old_y + avctx->width * avctx->height;
145  s->old_v = s->old_u + avctx->width * avctx->height / 4;
146  memset(s->old_y, 0, avctx->width * avctx->height);
147  memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
148  memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
149 
150  return 0;
151 }
152 
154 {
155  Escape130Context *s = avctx->priv_data;
156 
157  av_freep(&s->old_y_avg);
158  av_freep(&s->buf1);
159  av_freep(&s->buf2);
160 
161  return 0;
162 }
163 
165 {
166  int value;
167 
168  if (get_bits_left(gb) < 1+3)
169  return -1;
170 
171  value = get_bits1(gb);
172  if (value)
173  return 0;
174 
175  value = get_bits(gb, 3);
176  if (value)
177  return value;
178 
179  value = get_bits(gb, 8);
180  if (value)
181  return value + 7;
182 
183  value = get_bits(gb, 15);
184  if (value)
185  return value + 262;
186 
187  return -1;
188 }
189 
191  int *got_frame, AVPacket *avpkt)
192 {
193  int buf_size = avpkt->size;
194  Escape130Context *s = avctx->priv_data;
195  GetBitContext gb;
196  int ret;
197 
198  uint8_t *old_y, *old_cb, *old_cr,
199  *new_y, *new_cb, *new_cr;
200  uint8_t *dstY, *dstU, *dstV;
201  unsigned old_y_stride, old_cb_stride, old_cr_stride,
202  new_y_stride, new_cb_stride, new_cr_stride;
203  unsigned total_blocks = avctx->width * avctx->height / 4,
204  block_index, block_x = 0;
205  unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
206  int skip = -1, y_avg = 0, i, j;
207  uint8_t *ya = s->old_y_avg;
208 
209  // first 16 bytes are header; no useful information in here
210  if (buf_size <= 16) {
211  av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
212  return AVERROR_INVALIDDATA;
213  }
214 
215  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
216  return ret;
217 
218  if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
219  return ret;
220  skip_bits_long(&gb, 16 * 8);
221 
222  new_y = s->new_y;
223  new_cb = s->new_u;
224  new_cr = s->new_v;
225  new_y_stride = s->linesize[0];
226  new_cb_stride = s->linesize[1];
227  new_cr_stride = s->linesize[2];
228  old_y = s->old_y;
229  old_cb = s->old_u;
230  old_cr = s->old_v;
231  old_y_stride = s->linesize[0];
232  old_cb_stride = s->linesize[1];
233  old_cr_stride = s->linesize[2];
234 
235  for (block_index = 0; block_index < total_blocks; block_index++) {
236  // Note that this call will make us skip the rest of the blocks
237  // if the frame ends prematurely.
238  if (skip == -1)
239  skip = decode_skip_count(&gb);
240  if (skip == -1) {
241  av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
242  return AVERROR_INVALIDDATA;
243  }
244 
245  if (skip) {
246  y[0] = old_y[0];
247  y[1] = old_y[1];
248  y[2] = old_y[old_y_stride];
249  y[3] = old_y[old_y_stride + 1];
250  y_avg = ya[0];
251  cb = old_cb[0];
252  cr = old_cr[0];
253  } else {
254  if (get_bits1(&gb)) {
255  unsigned sign_selector = get_bits(&gb, 6);
256  unsigned difference_selector = get_bits(&gb, 2);
257  y_avg = 2 * get_bits(&gb, 5);
258  for (i = 0; i < 4; i++) {
259  y[i] = av_clip(y_avg + offset_table[difference_selector] *
260  sign_table[sign_selector][i], 0, 63);
261  }
262  } else if (get_bits1(&gb)) {
263  if (get_bits1(&gb)) {
264  y_avg = get_bits(&gb, 6);
265  } else {
266  unsigned adjust_index = get_bits(&gb, 3);
267  y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
268  }
269  for (i = 0; i < 4; i++)
270  y[i] = y_avg;
271  }
272 
273  if (get_bits1(&gb)) {
274  if (get_bits1(&gb)) {
275  cb = get_bits(&gb, 5);
276  cr = get_bits(&gb, 5);
277  } else {
278  unsigned adjust_index = get_bits(&gb, 3);
279  cb = (cb + chroma_adjust[0][adjust_index]) & 31;
280  cr = (cr + chroma_adjust[1][adjust_index]) & 31;
281  }
282  }
283  }
284  *ya++ = y_avg;
285 
286  new_y[0] = y[0];
287  new_y[1] = y[1];
288  new_y[new_y_stride] = y[2];
289  new_y[new_y_stride + 1] = y[3];
290  *new_cb = cb;
291  *new_cr = cr;
292 
293  old_y += 2;
294  old_cb++;
295  old_cr++;
296  new_y += 2;
297  new_cb++;
298  new_cr++;
299  block_x++;
300  if (block_x * 2 == avctx->width) {
301  block_x = 0;
302  old_y += old_y_stride * 2 - avctx->width;
303  old_cb += old_cb_stride - avctx->width / 2;
304  old_cr += old_cr_stride - avctx->width / 2;
305  new_y += new_y_stride * 2 - avctx->width;
306  new_cb += new_cb_stride - avctx->width / 2;
307  new_cr += new_cr_stride - avctx->width / 2;
308  }
309 
310  skip--;
311  }
312 
313  new_y = s->new_y;
314  new_cb = s->new_u;
315  new_cr = s->new_v;
316  dstY = pic->data[0];
317  dstU = pic->data[1];
318  dstV = pic->data[2];
319  for (j = 0; j < avctx->height; j++) {
320  for (i = 0; i < avctx->width; i++)
321  dstY[i] = new_y[i] << 2;
322  dstY += pic->linesize[0];
323  new_y += new_y_stride;
324  }
325  for (j = 0; j < avctx->height / 2; j++) {
326  for (i = 0; i < avctx->width / 2; i++) {
327  dstU[i] = chroma_vals[new_cb[i]];
328  dstV[i] = chroma_vals[new_cr[i]];
329  }
330  dstU += pic->linesize[1];
331  dstV += pic->linesize[2];
332  new_cb += new_cb_stride;
333  new_cr += new_cr_stride;
334  }
335 
336  ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
337  buf_size, get_bits_count(&gb) >> 3);
338 
339  FFSWAP(uint8_t*, s->old_y, s->new_y);
340  FFSWAP(uint8_t*, s->old_u, s->new_u);
341  FFSWAP(uint8_t*, s->old_v, s->new_v);
342 
343  *got_frame = 1;
344 
345  return buf_size;
346 }
347 
349  .p.name = "escape130",
350  CODEC_LONG_NAME("Escape 130"),
351  .p.type = AVMEDIA_TYPE_VIDEO,
352  .p.id = AV_CODEC_ID_ESCAPE130,
353  .priv_data_size = sizeof(Escape130Context),
355  .close = escape130_decode_close,
357  .p.capabilities = AV_CODEC_CAP_DR1,
358  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
359 };
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:268
av_clip
#define av_clip
Definition: common.h:95
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:664
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
AV_CODEC_ID_ESCAPE130
@ AV_CODEC_ID_ESCAPE130
Definition: codec_id.h:222
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:239
Escape130Context::old_v
uint8_t * old_v
Definition: escape130.c:36
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:256
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
AVPacket::data
uint8_t * data
Definition: packet.h:374
Escape130Context::buf1
uint8_t * buf1
Definition: escape130.c:38
FFCodec
Definition: codec_internal.h:127
escape130_decode_frame
static int escape130_decode_frame(AVCodecContext *avctx, AVFrame *pic, int *got_frame, AVPacket *avpkt)
Definition: escape130.c:190
Escape130Context::new_v
uint8_t * new_v
Definition: escape130.c:36
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:351
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:325
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
GetBitContext
Definition: get_bits.h:107
ff_escape130_decoder
const FFCodec ff_escape130_decoder
Definition: escape130.c:348
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:524
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
s
#define s(width, name)
Definition: cbs_vp9.c:256
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
decode.h
get_bits.h
Escape130Context
Definition: escape130.c:31
chroma_adjust
static const int8_t chroma_adjust[2][8]
Definition: escape130.c:105
Escape130Context::buf2
uint8_t * buf2
Definition: escape130.c:38
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
escape130_decode_close
static av_cold int escape130_decode_close(AVCodecContext *avctx)
Definition: escape130.c:153
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
Escape130Context::linesize
int linesize[3]
Definition: escape130.c:39
Escape130Context::new_y
uint8_t * new_y
Definition: escape130.c:34
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:378
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1473
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
codec_internal.h
decode_skip_count
static int decode_skip_count(GetBitContext *gb)
Definition: escape130.c:164
attributes.h
offset_table
static const uint8_t offset_table[]
Definition: escape130.c:42
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:191
AVCodecContext::height
int height
Definition: avcodec.h:598
Escape130Context::old_u
uint8_t * old_u
Definition: escape130.c:35
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:635
avcodec.h
ret
ret
Definition: filter_design.txt:187
escape130_decode_init
static av_cold int escape130_decode_init(AVCodecContext *avctx)
Definition: escape130.c:117
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
sign_table
static const int8_t sign_table[64][4]
Definition: escape130.c:43
AVCodecContext
main external API structure.
Definition: avcodec.h:426
Escape130Context::new_u
uint8_t * new_u
Definition: escape130.c:35
Escape130Context::old_y_avg
uint8_t * old_y_avg
Definition: escape130.c:32
chroma_vals
static const uint8_t chroma_vals[]
Definition: escape130.c:110
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
luma_adjust
static const int8_t luma_adjust[]
Definition: escape130.c:103
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:453
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:598
AVFrame::linesize
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:375
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
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
Escape130Context::old_y
uint8_t * old_y
Definition: escape130.c:34