FFmpeg
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 */
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 };
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:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
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: avcodec.h:1483
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1780
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
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: avcodec.h:3494
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:443
uint8_t * data
Definition: avcodec.h:1482
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:2794
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1514
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:363
Definition: graph2dot.c:48
const char * name
Name of the codec implementation.
Definition: avcodec.h:3501
#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: avcodec.h:1488
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:378
#define FFMIN(a, b)
Definition: common.h:96
#define width
int width
picture width / height.
Definition: avcodec.h:1743
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:326
main external API structure.
Definition: avcodec.h:1570
void * buf
Definition: avisynth_c.h:766
#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:553
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:309
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:1765
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:2820
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:1597
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:373
#define av_uninit(x)
Definition: attributes.h:148
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2261
AVCodec ff_qtrle_encoder
Definition: qtrleenc.c:404
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
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1459
Predicted.
Definition: avutil.h:275
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191