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 {
42  unsigned int max_buf_size;
44  /**
45  * This array will contain at ith position the value of the best RLE code
46  * if the line started at pixel i
47  * There can be 3 values :
48  * skip (0) : skip as much as possible pixels because they are equal to the
49  * previous frame ones
50  * repeat (<-1) : repeat that pixel -rle_code times, still as much as
51  * possible
52  * copy (>0) : copy the raw next rle_code pixels */
53  signed char *rlecode_table;
54  /**
55  * This array will contain the length of the best rle encoding of the line
56  * starting at ith pixel */
58  /**
59  * Will contain at ith position the number of consecutive pixels equal to the previous
60  * frame starting from pixel i */
63 
65 {
66  QtrleEncContext *s = avctx->priv_data;
67  int ret;
68 
69  if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
70  return AVERROR(EINVAL);
71  }
72  s->avctx=avctx;
73  s->logical_width=avctx->width;
74 
75  switch (avctx->pix_fmt) {
76  case AV_PIX_FMT_GRAY8:
77  s->logical_width = avctx->width / 4;
78  s->pixel_size = 4;
79  break;
81  s->pixel_size = 2;
82  break;
83  case AV_PIX_FMT_RGB24:
84  s->pixel_size = 3;
85  break;
86  case AV_PIX_FMT_ARGB:
87  s->pixel_size = 4;
88  break;
89  default:
90  av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n");
91  break;
92  }
93  avctx->bits_per_coded_sample = avctx->pix_fmt == AV_PIX_FMT_GRAY8 ? 40 : s->pixel_size*8;
94 
97  s->length_table = av_mallocz((s->logical_width + 1)*sizeof(int));
98  if (!s->skip_table || !s->length_table || !s->rlecode_table) {
99  av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n");
100  return AVERROR(ENOMEM);
101  }
102  if ((ret = avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height)) < 0) {
103  av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n");
104  return ret;
105  }
106 
107  s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size*2 /* image base material */
108  + 15 /* header + footer */
109  + s->avctx->height*2 /* skip code+rle end */
110  + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */;
111  avctx->coded_frame = &s->frame;
112  return 0;
113 }
114 
115 /**
116  * Compute the best RLE sequence for a line
117  */
118 static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, uint8_t **buf)
119 {
120  int width=s->logical_width;
121  int i;
122  signed char rlecode;
123 
124  /* This will be the number of pixels equal to the preivous frame one's
125  * starting from the ith pixel */
126  unsigned int skipcount;
127  /* This will be the number of consecutive equal pixels in the current
128  * frame, starting from the ith one also */
129  unsigned int av_uninit(repeatcount);
130 
131  /* The cost of the three different possibilities */
132  int total_skip_cost;
133  int total_repeat_cost;
134 
135  int base_bulk_cost;
136  int lowest_bulk_cost;
137  int lowest_bulk_cost_index;
138  int sec_lowest_bulk_cost;
139  int sec_lowest_bulk_cost_index;
140 
141  uint8_t *this_line = p-> data[0] + line*p-> linesize[0] +
142  (width - 1)*s->pixel_size;
143  uint8_t *prev_line = s->previous_frame.data[0] + line*s->previous_frame.linesize[0] +
144  (width - 1)*s->pixel_size;
145 
146  s->length_table[width] = 0;
147  skipcount = 0;
148 
149  /* Initial values */
150  lowest_bulk_cost = INT_MAX / 2;
151  lowest_bulk_cost_index = width;
152  sec_lowest_bulk_cost = INT_MAX / 2;
153  sec_lowest_bulk_cost_index = width;
154 
155  base_bulk_cost = 1 + s->pixel_size;
156 
157  for (i = width - 1; i >= 0; i--) {
158 
159  int prev_bulk_cost;
160 
161  /* If our lowest bulk cost index is too far away, replace it
162  * with the next lowest bulk cost */
163  if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) {
164  lowest_bulk_cost = sec_lowest_bulk_cost;
165  lowest_bulk_cost_index = sec_lowest_bulk_cost_index;
166 
167  sec_lowest_bulk_cost = INT_MAX / 2;
168  sec_lowest_bulk_cost_index = width;
169  }
170 
171  /* Deal with the first pixel's bulk cost */
172  if (!i) {
173  base_bulk_cost++;
174  lowest_bulk_cost++;
175  sec_lowest_bulk_cost++;
176  }
177 
178  /* Look at the bulk cost of the previous loop and see if it is
179  * a new lower bulk cost */
180  prev_bulk_cost = s->length_table[i + 1] + base_bulk_cost;
181  if (prev_bulk_cost <= sec_lowest_bulk_cost) {
182  /* If it's lower than the 2nd lowest, then it may be lower
183  * than the lowest */
184  if (prev_bulk_cost <= lowest_bulk_cost) {
185 
186  /* If we have found a new lowest bulk cost,
187  * then the 2nd lowest bulk cost is now farther than the
188  * lowest bulk cost, and will never be used */
189  sec_lowest_bulk_cost = INT_MAX / 2;
190 
191  lowest_bulk_cost = prev_bulk_cost;
192  lowest_bulk_cost_index = i + 1;
193  } else {
194  /* Then it must be the 2nd lowest bulk cost */
195  sec_lowest_bulk_cost = prev_bulk_cost;
196  sec_lowest_bulk_cost_index = i + 1;
197  }
198  }
199 
200  if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size))
201  skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
202  else
203  skipcount = 0;
204 
205  total_skip_cost = s->length_table[i + skipcount] + 2;
206  s->skip_table[i] = skipcount;
207 
208 
209  if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size))
210  repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT);
211  else
212  repeatcount = 1;
213 
214  total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size;
215 
216  /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy
217  * so let's make it aware */
218  if (i == 0) {
219  total_skip_cost--;
220  total_repeat_cost++;
221  }
222 
223  if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) {
224  /* repeat is the best */
225  s->length_table[i] = total_repeat_cost;
226  s->rlecode_table[i] = -repeatcount;
227  }
228  else if (skipcount > 0) {
229  /* skip is the best choice here */
230  s->length_table[i] = total_skip_cost;
231  s->rlecode_table[i] = 0;
232  }
233  else {
234  /* We cannot do neither skip nor repeat
235  * thus we use the best bulk copy */
236 
237  s->length_table[i] = lowest_bulk_cost;
238  s->rlecode_table[i] = lowest_bulk_cost_index - i;
239 
240  }
241 
242  /* These bulk costs increase every iteration */
243  lowest_bulk_cost += s->pixel_size;
244  sec_lowest_bulk_cost += s->pixel_size;
245 
246  this_line -= s->pixel_size;
247  prev_line -= s->pixel_size;
248  }
249 
250  /* Good ! Now we have the best sequence for this line, let's output it */
251 
252  /* We do a special case for the first pixel so that we avoid testing it in
253  * the whole loop */
254 
255  i=0;
256  this_line = p-> data[0] + line*p->linesize[0];
257 
258  if (s->rlecode_table[0] == 0) {
259  bytestream_put_byte(buf, s->skip_table[0] + 1);
260  i += s->skip_table[0];
261  }
262  else bytestream_put_byte(buf, 1);
263 
264 
265  while (i < width) {
266  rlecode = s->rlecode_table[i];
267  bytestream_put_byte(buf, rlecode);
268  if (rlecode == 0) {
269  /* Write a skip sequence */
270  bytestream_put_byte(buf, s->skip_table[i] + 1);
271  i += s->skip_table[i];
272  }
273  else if (rlecode > 0) {
274  /* bulk copy */
275  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
276  int j;
277  // QT grayscale colorspace has 0=white and 255=black, we will
278  // ignore the palette that is included in the AVFrame because
279  // AV_PIX_FMT_GRAY8 has defined color mapping
280  for (j = 0; j < rlecode*s->pixel_size; ++j)
281  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
282  } else {
283  bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
284  }
285  i += rlecode;
286  }
287  else {
288  /* repeat the bits */
289  if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
290  int j;
291  // QT grayscale colorspace has 0=white and 255=black, ...
292  for (j = 0; j < s->pixel_size; ++j)
293  bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
294  } else {
295  bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
296  }
297  i -= rlecode;
298  }
299  }
300  bytestream_put_byte(buf, -1); // end RLE line
301 }
302 
303 /** Encode frame including header */
305 {
306  int i;
307  int start_line = 0;
308  int end_line = s->avctx->height;
309  uint8_t *orig_buf = buf;
310 
311  if (!s->frame.key_frame) {
312  unsigned line_size = s->logical_width * s->pixel_size;
313  for (start_line = 0; start_line < s->avctx->height; start_line++)
314  if (memcmp(p->data[0] + start_line*p->linesize[0],
315  s->previous_frame.data[0] + start_line*s->previous_frame.linesize[0],
316  line_size))
317  break;
318 
319  for (end_line=s->avctx->height; end_line > start_line; end_line--)
320  if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0],
321  s->previous_frame.data[0] + (end_line - 1)*s->previous_frame.linesize[0],
322  line_size))
323  break;
324  }
325 
326  bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later
327 
328  if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height)
329  bytestream_put_be16(&buf, 0); // header
330  else {
331  bytestream_put_be16(&buf, 8); // header
332  bytestream_put_be16(&buf, start_line); // starting line
333  bytestream_put_be16(&buf, 0); // unknown
334  bytestream_put_be16(&buf, end_line - start_line); // lines to update
335  bytestream_put_be16(&buf, 0); // unknown
336  }
337  for (i = start_line; i < end_line; i++)
338  qtrle_encode_line(s, p, i, &buf);
339 
340  bytestream_put_byte(&buf, 0); // zero skip code = frame finished
341  AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size
342  return buf - orig_buf;
343 }
344 
346  const AVFrame *pict, int *got_packet)
347 {
348  QtrleEncContext * const s = avctx->priv_data;
349  AVFrame * const p = &s->frame;
350  int ret;
351 
352  *p = *pict;
353 
354  if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size)) < 0)
355  return ret;
356 
357  if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
358  /* I-Frame */
360  p->key_frame = 1;
361  } else {
362  /* P-Frame */
364  p->key_frame = 0;
365  }
366 
367  pkt->size = encode_frame(s, pict, pkt->data);
368 
369  /* save the current frame */
370  av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height);
371 
372  if (p->key_frame)
373  pkt->flags |= AV_PKT_FLAG_KEY;
374  *got_packet = 1;
375 
376  return 0;
377 }
378 
380 {
381  QtrleEncContext *s = avctx->priv_data;
382 
385  av_free(s->length_table);
386  av_free(s->skip_table);
387  return 0;
388 }
389 
391  .name = "qtrle",
392  .type = AVMEDIA_TYPE_VIDEO,
393  .id = AV_CODEC_ID_QTRLE,
394  .priv_data_size = sizeof(QtrleEncContext),
396  .encode2 = qtrle_encode_frame,
398  .pix_fmts = (const enum AVPixelFormat[]){
400  },
401  .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
402 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
AVFrame frame
Definition: qtrleenc.c:39
int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
int * length_table
This array will contain the length of the best rle encoding of the line starting at ith pixel...
Definition: qtrleenc.c:57
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
AVFrame * coded_frame
the picture in the bitstream
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
Encode frame including header.
Definition: qtrleenc.c:304
four components are given, that&#39;s all.
static av_cold int qtrle_encode_end(AVCodecContext *avctx)
Definition: qtrleenc.c:379
void av_picture_copy(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height)
Copy image src to dst.
Definition: avpicture.c:72
#define AV_WB32(p, darg)
Definition: intreadwrite.h:265
uint8_t
#define av_cold
Definition: attributes.h:78
int logical_width
Definition: qtrleenc.c:43
uint8_t * data[AV_NUM_DATA_POINTERS]
AVCodecContext * avctx
Definition: qtrleenc.c:38
static AVPacket pkt
Definition: demuxing.c:56
uint8_t * data
uint8_t * skip_table
Will contain at ith position the number of consecutive pixels equal to the previous frame starting fr...
Definition: qtrleenc.c:61
AVPicture previous_frame
Definition: qtrleenc.c:41
void avpicture_free(AVPicture *picture)
Free a picture previously allocated by avpicture_alloc().
Definition: avpicture.c:67
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define MAX_RLE_BULK
Maximum RLE code for bulk copy.
Definition: qtrleenc.c:31
Spectrum Plot time data
static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: qtrleenc.c:345
Definition: graph2dot.c:48
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
#define MAX_RLE_SKIP
Maximum RLE code for skip.
Definition: qtrleenc.c:35
external API header
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:96
int flags
A combination of AV_PKT_FLAG values.
static av_cold int qtrle_encode_init(AVCodecContext *avctx)
Definition: qtrleenc.c:64
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:231
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
int width
picture width / height.
struct QtrleEncContext QtrleEncContext
#define MAX_RLE_REPEAT
Maximum RLE code for repeat.
Definition: qtrleenc.c:33
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
unsigned int max_buf_size
Definition: qtrleenc.c:42
static int width
Definition: tests/utils.c:158
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height)
Allocate memory for a picture.
Definition: avpicture.c:54
synthesis window for stochastic i
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:116
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
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:118
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Y , 8bpp.
Definition: pixfmt.h:76
common internal api header.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
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:53
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
#define av_uninit(x)
Definition: attributes.h:137
int frame_number
Frame counter, set by libavcodec.
AVCodec ff_qtrle_encoder
Definition: qtrleenc.c:390
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
This structure stores compressed data.
Predicted.
Definition: avutil.h:217