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 "get_bits.h"
28 #include "internal.h"
29 
30 typedef struct Escape130Context {
32 
36 
38  int linesize[3];
40 
41 static const uint8_t offset_table[] = { 2, 4, 10, 20 };
42 static const int8_t sign_table[64][4] = {
43  { 0, 0, 0, 0 },
44  { -1, 1, 0, 0 },
45  { 1, -1, 0, 0 },
46  { -1, 0, 1, 0 },
47  { -1, 1, 1, 0 },
48  { 0, -1, 1, 0 },
49  { 1, -1, 1, 0 },
50  { -1, -1, 1, 0 },
51  { 1, 0, -1, 0 },
52  { 0, 1, -1, 0 },
53  { 1, 1, -1, 0 },
54  { -1, 1, -1, 0 },
55  { 1, -1, -1, 0 },
56  { -1, 0, 0, 1 },
57  { -1, 1, 0, 1 },
58  { 0, -1, 0, 1 },
59 
60  { 0, 0, 0, 0 },
61  { 1, -1, 0, 1 },
62  { -1, -1, 0, 1 },
63  { -1, 0, 1, 1 },
64  { -1, 1, 1, 1 },
65  { 0, -1, 1, 1 },
66  { 1, -1, 1, 1 },
67  { -1, -1, 1, 1 },
68  { 0, 0, -1, 1 },
69  { 1, 0, -1, 1 },
70  { -1, 0, -1, 1 },
71  { 0, 1, -1, 1 },
72  { 1, 1, -1, 1 },
73  { -1, 1, -1, 1 },
74  { 0, -1, -1, 1 },
75  { 1, -1, -1, 1 },
76 
77  { 0, 0, 0, 0 },
78  { -1, -1, -1, 1 },
79  { 1, 0, 0, -1 },
80  { 0, 1, 0, -1 },
81  { 1, 1, 0, -1 },
82  { -1, 1, 0, -1 },
83  { 1, -1, 0, -1 },
84  { 0, 0, 1, -1 },
85  { 1, 0, 1, -1 },
86  { -1, 0, 1, -1 },
87  { 0, 1, 1, -1 },
88  { 1, 1, 1, -1 },
89  { -1, 1, 1, -1 },
90  { 0, -1, 1, -1 },
91  { 1, -1, 1, -1 },
92  { -1, -1, 1, -1 },
93 
94  { 0, 0, 0, 0 },
95  { 1, 0, -1, -1 },
96  { 0, 1, -1, -1 },
97  { 1, 1, -1, -1 },
98  { -1, 1, -1, -1 },
99  { 1, -1, -1, -1 }
100 };
101 
102 static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
103 
104 static const int8_t chroma_adjust[2][8] = {
105  { 1, 1, 0, -1, -1, -1, 0, 1 },
106  { 0, 1, 1, 1, 0, -1, -1, -1 }
107 };
108 
109 static const uint8_t chroma_vals[] = {
110  20, 28, 36, 44, 52, 60, 68, 76,
111  84, 92, 100, 106, 112, 116, 120, 124,
112  128, 132, 136, 140, 144, 150, 156, 164,
113  172, 180, 188, 196, 204, 212, 220, 228
114 };
115 
117 {
118  Escape130Context *s = avctx->priv_data;
119  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
120 
121  if ((avctx->width & 1) || (avctx->height & 1)) {
122  av_log(avctx, AV_LOG_ERROR,
123  "Dimensions should be a multiple of two.\n");
124  return AVERROR_INVALIDDATA;
125  }
126 
127  s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
128  s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2);
129  s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2);
130  if (!s->old_y_avg || !s->buf1 || !s->buf2) {
131  av_freep(&s->old_y_avg);
132  av_freep(&s->buf1);
133  av_freep(&s->buf2);
134  av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
135  return AVERROR(ENOMEM);
136  }
137 
138  s->linesize[0] = avctx->width;
139  s->linesize[1] =
140  s->linesize[2] = avctx->width / 2;
141 
142  s->new_y = s->buf1;
143  s->new_u = s->new_y + avctx->width * avctx->height;
144  s->new_v = s->new_u + avctx->width * avctx->height / 4;
145  s->old_y = s->buf2;
146  s->old_u = s->old_y + avctx->width * avctx->height;
147  s->old_v = s->old_u + avctx->width * avctx->height / 4;
148  memset(s->old_y, 0, avctx->width * avctx->height);
149  memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
150  memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
151 
152  return 0;
153 }
154 
156 {
157  Escape130Context *s = avctx->priv_data;
158 
159  av_freep(&s->old_y_avg);
160  av_freep(&s->buf1);
161  av_freep(&s->buf2);
162 
163  return 0;
164 }
165 
167 {
168  int value;
169 
170  if (get_bits_left(gb) < 1+3)
171  return -1;
172 
173  value = get_bits1(gb);
174  if (value)
175  return 0;
176 
177  value = get_bits(gb, 3);
178  if (value)
179  return value;
180 
181  value = get_bits(gb, 8);
182  if (value)
183  return value + 7;
184 
185  value = get_bits(gb, 15);
186  if (value)
187  return value + 262;
188 
189  return -1;
190 }
191 
192 static int escape130_decode_frame(AVCodecContext *avctx, void *data,
193  int *got_frame, AVPacket *avpkt)
194 {
195  int buf_size = avpkt->size;
196  Escape130Context *s = avctx->priv_data;
197  AVFrame *pic = data;
198  GetBitContext gb;
199  int ret;
200 
201  uint8_t *old_y, *old_cb, *old_cr,
202  *new_y, *new_cb, *new_cr;
203  uint8_t *dstY, *dstU, *dstV;
204  unsigned old_y_stride, old_cb_stride, old_cr_stride,
205  new_y_stride, new_cb_stride, new_cr_stride;
206  unsigned total_blocks = avctx->width * avctx->height / 4,
207  block_index, block_x = 0;
208  unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
209  int skip = -1, y_avg = 0, i, j;
210  uint8_t *ya = s->old_y_avg;
211 
212  // first 16 bytes are header; no useful information in here
213  if (buf_size <= 16) {
214  av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
215  return AVERROR_INVALIDDATA;
216  }
217 
218  if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
219  return ret;
220 
221  if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
222  return ret;
223  skip_bits_long(&gb, 16 * 8);
224 
225  new_y = s->new_y;
226  new_cb = s->new_u;
227  new_cr = s->new_v;
228  new_y_stride = s->linesize[0];
229  new_cb_stride = s->linesize[1];
230  new_cr_stride = s->linesize[2];
231  old_y = s->old_y;
232  old_cb = s->old_u;
233  old_cr = s->old_v;
234  old_y_stride = s->linesize[0];
235  old_cb_stride = s->linesize[1];
236  old_cr_stride = s->linesize[2];
237 
238  for (block_index = 0; block_index < total_blocks; block_index++) {
239  // Note that this call will make us skip the rest of the blocks
240  // if the frame ends prematurely.
241  if (skip == -1)
242  skip = decode_skip_count(&gb);
243  if (skip == -1) {
244  av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
245  return AVERROR_INVALIDDATA;
246  }
247 
248  if (skip) {
249  y[0] = old_y[0];
250  y[1] = old_y[1];
251  y[2] = old_y[old_y_stride];
252  y[3] = old_y[old_y_stride + 1];
253  y_avg = ya[0];
254  cb = old_cb[0];
255  cr = old_cr[0];
256  } else {
257  if (get_bits1(&gb)) {
258  unsigned sign_selector = get_bits(&gb, 6);
259  unsigned difference_selector = get_bits(&gb, 2);
260  y_avg = 2 * get_bits(&gb, 5);
261  for (i = 0; i < 4; i++) {
262  y[i] = av_clip(y_avg + offset_table[difference_selector] *
263  sign_table[sign_selector][i], 0, 63);
264  }
265  } else if (get_bits1(&gb)) {
266  if (get_bits1(&gb)) {
267  y_avg = get_bits(&gb, 6);
268  } else {
269  unsigned adjust_index = get_bits(&gb, 3);
270  y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
271  }
272  for (i = 0; i < 4; i++)
273  y[i] = y_avg;
274  }
275 
276  if (get_bits1(&gb)) {
277  if (get_bits1(&gb)) {
278  cb = get_bits(&gb, 5);
279  cr = get_bits(&gb, 5);
280  } else {
281  unsigned adjust_index = get_bits(&gb, 3);
282  cb = (cb + chroma_adjust[0][adjust_index]) & 31;
283  cr = (cr + chroma_adjust[1][adjust_index]) & 31;
284  }
285  }
286  }
287  *ya++ = y_avg;
288 
289  new_y[0] = y[0];
290  new_y[1] = y[1];
291  new_y[new_y_stride] = y[2];
292  new_y[new_y_stride + 1] = y[3];
293  *new_cb = cb;
294  *new_cr = cr;
295 
296  old_y += 2;
297  old_cb++;
298  old_cr++;
299  new_y += 2;
300  new_cb++;
301  new_cr++;
302  block_x++;
303  if (block_x * 2 == avctx->width) {
304  block_x = 0;
305  old_y += old_y_stride * 2 - avctx->width;
306  old_cb += old_cb_stride - avctx->width / 2;
307  old_cr += old_cr_stride - avctx->width / 2;
308  new_y += new_y_stride * 2 - avctx->width;
309  new_cb += new_cb_stride - avctx->width / 2;
310  new_cr += new_cr_stride - avctx->width / 2;
311  }
312 
313  skip--;
314  }
315 
316  new_y = s->new_y;
317  new_cb = s->new_u;
318  new_cr = s->new_v;
319  dstY = pic->data[0];
320  dstU = pic->data[1];
321  dstV = pic->data[2];
322  for (j = 0; j < avctx->height; j++) {
323  for (i = 0; i < avctx->width; i++)
324  dstY[i] = new_y[i] << 2;
325  dstY += pic->linesize[0];
326  new_y += new_y_stride;
327  }
328  for (j = 0; j < avctx->height / 2; j++) {
329  for (i = 0; i < avctx->width / 2; i++) {
330  dstU[i] = chroma_vals[new_cb[i]];
331  dstV[i] = chroma_vals[new_cr[i]];
332  }
333  dstU += pic->linesize[1];
334  dstV += pic->linesize[2];
335  new_cb += new_cb_stride;
336  new_cr += new_cr_stride;
337  }
338 
339  ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
340  buf_size, get_bits_count(&gb) >> 3);
341 
342  FFSWAP(uint8_t*, s->old_y, s->new_y);
343  FFSWAP(uint8_t*, s->old_u, s->new_u);
344  FFSWAP(uint8_t*, s->old_v, s->new_v);
345 
346  *got_frame = 1;
347 
348  return buf_size;
349 }
350 
352  .name = "escape130",
353  .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
354  .type = AVMEDIA_TYPE_VIDEO,
355  .id = AV_CODEC_ID_ESCAPE130,
356  .priv_data_size = sizeof(Escape130Context),
358  .close = escape130_decode_close,
360  .capabilities = AV_CODEC_CAP_DR1,
361 };
AVCodec
AVCodec.
Definition: codec.h:190
skip_bits_long
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:291
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
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:219
FFSWAP
#define FFSWAP(type, a, b)
Definition: common.h:99
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
Escape130Context::old_v
uint8_t * old_v
Definition: escape130.c:35
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
Escape130Context::buf1
uint8_t * buf1
Definition: escape130.c:37
data
const char data[16]
Definition: mxf.c:91
Escape130Context::new_v
uint8_t * new_v
Definition: escape130.c:35
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
GetBitContext
Definition: get_bits.h:61
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:677
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
s
#define s(width, name)
Definition: cbs_vp9.c:257
get_bits.h
Escape130Context
Definition: escape130.c:30
chroma_adjust
static const int8_t chroma_adjust[2][8]
Definition: escape130.c:104
Escape130Context::buf2
uint8_t * buf2
Definition: escape130.c:37
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:155
Escape130Context::linesize
int linesize[3]
Definition: escape130.c:38
Escape130Context::new_y
uint8_t * new_y
Definition: escape130.c:33
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
ff_escape130_decoder
AVCodec ff_escape130_decoder
Definition: escape130.c:351
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1854
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
AVPacket::size
int size
Definition: packet.h:356
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:188
decode_skip_count
static int decode_skip_count(GetBitContext *gb)
Definition: escape130.c:166
attributes.h
offset_table
static const uint8_t offset_table[]
Definition: escape130.c:41
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
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
AVCodecContext::height
int height
Definition: avcodec.h:699
Escape130Context::old_u
uint8_t * old_u
Definition: escape130.c:34
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
avcodec.h
ret
ret
Definition: filter_design.txt:187
escape130_decode_init
static av_cold int escape130_decode_init(AVCodecContext *avctx)
Definition: escape130.c:116
sign_table
static const int8_t sign_table[64][4]
Definition: escape130.c:42
AVCodecContext
main external API structure.
Definition: avcodec.h:526
Escape130Context::new_u
uint8_t * new_u
Definition: escape130.c:34
Escape130Context::old_y_avg
uint8_t * old_y_avg
Definition: escape130.c:31
chroma_vals
static const uint8_t chroma_vals[]
Definition: escape130.c:109
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
luma_adjust
static const int8_t luma_adjust[]
Definition: escape130.c:102
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:216
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:699
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
escape130_decode_frame
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: escape130.c:192
Escape130Context::old_y
uint8_t * old_y
Definition: escape130.c:33