FFmpeg  4.3.6
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 
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 
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  }
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  uint8_t *this_line = p-> data[0] + line*p-> linesize[0] +
159  (width - 1)*s->pixel_size;
160  uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] +
161  (width - 1)*s->pixel_size;
162 
163  s->length_table[width] = 0;
164  skipcount = 0;
165 
166  /* Initial values */
167  lowest_bulk_cost = INT_MAX / 2;
168  lowest_bulk_cost_index = width;
169  sec_lowest_bulk_cost = INT_MAX / 2;
170  sec_lowest_bulk_cost_index = width;
171 
172  base_bulk_cost = 1 + s->pixel_size;
173 
174  for (i = width - 1; i >= 0; i--) {
175 
176  int prev_bulk_cost;
177 
178  /* If our lowest bulk cost index is too far away, replace it
179  * with the next lowest bulk cost */
180  if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
181  lowest_bulk_cost = sec_lowest_bulk_cost;
182  lowest_bulk_cost_index = sec_lowest_bulk_cost_index;
183 
184  sec_lowest_bulk_cost = INT_MAX / 2;
185  sec_lowest_bulk_cost_index = width;
186  }
187 
188  /* Deal with the first pixel's bulk cost */
189  if (!i) {
190  base_bulk_cost++;
191  lowest_bulk_cost++;
192  sec_lowest_bulk_cost++;
193  }
194 
195  /* Look at the bulk cost of the previous loop and see if it is
196  * a new lower bulk cost */
197  prev_bulk_cost = s->length_table[i + 1] + base_bulk_cost;
198  if (prev_bulk_cost <= sec_lowest_bulk_cost) {
199  /* If it's lower than the 2nd lowest, then it may be lower
200  * than the lowest */
201  if (prev_bulk_cost <= lowest_bulk_cost) {
202 
203  /* If we have found a new lowest bulk cost,
204  * then the 2nd lowest bulk cost is now farther than the
205  * lowest bulk cost, and will never be used */
206  sec_lowest_bulk_cost = INT_MAX / 2;
207 
208  lowest_bulk_cost = prev_bulk_cost;
209  lowest_bulk_cost_index = i + 1;
210  } else {
211  /* Then it must be the 2nd lowest bulk cost */
212  sec_lowest_bulk_cost = prev_bulk_cost;
213  sec_lowest_bulk_cost_index = i + 1;
214  }
215  }
216 
217  if (!s->key_frame && !memcmp(this_line, prev_line, s->pixel_size))
218  skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
219  else
220  skipcount = 0;
221 
222  total_skip_cost = s->length_table[i + skipcount] + 2;
223  s->skip_table[i] = skipcount;
224 
225 
226  if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size))
227  repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT);
228  else
229  repeatcount = 1;
230 
231  total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size;
232 
233  /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy
234  * so let's make it aware */
235  if (i == 0) {
236  total_skip_cost--;
237  total_repeat_cost++;
238  }
239 
240  if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) {
241  /* repeat is the best */
242  s->length_table[i] = total_repeat_cost;
243  s->rlecode_table[i] = -repeatcount;
244  }
245  else if (skipcount > 0) {
246  /* skip is the best choice here */
247  s->length_table[i] = total_skip_cost;
248  s->rlecode_table[i] = 0;
249  }
250  else {
251  /* We cannot do neither skip nor repeat
252  * thus we use the best bulk copy */
253 
254  s->length_table[i] = lowest_bulk_cost;
255  s->rlecode_table[i] = lowest_bulk_cost_index - i;
256 
257  }
258 
259  /* These bulk costs increase every iteration */
260  lowest_bulk_cost += s->pixel_size;
261  sec_lowest_bulk_cost += s->pixel_size;
262  if (this_line >= p->data[0] + s->pixel_size)
263  this_line -= s->pixel_size;
264  if (prev_line >= s->previous_frame->data[0] + s->pixel_size)
265  prev_line -= s->pixel_size;
266  }
267 
268  /* Good! Now we have the best sequence for this line, let's output it. */
269 
270  /* We do a special case for the first pixel so that we avoid testing it in
271  * the whole loop */
272 
273  i=0;
274  this_line = p-> data[0] + line*p->linesize[0];
275 
276  if (s->rlecode_table[0] == 0) {
277  bytestream_put_byte(buf, s->skip_table[0] + 1);
278  i += s->skip_table[0];
279  }
280  else bytestream_put_byte(buf, 1);
281 
282 
283  while (i < width) {
284  rlecode = s->rlecode_table[i];
285  bytestream_put_byte(buf, rlecode);
286  if (rlecode == 0) {
287  /* Write a skip sequence */
288  bytestream_put_byte(buf, s->skip_table[i] + 1);
289  i += s->skip_table[i];
290  }
291  else if (rlecode > 0) {
292  /* bulk copy */
293  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
294  int j;
295  // QT grayscale colorspace has 0=white and 255=black, we will
296  // ignore the palette that is included in the AVFrame because
297  // AV_PIX_FMT_GRAY8 has defined color mapping
298  for (j = 0; j < rlecode*s->pixel_size; ++j)
299  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
300  } else {
301  bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
302  }
303  i += rlecode;
304  }
305  else {
306  /* repeat the bits */
307  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
308  int j;
309  // QT grayscale colorspace has 0=white and 255=black, ...
310  for (j = 0; j < s->pixel_size; ++j)
311  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
312  } else {
313  bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
314  }
315  i -= rlecode;
316  }
317  }
318  bytestream_put_byte(buf, -1); // end RLE line
319 }
320 
321 /** Encode frame including header */
322 static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
323 {
324  int i;
325  int start_line = 0;
326  int end_line = s->avctx->height;
327  uint8_t *orig_buf = buf;
328 
329  if (!s->key_frame) {
330  unsigned line_size = s->logical_width * s->pixel_size;
331  for (start_line = 0; start_line < s->avctx->height; start_line++)
332  if (memcmp(p->data[0] + start_line*p->linesize[0],
333  s->previous_frame->data[0] + start_line * s->previous_frame->linesize[0],
334  line_size))
335  break;
336 
337  for (end_line=s->avctx->height; end_line > start_line; end_line--)
338  if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0],
339  s->previous_frame->data[0] + (end_line - 1) * s->previous_frame->linesize[0],
340  line_size))
341  break;
342  }
343 
344  bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later
345 
346  if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height)
347  bytestream_put_be16(&buf, 0); // header
348  else {
349  bytestream_put_be16(&buf, 8); // header
350  bytestream_put_be16(&buf, start_line); // starting line
351  bytestream_put_be16(&buf, 0); // unknown
352  bytestream_put_be16(&buf, end_line - start_line); // lines to update
353  bytestream_put_be16(&buf, 0); // unknown
354  }
355  for (i = start_line; i < end_line; i++)
356  qtrle_encode_line(s, p, i, &buf);
357 
358  bytestream_put_byte(&buf, 0); // zero skip code = frame finished
359  AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size
360  return buf - orig_buf;
361 }
362 
364  const AVFrame *pict, int *got_packet)
365 {
366  QtrleEncContext * const s = avctx->priv_data;
367  int ret;
368 
369  if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0)
370  return ret;
371 
372  if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
373  /* I-Frame */
374  s->key_frame = 1;
375  } else {
376  /* P-Frame */
377  s->key_frame = 0;
378  }
379 
380  pkt->size = encode_frame(s, pict, pkt->data);
381 
382  /* save the current frame */
384  ret = av_frame_ref(s->previous_frame, pict);
385  if (ret < 0) {
386  av_log(avctx, AV_LOG_ERROR, "cannot add reference\n");
387  return ret;
388  }
389 
390 #if FF_API_CODED_FRAME
392  avctx->coded_frame->key_frame = s->key_frame;
395 #endif
396 
397  if (s->key_frame)
398  pkt->flags |= AV_PKT_FLAG_KEY;
399  *got_packet = 1;
400 
401  return 0;
402 }
403 
405  .name = "qtrle",
406  .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
407  .type = AVMEDIA_TYPE_VIDEO,
408  .id = AV_CODEC_ID_QTRLE,
409  .priv_data_size = sizeof(QtrleEncContext),
411  .encode2 = qtrle_encode_frame,
412  .close = qtrle_encode_end,
413  .pix_fmts = (const enum AVPixelFormat[]){
415  },
416  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
417 };
#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:48
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
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: packet.h:356
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
Encode frame including header.
Definition: qtrleenc.c:322
static AVPacket pkt
AVCodec.
Definition: codec.h:190
static av_cold int qtrle_encode_end(AVCodecContext *avctx)
Definition: qtrleenc.c:66
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:32
uint8_t
#define av_cold
Definition: attributes.h:88
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
int logical_width
Definition: qtrleenc.c:42
AVCodecContext * avctx
Definition: qtrleenc.c:38
int key_frame
Encoded frame is a key frame.
Definition: qtrleenc.c:63
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:444
const char data[16]
Definition: mxf.c:91
uint8_t * data
Definition: packet.h:355
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 bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1750
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:388
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:188
#define MAX_RLE_BULK
Maximum RLE code for bulk copy.
Definition: qtrleenc.c:31
static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: qtrleenc.c:363
Definition: graph2dot.c:48
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
const char * name
Name of the codec implementation.
Definition: codec.h:197
#define MAX_RLE_SKIP
Maximum RLE code for skip.
Definition: qtrleenc.c:35
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:361
static av_cold int qtrle_encode_init(AVCodecContext *avctx)
Definition: qtrleenc.c:77
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:282
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:383
#define FFMIN(a, b)
Definition: common.h:96
#define width
int width
picture width / height.
Definition: avcodec.h:699
AVFrame * previous_frame
Definition: qtrleenc.c:40
#define s(width, name)
Definition: cbs_vp9.c:257
#define MAX_RLE_REPEAT
Maximum RLE code for repeat.
Definition: qtrleenc.c:33
unsigned int max_buf_size
Definition: qtrleenc.c:41
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
main external API structure.
Definition: avcodec.h:526
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:554
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:107
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
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
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:721
Y , 8bpp.
Definition: pixfmt.h:74
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
common internal api header.
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:1776
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:368
void * priv_data
Definition: avcodec.h:553
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
#define av_free(p)
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:85
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:378
#define av_uninit(x)
Definition: attributes.h:154
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:1217
AVCodec ff_qtrle_encoder
Definition: qtrleenc.c:404
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: packet.h:332
Predicted.
Definition: avutil.h:275
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
Definition: mem.c:190