Encodes frame including header */
| 237 | |
| 238 | /** Encodes frame including header */ |
| 239 | static int encode_frame(QtrleEncContext *s, AVFrame *p, uint8_t *buf) |
| 240 | { |
| 241 | int i; |
| 242 | int start_line = 0; |
| 243 | int end_line = s->avctx->height; |
| 244 | uint8_t *orig_buf = buf; |
| 245 | |
| 246 | if (!s->frame.key_frame) { |
| 247 | unsigned line_size = s->avctx->width * s->pixel_size; |
| 248 | for (start_line = 0; start_line < s->avctx->height; start_line++) |
| 249 | if (memcmp(p->data[0] + start_line*p->linesize[0], |
| 250 | s->previous_frame.data[0] + start_line*s->previous_frame.linesize[0], |
| 251 | line_size)) |
| 252 | break; |
| 253 | |
| 254 | for (end_line=s->avctx->height; end_line > start_line; end_line--) |
| 255 | if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0], |
| 256 | s->previous_frame.data[0] + (end_line - 1)*s->previous_frame.linesize[0], |
| 257 | line_size)) |
| 258 | break; |
| 259 | } |
| 260 | |
| 261 | bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later |
| 262 | |
| 263 | if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height) |
| 264 | bytestream_put_be16(&buf, 0); // header |
| 265 | else { |
| 266 | bytestream_put_be16(&buf, 8); // header |
| 267 | bytestream_put_be16(&buf, start_line); // starting line |
| 268 | bytestream_put_be16(&buf, 0); // unknown |
| 269 | bytestream_put_be16(&buf, end_line - start_line); // lines to update |
| 270 | bytestream_put_be16(&buf, 0); // unknown |
| 271 | } |
| 272 | for (i = start_line; i < end_line; i++) |
| 273 | qtrle_encode_line(s, p, i, &buf); |
| 274 | |
| 275 | bytestream_put_byte(&buf, 0); // zero skip code = frame finished |
| 276 | AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size |
| 277 | return buf - orig_buf; |
| 278 | } |
| 279 | |
| 280 | static int qtrle_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) |
| 281 | { |
no test coverage detected