You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
13KB

  1. /*
  2. * innoHeim/Rsupport Screen Capture Codec
  3. * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * innoHeim/Rsupport Screen Capture Codec decoder
  24. *
  25. * Fourcc: ISCC, RSCC
  26. *
  27. * Lossless codec, data stored in tiles, with optional deflate compression.
  28. *
  29. * Header contains the number of tiles in a frame with the tile coordinates,
  30. * and it can be deflated or not. Similarly, pixel data comes after the header
  31. * and a variable size value, and it can be deflated or just raw.
  32. *
  33. * Supports: PAL8, BGRA, BGR24, RGB555
  34. */
  35. #include <stdint.h>
  36. #include <string.h>
  37. #include <zlib.h>
  38. #include "libavutil/imgutils.h"
  39. #include "libavutil/internal.h"
  40. #include "avcodec.h"
  41. #include "bytestream.h"
  42. #include "internal.h"
  43. #define TILE_SIZE 8
  44. typedef struct Tile {
  45. int x, y;
  46. int w, h;
  47. } Tile;
  48. typedef struct RsccContext {
  49. GetByteContext gbc;
  50. AVFrame *reference;
  51. Tile *tiles;
  52. unsigned int tiles_size;
  53. int component_size;
  54. uint8_t palette[AVPALETTE_SIZE];
  55. /* zlib interaction */
  56. uint8_t *inflated_buf;
  57. uLongf inflated_size;
  58. int valid_pixels;
  59. } RsccContext;
  60. static av_cold int rscc_init(AVCodecContext *avctx)
  61. {
  62. RsccContext *ctx = avctx->priv_data;
  63. /* These needs to be set to estimate uncompressed buffer */
  64. int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
  65. if (ret < 0) {
  66. av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
  67. avctx->width, avctx->height);
  68. return ret;
  69. }
  70. /* Allocate reference frame */
  71. ctx->reference = av_frame_alloc();
  72. if (!ctx->reference)
  73. return AVERROR(ENOMEM);
  74. /* Get pixel format and the size of the pixel */
  75. if (avctx->codec_tag == MKTAG('I', 'S', 'C', 'C')) {
  76. if (avctx->extradata && avctx->extradata_size == 4) {
  77. if ((avctx->extradata[0] >> 1) & 1) {
  78. avctx->pix_fmt = AV_PIX_FMT_BGRA;
  79. ctx->component_size = 4;
  80. } else {
  81. avctx->pix_fmt = AV_PIX_FMT_BGR24;
  82. ctx->component_size = 3;
  83. }
  84. } else {
  85. avctx->pix_fmt = AV_PIX_FMT_BGRA;
  86. ctx->component_size = 4;
  87. }
  88. } else if (avctx->codec_tag == MKTAG('R', 'S', 'C', 'C')) {
  89. ctx->component_size = avctx->bits_per_coded_sample / 8;
  90. switch (avctx->bits_per_coded_sample) {
  91. case 8:
  92. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  93. break;
  94. case 16:
  95. avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
  96. break;
  97. case 24:
  98. avctx->pix_fmt = AV_PIX_FMT_BGR24;
  99. break;
  100. case 32:
  101. avctx->pix_fmt = AV_PIX_FMT_BGR0;
  102. break;
  103. default:
  104. av_log(avctx, AV_LOG_ERROR, "Invalid bits per pixel value (%d)\n",
  105. avctx->bits_per_coded_sample);
  106. return AVERROR_INVALIDDATA;
  107. }
  108. } else {
  109. avctx->pix_fmt = AV_PIX_FMT_BGR0;
  110. ctx->component_size = 4;
  111. av_log(avctx, AV_LOG_WARNING, "Invalid codec tag\n");
  112. }
  113. /* Store the value to check for keyframes */
  114. ctx->inflated_size = avctx->width * avctx->height * ctx->component_size;
  115. /* Allocate maximum size possible, a full frame */
  116. ctx->inflated_buf = av_malloc(ctx->inflated_size);
  117. if (!ctx->inflated_buf)
  118. return AVERROR(ENOMEM);
  119. return 0;
  120. }
  121. static av_cold int rscc_close(AVCodecContext *avctx)
  122. {
  123. RsccContext *ctx = avctx->priv_data;
  124. av_freep(&ctx->tiles);
  125. av_freep(&ctx->inflated_buf);
  126. av_frame_free(&ctx->reference);
  127. return 0;
  128. }
  129. static int rscc_decode_frame(AVCodecContext *avctx, void *data,
  130. int *got_frame, AVPacket *avpkt)
  131. {
  132. RsccContext *ctx = avctx->priv_data;
  133. GetByteContext *gbc = &ctx->gbc;
  134. GetByteContext tiles_gbc;
  135. AVFrame *frame = data;
  136. const uint8_t *pixels, *raw;
  137. uint8_t *inflated_tiles = NULL;
  138. int tiles_nb, packed_size, pixel_size = 0;
  139. int i, ret = 0;
  140. bytestream2_init(gbc, avpkt->data, avpkt->size);
  141. /* Size check */
  142. if (bytestream2_get_bytes_left(gbc) < 12) {
  143. av_log(avctx, AV_LOG_ERROR, "Packet too small (%d)\n", avpkt->size);
  144. return AVERROR_INVALIDDATA;
  145. }
  146. /* Read number of tiles, and allocate the array */
  147. tiles_nb = bytestream2_get_le16(gbc);
  148. if (tiles_nb == 0) {
  149. av_log(avctx, AV_LOG_DEBUG, "no tiles\n");
  150. return avpkt->size;
  151. }
  152. av_fast_malloc(&ctx->tiles, &ctx->tiles_size,
  153. tiles_nb * sizeof(*ctx->tiles));
  154. if (!ctx->tiles) {
  155. ret = AVERROR(ENOMEM);
  156. goto end;
  157. }
  158. av_log(avctx, AV_LOG_DEBUG, "Frame with %d tiles.\n", tiles_nb);
  159. /* When there are more than 5 tiles, they are packed together with
  160. * a size header. When that size does not match the number of tiles
  161. * times the tile size, it means it needs to be inflated as well */
  162. if (tiles_nb > 5) {
  163. uLongf packed_tiles_size;
  164. if (tiles_nb < 32)
  165. packed_tiles_size = bytestream2_get_byte(gbc);
  166. else
  167. packed_tiles_size = bytestream2_get_le16(gbc);
  168. ff_dlog(avctx, "packed tiles of size %lu.\n", packed_tiles_size);
  169. /* If necessary, uncompress tiles, and hijack the bytestream reader */
  170. if (packed_tiles_size != tiles_nb * TILE_SIZE) {
  171. uLongf length = tiles_nb * TILE_SIZE;
  172. if (bytestream2_get_bytes_left(gbc) < packed_tiles_size) {
  173. ret = AVERROR_INVALIDDATA;
  174. goto end;
  175. }
  176. inflated_tiles = av_malloc(length);
  177. if (!inflated_tiles) {
  178. ret = AVERROR(ENOMEM);
  179. goto end;
  180. }
  181. ret = uncompress(inflated_tiles, &length,
  182. gbc->buffer, packed_tiles_size);
  183. if (ret) {
  184. av_log(avctx, AV_LOG_ERROR, "Tile deflate error %d.\n", ret);
  185. ret = AVERROR_UNKNOWN;
  186. goto end;
  187. }
  188. /* Skip the compressed tile section in the main byte reader,
  189. * and point it to read the newly uncompressed data */
  190. bytestream2_skip(gbc, packed_tiles_size);
  191. bytestream2_init(&tiles_gbc, inflated_tiles, length);
  192. gbc = &tiles_gbc;
  193. }
  194. }
  195. /* Fill in array of tiles, keeping track of how many pixels are updated */
  196. for (i = 0; i < tiles_nb; i++) {
  197. ctx->tiles[i].x = bytestream2_get_le16(gbc);
  198. ctx->tiles[i].w = bytestream2_get_le16(gbc);
  199. ctx->tiles[i].y = bytestream2_get_le16(gbc);
  200. ctx->tiles[i].h = bytestream2_get_le16(gbc);
  201. if (pixel_size + ctx->tiles[i].w * (int64_t)ctx->tiles[i].h * ctx->component_size > INT_MAX) {
  202. av_log(avctx, AV_LOG_ERROR, "Invalid tile dimensions\n");
  203. ret = AVERROR_INVALIDDATA;
  204. goto end;
  205. }
  206. pixel_size += ctx->tiles[i].w * ctx->tiles[i].h * ctx->component_size;
  207. ff_dlog(avctx, "tile %d orig(%d,%d) %dx%d.\n", i,
  208. ctx->tiles[i].x, ctx->tiles[i].y,
  209. ctx->tiles[i].w, ctx->tiles[i].h);
  210. if (ctx->tiles[i].w == 0 || ctx->tiles[i].h == 0) {
  211. av_log(avctx, AV_LOG_ERROR,
  212. "invalid tile %d at (%d.%d) with size %dx%d.\n", i,
  213. ctx->tiles[i].x, ctx->tiles[i].y,
  214. ctx->tiles[i].w, ctx->tiles[i].h);
  215. ret = AVERROR_INVALIDDATA;
  216. goto end;
  217. } else if (ctx->tiles[i].x + ctx->tiles[i].w > avctx->width ||
  218. ctx->tiles[i].y + ctx->tiles[i].h > avctx->height) {
  219. av_log(avctx, AV_LOG_ERROR,
  220. "out of bounds tile %d at (%d.%d) with size %dx%d.\n", i,
  221. ctx->tiles[i].x, ctx->tiles[i].y,
  222. ctx->tiles[i].w, ctx->tiles[i].h);
  223. ret = AVERROR_INVALIDDATA;
  224. goto end;
  225. }
  226. }
  227. /* Reset the reader in case it had been modified before */
  228. gbc = &ctx->gbc;
  229. /* Extract how much pixel data the tiles contain */
  230. if (pixel_size < 0x100)
  231. packed_size = bytestream2_get_byte(gbc);
  232. else if (pixel_size < 0x10000)
  233. packed_size = bytestream2_get_le16(gbc);
  234. else if (pixel_size < 0x1000000)
  235. packed_size = bytestream2_get_le24(gbc);
  236. else
  237. packed_size = bytestream2_get_le32(gbc);
  238. ff_dlog(avctx, "pixel_size %d packed_size %d.\n", pixel_size, packed_size);
  239. if (packed_size < 0) {
  240. av_log(avctx, AV_LOG_ERROR, "Invalid tile size %d\n", packed_size);
  241. ret = AVERROR_INVALIDDATA;
  242. goto end;
  243. }
  244. /* Get pixels buffer, it may be deflated or just raw */
  245. if (pixel_size == packed_size) {
  246. if (bytestream2_get_bytes_left(gbc) < pixel_size) {
  247. av_log(avctx, AV_LOG_ERROR, "Insufficient input for %d\n", pixel_size);
  248. ret = AVERROR_INVALIDDATA;
  249. goto end;
  250. }
  251. pixels = gbc->buffer;
  252. } else {
  253. uLongf len = ctx->inflated_size;
  254. if (bytestream2_get_bytes_left(gbc) < packed_size) {
  255. av_log(avctx, AV_LOG_ERROR, "Insufficient input for %d\n", packed_size);
  256. ret = AVERROR_INVALIDDATA;
  257. goto end;
  258. }
  259. ret = uncompress(ctx->inflated_buf, &len, gbc->buffer, packed_size);
  260. if (ret) {
  261. av_log(avctx, AV_LOG_ERROR, "Pixel deflate error %d.\n", ret);
  262. ret = AVERROR_UNKNOWN;
  263. goto end;
  264. }
  265. pixels = ctx->inflated_buf;
  266. }
  267. /* Allocate when needed */
  268. ret = ff_reget_buffer(avctx, ctx->reference, 0);
  269. if (ret < 0)
  270. goto end;
  271. /* Pointer to actual pixels, will be updated when data is consumed */
  272. raw = pixels;
  273. for (i = 0; i < tiles_nb; i++) {
  274. uint8_t *dst = ctx->reference->data[0] + ctx->reference->linesize[0] *
  275. (avctx->height - ctx->tiles[i].y - 1) +
  276. ctx->tiles[i].x * ctx->component_size;
  277. av_image_copy_plane(dst, -1 * ctx->reference->linesize[0],
  278. raw, ctx->tiles[i].w * ctx->component_size,
  279. ctx->tiles[i].w * ctx->component_size,
  280. ctx->tiles[i].h);
  281. raw += ctx->tiles[i].w * ctx->component_size * ctx->tiles[i].h;
  282. }
  283. /* Frame is ready to be output */
  284. ret = av_frame_ref(frame, ctx->reference);
  285. if (ret < 0)
  286. goto end;
  287. /* Keyframe when the number of pixels updated matches the whole surface */
  288. if (pixel_size == ctx->inflated_size) {
  289. frame->pict_type = AV_PICTURE_TYPE_I;
  290. frame->key_frame = 1;
  291. } else {
  292. frame->pict_type = AV_PICTURE_TYPE_P;
  293. }
  294. /* Palette handling */
  295. if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
  296. int size;
  297. const uint8_t *palette = av_packet_get_side_data(avpkt,
  298. AV_PKT_DATA_PALETTE,
  299. &size);
  300. if (palette && size == AVPALETTE_SIZE) {
  301. frame->palette_has_changed = 1;
  302. memcpy(ctx->palette, palette, AVPALETTE_SIZE);
  303. } else if (palette) {
  304. av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
  305. }
  306. memcpy (frame->data[1], ctx->palette, AVPALETTE_SIZE);
  307. }
  308. // We only return a picture when enough of it is undamaged, this avoids copying nearly broken frames around
  309. if (ctx->valid_pixels < ctx->inflated_size)
  310. ctx->valid_pixels += pixel_size;
  311. if (ctx->valid_pixels >= ctx->inflated_size * (100 - avctx->discard_damaged_percentage) / 100)
  312. *got_frame = 1;
  313. ret = avpkt->size;
  314. end:
  315. av_free(inflated_tiles);
  316. return ret;
  317. }
  318. AVCodec ff_rscc_decoder = {
  319. .name = "rscc",
  320. .long_name = NULL_IF_CONFIG_SMALL("innoHeim/Rsupport Screen Capture Codec"),
  321. .type = AVMEDIA_TYPE_VIDEO,
  322. .id = AV_CODEC_ID_RSCC,
  323. .init = rscc_init,
  324. .decode = rscc_decode_frame,
  325. .close = rscc_close,
  326. .priv_data_size = sizeof(RsccContext),
  327. .capabilities = AV_CODEC_CAP_DR1,
  328. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
  329. FF_CODEC_CAP_INIT_CLEANUP,
  330. };