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 "codec_internal.h" 29#include "encode.h" 30 31/** Maximum RLE code for bulk copy */ 32#define MAX_RLE_BULK 127 33/** Maximum RLE code for repeat */ 34#define MAX_RLE_REPEAT 128 35/** Maximum RLE code for skip */ 36#define MAX_RLE_SKIP 254 37 38typedef struct QtrleEncContext { 39 AVCodecContext *avctx; 40 int pixel_size; 41 AVFrame *previous_frame; 42 unsigned int max_buf_size; 43 int logical_width; 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 */ 57 int *length_table; 58 /** 59 * Will contain at ith position the number of consecutive pixels equal to the previous 60 * frame starting from pixel i */ 61 uint8_t* skip_table; 62 63 /** Encoded frame is a key frame */ 64 int key_frame; 65} QtrleEncContext; 66 67static av_cold int qtrle_encode_end(AVCodecContext *avctx) 68{ 69 QtrleEncContext *s = avctx->priv_data; 70 71 av_frame_free(&s->previous_frame); 72 av_free(s->rlecode_table); 73 av_free(s->length_table); 74 av_free(s->skip_table); 75 return 0; 76} 77 78static av_cold int qtrle_encode_init(AVCodecContext *avctx) 79{ 80 QtrleEncContext *s = avctx->priv_data; 81 82 if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) { 83 return AVERROR(EINVAL); 84 } 85 s->avctx=avctx; 86 s->logical_width=avctx->width; 87 88 switch (avctx->pix_fmt) { 89 case AV_PIX_FMT_GRAY8: 90 if (avctx->width % 4) { 91 av_log(avctx, AV_LOG_ERROR, "Width not being a multiple of 4 is not supported\n"); 92 return AVERROR(EINVAL); 93 } 94 s->logical_width = avctx->width / 4; 95 s->pixel_size = 4; 96 break; 97 case AV_PIX_FMT_RGB555BE: 98 s->pixel_size = 2; 99 break; 100 case AV_PIX_FMT_RGB24: 101 s->pixel_size = 3; 102 break; 103 case AV_PIX_FMT_ARGB: 104 s->pixel_size = 4; 105 break; 106 default: 107 av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n"); 108 break; 109 } 110 avctx->bits_per_coded_sample = avctx->pix_fmt == AV_PIX_FMT_GRAY8 ? 40 : s->pixel_size*8; 111 112 s->rlecode_table = av_mallocz(s->logical_width); 113 s->skip_table = av_mallocz(s->logical_width); 114 s->length_table = av_calloc(s->logical_width + 1, sizeof(*s->length_table)); 115 if (!s->skip_table || !s->length_table || !s->rlecode_table) { 116 av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n"); 117 return AVERROR(ENOMEM); 118 } 119 s->previous_frame = av_frame_alloc(); 120 if (!s->previous_frame) { 121 av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n"); 122 return AVERROR(ENOMEM); 123 } 124 125 s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size*2 /* image base material */ 126 + 15 /* header + footer */ 127 + s->avctx->height*2 /* skip code+rle end */ 128 + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */; 129 130 return 0; 131} 132 133/** 134 * Compute the best RLE sequence for a line 135 */ 136static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, uint8_t **buf) 137{ 138 int width=s->logical_width; 139 int i; 140 signed char rlecode; 141 142 /* This will be the number of pixels equal to the previous frame one's 143 * starting from the ith pixel */ 144 unsigned int skipcount; 145 /* This will be the number of consecutive equal pixels in the current 146 * frame, starting from the ith one also */ 147 unsigned int av_uninit(repeatcount); 148 149 /* The cost of the three different possibilities */ 150 int total_skip_cost; 151 int total_repeat_cost; 152 153 int base_bulk_cost; 154 int lowest_bulk_cost; 155 int lowest_bulk_cost_index; 156 int sec_lowest_bulk_cost; 157 int sec_lowest_bulk_cost_index; 158 159 const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size; 160 /* There might be no earlier frame if the current frame is a keyframe. 161 * So just use a pointer to the current frame to avoid a check 162 * to avoid NULL - s->pixel_size (which is undefined behaviour). */ 163 const uint8_t *prev_line = s->key_frame ? this_line 164 : s->previous_frame->data[0] 165 + line * s->previous_frame->linesize[0] 166 + width * s->pixel_size; 167 168 s->length_table[width] = 0; 169 skipcount = 0; 170 171 /* Initial values */ 172 lowest_bulk_cost = INT_MAX / 2; 173 lowest_bulk_cost_index = width; 174 sec_lowest_bulk_cost = INT_MAX / 2; 175 sec_lowest_bulk_cost_index = width; 176 177 base_bulk_cost = 1 + s->pixel_size; 178 179 for (i = width - 1; i >= 0; i--) { 180 181 int prev_bulk_cost; 182 183 this_line -= s->pixel_size; 184 prev_line -= s->pixel_size; 185 186 /* If our lowest bulk cost index is too far away, replace it 187 * with the next lowest bulk cost */ 188 if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) { 189 lowest_bulk_cost = sec_lowest_bulk_cost; 190 lowest_bulk_cost_index = sec_lowest_bulk_cost_index; 191 192 sec_lowest_bulk_cost = INT_MAX / 2; 193 sec_lowest_bulk_cost_index = width; 194 } 195 196 /* Deal with the first pixel's bulk cost */ 197 if (!i) { 198 base_bulk_cost++; 199 lowest_bulk_cost++; 200 sec_lowest_bulk_cost++; 201 } 202 203 /* Look at the bulk cost of the previous loop and see if it is 204 * a new lower bulk cost */ 205 prev_bulk_cost = s->length_table[i + 1] + base_bulk_cost; 206 if (prev_bulk_cost <= sec_lowest_bulk_cost) { 207 /* If it's lower than the 2nd lowest, then it may be lower 208 * than the lowest */ 209 if (prev_bulk_cost <= lowest_bulk_cost) { 210 211 /* If we have found a new lowest bulk cost, 212 * then the 2nd lowest bulk cost is now farther than the 213 * lowest bulk cost, and will never be used */ 214 sec_lowest_bulk_cost = INT_MAX / 2; 215 216 lowest_bulk_cost = prev_bulk_cost; 217 lowest_bulk_cost_index = i + 1; 218 } else { 219 /* Then it must be the 2nd lowest bulk cost */ 220 sec_lowest_bulk_cost = prev_bulk_cost; 221 sec_lowest_bulk_cost_index = i + 1; 222 } 223 } 224 225 if (!s->key_frame && !memcmp(this_line, prev_line, s->pixel_size)) 226 skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP); 227 else 228 skipcount = 0; 229 230 total_skip_cost = s->length_table[i + skipcount] + 2; 231 s->skip_table[i] = skipcount; 232 233 234 if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size)) 235 repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT); 236 else 237 repeatcount = 1; 238 239 total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size; 240 241 /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy 242 * so let's make it aware */ 243 if (i == 0) { 244 total_skip_cost--; 245 total_repeat_cost++; 246 } 247 248 if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) { 249 /* repeat is the best */ 250 s->length_table[i] = total_repeat_cost; 251 s->rlecode_table[i] = -repeatcount; 252 } 253 else if (skipcount > 0) { 254 /* skip is the best choice here */ 255 s->length_table[i] = total_skip_cost; 256 s->rlecode_table[i] = 0; 257 } 258 else { 259 /* We cannot do neither skip nor repeat 260 * thus we use the best bulk copy */ 261 262 s->length_table[i] = lowest_bulk_cost; 263 s->rlecode_table[i] = lowest_bulk_cost_index - i; 264 265 } 266 267 /* These bulk costs increase every iteration */ 268 lowest_bulk_cost += s->pixel_size; 269 sec_lowest_bulk_cost += s->pixel_size; 270 } 271 272 /* Good! Now we have the best sequence for this line, let's output it. */ 273 274 /* We do a special case for the first pixel so that we avoid testing it in 275 * the whole loop */ 276 277 i=0; 278 this_line = p-> data[0] + line*p->linesize[0]; 279 280 if (s->rlecode_table[0] == 0) { 281 bytestream_put_byte(buf, s->skip_table[0] + 1); 282 i += s->skip_table[0]; 283 } 284 else bytestream_put_byte(buf, 1); 285 286 287 while (i < width) { 288 rlecode = s->rlecode_table[i]; 289 bytestream_put_byte(buf, rlecode); 290 if (rlecode == 0) { 291 /* Write a skip sequence */ 292 bytestream_put_byte(buf, s->skip_table[i] + 1); 293 i += s->skip_table[i]; 294 } 295 else if (rlecode > 0) { 296 /* bulk copy */ 297 if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) { 298 int j; 299 // QT grayscale colorspace has 0=white and 255=black, we will 300 // ignore the palette that is included in the AVFrame because 301 // AV_PIX_FMT_GRAY8 has defined color mapping 302 for (j = 0; j < rlecode*s->pixel_size; ++j) 303 bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff); 304 } else { 305 bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size); 306 } 307 i += rlecode; 308 } 309 else { 310 /* repeat the bits */ 311 if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) { 312 int j; 313 // QT grayscale colorspace has 0=white and 255=black, ... 314 for (j = 0; j < s->pixel_size; ++j) 315 bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff); 316 } else { 317 bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size); 318 } 319 i -= rlecode; 320 } 321 } 322 bytestream_put_byte(buf, -1); // end RLE line 323} 324 325/** Encode frame including header */ 326static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf) 327{ 328 int i; 329 int start_line = 0; 330 int end_line = s->avctx->height; 331 uint8_t *orig_buf = buf; 332 333 if (!s->key_frame) { 334 unsigned line_size = s->logical_width * s->pixel_size; 335 for (start_line = 0; start_line < s->avctx->height; start_line++) 336 if (memcmp(p->data[0] + start_line*p->linesize[0], 337 s->previous_frame->data[0] + start_line * s->previous_frame->linesize[0], 338 line_size)) 339 break; 340 341 for (end_line=s->avctx->height; end_line > start_line; end_line--) 342 if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0], 343 s->previous_frame->data[0] + (end_line - 1) * s->previous_frame->linesize[0], 344 line_size)) 345 break; 346 } 347 348 bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later 349 350 if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height) 351 bytestream_put_be16(&buf, 0); // header 352 else { 353 bytestream_put_be16(&buf, 8); // header 354 bytestream_put_be16(&buf, start_line); // starting line 355 bytestream_put_be16(&buf, 0); // unknown 356 bytestream_put_be16(&buf, end_line - start_line); // lines to update 357 bytestream_put_be16(&buf, 0); // unknown 358 } 359 for (i = start_line; i < end_line; i++) 360 qtrle_encode_line(s, p, i, &buf); 361 362 bytestream_put_byte(&buf, 0); // zero skip code = frame finished 363 AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size 364 return buf - orig_buf; 365} 366 367static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 368 const AVFrame *pict, int *got_packet) 369{ 370 QtrleEncContext * const s = avctx->priv_data; 371 int ret; 372 373 if ((ret = ff_alloc_packet(avctx, pkt, s->max_buf_size)) < 0) 374 return ret; 375 376 if (avctx->gop_size == 0 || !s->previous_frame->data[0] || 377 (s->avctx->frame_number % avctx->gop_size) == 0) { 378 /* I-Frame */ 379 s->key_frame = 1; 380 } else { 381 /* P-Frame */ 382 s->key_frame = 0; 383 } 384 385 pkt->size = encode_frame(s, pict, pkt->data); 386 387 /* save the current frame */ 388 av_frame_unref(s->previous_frame); 389 ret = av_frame_ref(s->previous_frame, pict); 390 if (ret < 0) { 391 av_log(avctx, AV_LOG_ERROR, "cannot add reference\n"); 392 return ret; 393 } 394 395 if (s->key_frame) 396 pkt->flags |= AV_PKT_FLAG_KEY; 397 *got_packet = 1; 398 399 return 0; 400} 401 402const FFCodec ff_qtrle_encoder = { 403 .p.name = "qtrle", 404 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), 405 .p.type = AVMEDIA_TYPE_VIDEO, 406 .p.id = AV_CODEC_ID_QTRLE, 407 .priv_data_size = sizeof(QtrleEncContext), 408 .init = qtrle_encode_init, 409 FF_CODEC_ENCODE_CB(qtrle_encode_frame), 410 .close = qtrle_encode_end, 411 .p.pix_fmts = (const enum AVPixelFormat[]){ 412 AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE 413 }, 414 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 415}; 416