FFmpeg  4.0
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 
263  this_line -= s->pixel_size;
264  prev_line -= s->pixel_size;
265  }
266 
267  /* Good! Now we have the best sequence for this line, let's output it. */
268 
269  /* We do a special case for the first pixel so that we avoid testing it in
270  * the whole loop */
271 
272  i=0;
273  this_line = p-> data[0] + line*p->linesize[0];
274 
275  if (s->rlecode_table[0] == 0) {
276  bytestream_put_byte(buf, s->skip_table[0] + 1);
277  i += s->skip_table[0];
278  }
279  else bytestream_put_byte(buf, 1);
280 
281 
282  while (i < width) {
283  rlecode = s->rlecode_table[i];
284  bytestream_put_byte(buf, rlecode);
285  if (rlecode == 0) {
286  /* Write a skip sequence */
287  bytestream_put_byte(buf, s->skip_table[i] + 1);
288  i += s->skip_table[i];
289  }
290  else if (rlecode > 0) {
291  /* bulk copy */
292  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
293  int j;
294  // QT grayscale colorspace has 0=white and 255=black, we will
295  // ignore the palette that is included in the AVFrame because
296  // AV_PIX_FMT_GRAY8 has defined color mapping
297  for (j = 0; j < rlecode*s->pixel_size; ++j)
298  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
299  } else {
300  bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
301  }
302  i += rlecode;
303  }
304  else {
305  /* repeat the bits */
306  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
307  int j;
308  // QT grayscale colorspace has 0=white and 255=black, ...
309  for (j = 0; j < s->pixel_size; ++j)
310  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
311  } else {
312  bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
313  }
314  i -= rlecode;
315  }
316  }
317  bytestream_put_byte(buf, -1); // end RLE line
318 }
319 
320 /** Encode frame including header */
322 {
323  int i;
324  int start_line = 0;
325  int end_line = s->avctx->height;
326  uint8_t *orig_buf = buf;
327 
328  if (!s->key_frame) {
329  unsigned line_size = s->logical_width * s->pixel_size;
330  for (start_line = 0; start_line < s->avctx->height; start_line++)
331  if (memcmp(p->data[0] + start_line*p->linesize[0],
332  s->previous_frame->data[0] + start_line * s->previous_frame->linesize[0],
333  line_size))
334  break;
335 
336  for (end_line=s->avctx->height; end_line > start_line; end_line--)
337  if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0],
338  s->previous_frame->data[0] + (end_line - 1) * s->previous_frame->linesize[0],
339  line_size))
340  break;
341  }
342 
343  bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later
344 
345  if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height)
346  bytestream_put_be16(&buf, 0); // header
347  else {
348  bytestream_put_be16(&buf, 8); // header
349  bytestream_put_be16(&buf, start_line); // starting line
350  bytestream_put_be16(&buf, 0); // unknown
351  bytestream_put_be16(&buf, end_line - start_line); // lines to update
352  bytestream_put_be16(&buf, 0); // unknown
353  }
354  for (i = start_line; i < end_line; i++)
355  qtrle_encode_line(s, p, i, &buf);
356 
357  bytestream_put_byte(&buf, 0); // zero skip code = frame finished
358  AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size
359  return buf - orig_buf;
360 }
361 
363  const AVFrame *pict, int *got_packet)
364 {
365  QtrleEncContext * const s = avctx->priv_data;
366  int ret;
367 
368  if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0)
369  return ret;
370 
371  if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
372  /* I-Frame */
373  s->key_frame = 1;
374  } else {
375  /* P-Frame */
376  s->key_frame = 0;
377  }
378 
379  pkt->size = encode_frame(s, pict, pkt->data);
380 
381  /* save the current frame */
383  ret = av_frame_ref(s->previous_frame, pict);
384  if (ret < 0) {
385  av_log(avctx, AV_LOG_ERROR, "cannot add reference\n");
386  return ret;
387  }
388 
389 #if FF_API_CODED_FRAME
391  avctx->coded_frame->key_frame = s->key_frame;
394 #endif
395 
396  if (s->key_frame)
397  pkt->flags |= AV_PKT_FLAG_KEY;
398  *got_packet = 1;
399 
400  return 0;
401 }
402 
404  .name = "qtrle",
405  .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
406  .type = AVMEDIA_TYPE_VIDEO,
407  .id = AV_CODEC_ID_QTRLE,
408  .priv_data_size = sizeof(QtrleEncContext),
410  .encode2 = qtrle_encode_frame,
411  .close = qtrle_encode_end,
412  .pix_fmts = (const enum AVPixelFormat[]){
414  },
415 };
const char * s
Definition: avisynth_c.h:768
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:218
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:64
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1431
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1727
static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
Encode frame including header.
Definition: qtrleenc.c:321
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3408
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:82
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
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:441
const char data[16]
Definition: mxf.c:90
uint8_t * data
Definition: avcodec.h:1430
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:2734
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1462
#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:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
#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:362
Definition: graph2dot.c:48
uint16_t width
Definition: gdv.c:47
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
const char * name
Name of the codec implementation.
Definition: avcodec.h:3415
#define MAX_RLE_SKIP
Maximum RLE code for skip.
Definition: qtrleenc.c:35
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:88
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1436
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:301
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1690
AVFrame * previous_frame
Definition: qtrleenc.c:40
#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:249
main external API structure.
Definition: avcodec.h:1518
void * buf
Definition: avisynth_c.h:690
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:551
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), big-endian , X=unused/undefined
Definition: pixfmt.h:103
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
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:1712
Y , 8bpp.
Definition: pixfmt.h:70
#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:2760
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:1545
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:296
#define av_uninit(x)
Definition: attributes.h:148
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2204
AVCodec ff_qtrle_encoder
Definition: qtrleenc.c:403
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1407
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:191