FFmpeg  4.4
qtrleenc.c
Go to the documentation of this file.
1 /*
2  * Quicktime Animation (RLE) Video Encoder
3  * Copyright (C) 2007 Clemens Fruhwirth
4  * Copyright (C) 2007 Alexis Ballier
5  *
6  * This file is based on flashsvenc.c.
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include "libavutil/imgutils.h"
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "internal.h"
29 
30 /** Maximum RLE code for bulk copy */
31 #define MAX_RLE_BULK 127
32 /** Maximum RLE code for repeat */
33 #define MAX_RLE_REPEAT 128
34 /** Maximum RLE code for skip */
35 #define MAX_RLE_SKIP 254
36 
37 typedef struct QtrleEncContext {
41  unsigned int max_buf_size;
43  /**
44  * This array will contain at ith position the value of the best RLE code
45  * if the line started at pixel i
46  * There can be 3 values :
47  * skip (0) : skip as much as possible pixels because they are equal to the
48  * previous frame ones
49  * repeat (<-1) : repeat that pixel -rle_code times, still as much as
50  * possible
51  * copy (>0) : copy the raw next rle_code pixels */
52  signed char *rlecode_table;
53  /**
54  * This array will contain the length of the best rle encoding of the line
55  * starting at ith pixel */
57  /**
58  * Will contain at ith position the number of consecutive pixels equal to the previous
59  * frame starting from pixel i */
61 
62  /** Encoded frame is a key frame */
63  int key_frame;
65 
67 {
68  QtrleEncContext *s = avctx->priv_data;
69 
70  av_frame_free(&s->previous_frame);
71  av_free(s->rlecode_table);
72  av_free(s->length_table);
73  av_free(s->skip_table);
74  return 0;
75 }
76 
78 {
79  QtrleEncContext *s = avctx->priv_data;
80 
81  if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
82  return AVERROR(EINVAL);
83  }
84  s->avctx=avctx;
85  s->logical_width=avctx->width;
86 
87  switch (avctx->pix_fmt) {
88  case AV_PIX_FMT_GRAY8:
89  if (avctx->width % 4) {
90  av_log(avctx, AV_LOG_ERROR, "Width not being a multiple of 4 is not supported\n");
91  return AVERROR(EINVAL);
92  }
93  s->logical_width = avctx->width / 4;
94  s->pixel_size = 4;
95  break;
97  s->pixel_size = 2;
98  break;
99  case AV_PIX_FMT_RGB24:
100  s->pixel_size = 3;
101  break;
102  case AV_PIX_FMT_ARGB:
103  s->pixel_size = 4;
104  break;
105  default:
106  av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n");
107  break;
108  }
109  avctx->bits_per_coded_sample = avctx->pix_fmt == AV_PIX_FMT_GRAY8 ? 40 : s->pixel_size*8;
110 
111  s->rlecode_table = av_mallocz(s->logical_width);
112  s->skip_table = av_mallocz(s->logical_width);
113  s->length_table = av_mallocz_array(s->logical_width + 1, sizeof(int));
114  if (!s->skip_table || !s->length_table || !s->rlecode_table) {
115  av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n");
116  return AVERROR(ENOMEM);
117  }
118  s->previous_frame = av_frame_alloc();
119  if (!s->previous_frame) {
120  av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n");
121  return AVERROR(ENOMEM);
122  }
123 
124  s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size*2 /* image base material */
125  + 15 /* header + footer */
126  + s->avctx->height*2 /* skip code+rle end */
127  + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */;
128 
129  return 0;
130 }
131 
132 /**
133  * Compute the best RLE sequence for a line
134  */
135 static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, uint8_t **buf)
136 {
137  int width=s->logical_width;
138  int i;
139  signed char rlecode;
140 
141  /* This will be the number of pixels equal to the previous frame one's
142  * starting from the ith pixel */
143  unsigned int skipcount;
144  /* This will be the number of consecutive equal pixels in the current
145  * frame, starting from the ith one also */
146  unsigned int av_uninit(repeatcount);
147 
148  /* The cost of the three different possibilities */
149  int total_skip_cost;
150  int total_repeat_cost;
151 
152  int base_bulk_cost;
153  int lowest_bulk_cost;
154  int lowest_bulk_cost_index;
155  int sec_lowest_bulk_cost;
156  int sec_lowest_bulk_cost_index;
157 
158  const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size;
159  /* There might be no earlier frame if the current frame is a keyframe.
160  * So just use a pointer to the current frame to avoid a check
161  * to avoid NULL - s->pixel_size (which is undefined behaviour). */
162  const uint8_t *prev_line = s->key_frame ? this_line
163  : s->previous_frame->data[0]
164  + line * s->previous_frame->linesize[0]
165  + width * s->pixel_size;
166 
167  s->length_table[width] = 0;
168  skipcount = 0;
169 
170  /* Initial values */
171  lowest_bulk_cost = INT_MAX / 2;
172  lowest_bulk_cost_index = width;
173  sec_lowest_bulk_cost = INT_MAX / 2;
174  sec_lowest_bulk_cost_index = width;
175 
176  base_bulk_cost = 1 + s->pixel_size;
177 
178  for (i = width - 1; i >= 0; i--) {
179 
180  int prev_bulk_cost;
181 
182  this_line -= s->pixel_size;
183  prev_line -= s->pixel_size;
184 
185  /* If our lowest bulk cost index is too far away, replace it
186  * with the next lowest bulk cost */
187  if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
188  lowest_bulk_cost = sec_lowest_bulk_cost;
189  lowest_bulk_cost_index = sec_lowest_bulk_cost_index;
190 
191  sec_lowest_bulk_cost = INT_MAX / 2;
192  sec_lowest_bulk_cost_index = width;
193  }
194 
195  /* Deal with the first pixel's bulk cost */
196  if (!i) {
197  base_bulk_cost++;
198  lowest_bulk_cost++;
199  sec_lowest_bulk_cost++;
200  }
201 
202  /* Look at the bulk cost of the previous loop and see if it is
203  * a new lower bulk cost */
204  prev_bulk_cost = s->length_table[i + 1] + base_bulk_cost;
205  if (prev_bulk_cost <= sec_lowest_bulk_cost) {
206  /* If it's lower than the 2nd lowest, then it may be lower
207  * than the lowest */
208  if (prev_bulk_cost <= lowest_bulk_cost) {
209 
210  /* If we have found a new lowest bulk cost,
211  * then the 2nd lowest bulk cost is now farther than the
212  * lowest bulk cost, and will never be used */
213  sec_lowest_bulk_cost = INT_MAX / 2;
214 
215  lowest_bulk_cost = prev_bulk_cost;
216  lowest_bulk_cost_index = i + 1;
217  } else {
218  /* Then it must be the 2nd lowest bulk cost */
219  sec_lowest_bulk_cost = prev_bulk_cost;
220  sec_lowest_bulk_cost_index = i + 1;
221  }
222  }
223 
224  if (!s->key_frame && !memcmp(this_line, prev_line, s->pixel_size))
225  skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
226  else
227  skipcount = 0;
228 
229  total_skip_cost = s->length_table[i + skipcount] + 2;
230  s->skip_table[i] = skipcount;
231 
232 
233  if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size))
234  repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT);
235  else
236  repeatcount = 1;
237 
238  total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size;
239 
240  /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy
241  * so let's make it aware */
242  if (i == 0) {
243  total_skip_cost--;
244  total_repeat_cost++;
245  }
246 
247  if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) {
248  /* repeat is the best */
249  s->length_table[i] = total_repeat_cost;
250  s->rlecode_table[i] = -repeatcount;
251  }
252  else if (skipcount > 0) {
253  /* skip is the best choice here */
254  s->length_table[i] = total_skip_cost;
255  s->rlecode_table[i] = 0;
256  }
257  else {
258  /* We cannot do neither skip nor repeat
259  * thus we use the best bulk copy */
260 
261  s->length_table[i] = lowest_bulk_cost;
262  s->rlecode_table[i] = lowest_bulk_cost_index - i;
263 
264  }
265 
266  /* These bulk costs increase every iteration */
267  lowest_bulk_cost += s->pixel_size;
268  sec_lowest_bulk_cost += s->pixel_size;
269  }
270 
271  /* Good! Now we have the best sequence for this line, let's output it. */
272 
273  /* We do a special case for the first pixel so that we avoid testing it in
274  * the whole loop */
275 
276  i=0;
277  this_line = p-> data[0] + line*p->linesize[0];
278 
279  if (s->rlecode_table[0] == 0) {
280  bytestream_put_byte(buf, s->skip_table[0] + 1);
281  i += s->skip_table[0];
282  }
283  else bytestream_put_byte(buf, 1);
284 
285 
286  while (i < width) {
287  rlecode = s->rlecode_table[i];
288  bytestream_put_byte(buf, rlecode);
289  if (rlecode == 0) {
290  /* Write a skip sequence */
291  bytestream_put_byte(buf, s->skip_table[i] + 1);
292  i += s->skip_table[i];
293  }
294  else if (rlecode > 0) {
295  /* bulk copy */
296  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
297  int j;
298  // QT grayscale colorspace has 0=white and 255=black, we will
299  // ignore the palette that is included in the AVFrame because
300  // AV_PIX_FMT_GRAY8 has defined color mapping
301  for (j = 0; j < rlecode*s->pixel_size; ++j)
302  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
303  } else {
304  bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
305  }
306  i += rlecode;
307  }
308  else {
309  /* repeat the bits */
310  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
311  int j;
312  // QT grayscale colorspace has 0=white and 255=black, ...
313  for (j = 0; j < s->pixel_size; ++j)
314  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
315  } else {
316  bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
317  }
318  i -= rlecode;
319  }
320  }
321  bytestream_put_byte(buf, -1); // end RLE line
322 }
323 
324 /** Encode frame including header */
325 static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
326 {
327  int i;
328  int start_line = 0;
329  int end_line = s->avctx->height;
330  uint8_t *orig_buf = buf;
331 
332  if (!s->key_frame) {
333  unsigned line_size = s->logical_width * s->pixel_size;
334  for (start_line = 0; start_line < s->avctx->height; start_line++)
335  if (memcmp(p->data[0] + start_line*p->linesize[0],
336  s->previous_frame->data[0] + start_line * s->previous_frame->linesize[0],
337  line_size))
338  break;
339 
340  for (end_line=s->avctx->height; end_line > start_line; end_line--)
341  if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0],
342  s->previous_frame->data[0] + (end_line - 1) * s->previous_frame->linesize[0],
343  line_size))
344  break;
345  }
346 
347  bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later
348 
349  if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height)
350  bytestream_put_be16(&buf, 0); // header
351  else {
352  bytestream_put_be16(&buf, 8); // header
353  bytestream_put_be16(&buf, start_line); // starting line
354  bytestream_put_be16(&buf, 0); // unknown
355  bytestream_put_be16(&buf, end_line - start_line); // lines to update
356  bytestream_put_be16(&buf, 0); // unknown
357  }
358  for (i = start_line; i < end_line; i++)
359  qtrle_encode_line(s, p, i, &buf);
360 
361  bytestream_put_byte(&buf, 0); // zero skip code = frame finished
362  AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size
363  return buf - orig_buf;
364 }
365 
367  const AVFrame *pict, int *got_packet)
368 {
369  QtrleEncContext * const s = avctx->priv_data;
370  int ret;
371 
372  if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0)
373  return ret;
374 
375  if (avctx->gop_size == 0 || !s->previous_frame->data[0] ||
376  (s->avctx->frame_number % avctx->gop_size) == 0) {
377  /* I-Frame */
378  s->key_frame = 1;
379  } else {
380  /* P-Frame */
381  s->key_frame = 0;
382  }
383 
384  pkt->size = encode_frame(s, pict, pkt->data);
385 
386  /* save the current frame */
387  av_frame_unref(s->previous_frame);
388  ret = av_frame_ref(s->previous_frame, pict);
389  if (ret < 0) {
390  av_log(avctx, AV_LOG_ERROR, "cannot add reference\n");
391  return ret;
392  }
393 
394 #if FF_API_CODED_FRAME
396  avctx->coded_frame->key_frame = s->key_frame;
397  avctx->coded_frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
399 #endif
400 
401  if (s->key_frame)
403  *got_packet = 1;
404 
405  return 0;
406 }
407 
409  .name = "qtrle",
410  .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
411  .type = AVMEDIA_TYPE_VIDEO,
412  .id = AV_CODEC_ID_QTRLE,
413  .priv_data_size = sizeof(QtrleEncContext),
415  .encode2 = qtrle_encode_frame,
416  .close = qtrle_encode_end,
417  .pix_fmts = (const enum AVPixelFormat[]){
419  },
420  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
421 };
#define av_uninit(x)
Definition: attributes.h:154
#define av_cold
Definition: attributes.h:88
uint8_t
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:372
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:33
@ AV_CODEC_ID_QTRLE
Definition: codec_id.h:104
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:443
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
Definition: mem.c:190
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:317
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
misc image utilities
int i
Definition: input.c:407
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:49
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
const char data[16]
Definition: mxf.c:142
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
@ AV_PIX_FMT_RGB555BE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:107
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
static av_cold int qtrle_encode_end(AVCodecContext *avctx)
Definition: qtrleenc.c:66
static av_cold int qtrle_encode_init(AVCodecContext *avctx)
Definition: qtrleenc.c:77
#define MAX_RLE_REPEAT
Maximum RLE code for repeat.
Definition: qtrleenc.c:33
static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, uint8_t **buf)
Compute the best RLE sequence for a line.
Definition: qtrleenc.c:135
AVCodec ff_qtrle_encoder
Definition: qtrleenc.c:408
static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: qtrleenc.c:366
#define MAX_RLE_SKIP
Maximum RLE code for skip.
Definition: qtrleenc.c:35
#define MAX_RLE_BULK
Maximum RLE code for bulk copy.
Definition: qtrleenc.c:31
static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
Encode frame including header.
Definition: qtrleenc.c:325
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1740
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:1764
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:731
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
This structure stores compressed data.
Definition: packet.h:346
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
unsigned int max_buf_size
Definition: qtrleenc.c:41
AVFrame * previous_frame
Definition: qtrleenc.c:40
AVCodecContext * avctx
Definition: qtrleenc.c:38
int logical_width
Definition: qtrleenc.c:42
uint8_t * skip_table
Will contain at ith position the number of consecutive pixels equal to the previous frame starting fr...
Definition: qtrleenc.c:60
int * length_table
This array will contain the length of the best rle encoding of the line starting at ith pixel.
Definition: qtrleenc.c:56
signed char * rlecode_table
This array will contain at ith position the value of the best RLE code if the line started at pixel i...
Definition: qtrleenc.c:52
int key_frame
Encoded frame is a key frame.
Definition: qtrleenc.c:63
Definition: graph2dot.c:48
#define av_free(p)
#define av_log(a,...)
AVPacket * pkt
Definition: movenc.c:59
#define width