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.

642 lines
22KB

  1. /*
  2. * FM Screen Capture Codec decoder
  3. *
  4. * Copyright (c) 2017 Paul B Mahol
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "avcodec.h"
  26. #include "bytestream.h"
  27. #include "internal.h"
  28. #define BLOCK_HEIGHT 112u
  29. #define BLOCK_WIDTH 84u
  30. typedef struct InterBlock {
  31. int w, h;
  32. int size;
  33. int xor;
  34. } InterBlock;
  35. typedef struct FMVCContext {
  36. GetByteContext gb;
  37. PutByteContext pb;
  38. uint8_t *buffer;
  39. size_t buffer_size;
  40. uint8_t *pbuffer;
  41. size_t pbuffer_size;
  42. ptrdiff_t stride;
  43. int bpp;
  44. int yb, xb;
  45. InterBlock *blocks;
  46. unsigned nb_blocks;
  47. } FMVCContext;
  48. static int decode_type2(GetByteContext *gb, PutByteContext *pb)
  49. {
  50. unsigned repeat = 0, first = 1, opcode = 0;
  51. int i, len, pos;
  52. while (bytestream2_get_bytes_left(gb) > 0) {
  53. GetByteContext gbc;
  54. while (bytestream2_get_bytes_left(gb) > 0) {
  55. if (first) {
  56. first = 0;
  57. if (bytestream2_peek_byte(gb) > 17) {
  58. len = bytestream2_get_byte(gb) - 17;
  59. if (len < 4) {
  60. do {
  61. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  62. --len;
  63. } while (len);
  64. opcode = bytestream2_peek_byte(gb);
  65. continue;
  66. } else {
  67. do {
  68. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  69. --len;
  70. } while (len);
  71. opcode = bytestream2_peek_byte(gb);
  72. if (opcode < 0x10) {
  73. bytestream2_skip(gb, 1);
  74. pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;
  75. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  76. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  77. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  78. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  79. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  80. len = opcode & 3;
  81. if (!len) {
  82. repeat = 1;
  83. } else {
  84. do {
  85. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  86. --len;
  87. } while (len);
  88. opcode = bytestream2_peek_byte(gb);
  89. }
  90. continue;
  91. }
  92. }
  93. repeat = 0;
  94. }
  95. repeat = 1;
  96. }
  97. if (repeat) {
  98. repeat = 0;
  99. opcode = bytestream2_peek_byte(gb);
  100. if (opcode < 0x10) {
  101. bytestream2_skip(gb, 1);
  102. if (!opcode) {
  103. if (!bytestream2_peek_byte(gb)) {
  104. do {
  105. bytestream2_skip(gb, 1);
  106. opcode += 255;
  107. } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
  108. }
  109. opcode += bytestream2_get_byte(gb) + 15;
  110. }
  111. bytestream2_put_le32(pb, bytestream2_get_le32(gb));
  112. for (i = opcode - 1; i > 0; --i)
  113. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  114. opcode = bytestream2_peek_byte(gb);
  115. if (opcode < 0x10) {
  116. bytestream2_skip(gb, 1);
  117. pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;
  118. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  119. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  120. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  121. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  122. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  123. len = opcode & 3;
  124. if (!len) {
  125. repeat = 1;
  126. } else {
  127. do {
  128. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  129. --len;
  130. } while (len);
  131. opcode = bytestream2_peek_byte(gb);
  132. }
  133. continue;
  134. }
  135. }
  136. }
  137. if (opcode >= 0x40) {
  138. bytestream2_skip(gb, 1);
  139. pos = - ((opcode >> 2) & 7) - 1 - 8 * bytestream2_get_byte(gb);
  140. len = (opcode >> 5) - 1;
  141. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  142. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  143. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  144. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  145. do {
  146. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  147. --len;
  148. } while (len);
  149. len = opcode & 3;
  150. if (!len) {
  151. repeat = 1;
  152. } else {
  153. do {
  154. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  155. --len;
  156. } while (len);
  157. opcode = bytestream2_peek_byte(gb);
  158. }
  159. continue;
  160. } else if (opcode < 0x20) {
  161. break;
  162. }
  163. len = opcode & 0x1F;
  164. bytestream2_skip(gb, 1);
  165. if (!len) {
  166. if (!bytestream2_peek_byte(gb)) {
  167. do {
  168. bytestream2_skip(gb, 1);
  169. len += 255;
  170. } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
  171. }
  172. len += bytestream2_get_byte(gb) + 31;
  173. }
  174. i = bytestream2_get_le16(gb);
  175. pos = - (i >> 2) - 1;
  176. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  177. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  178. if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
  179. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  180. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  181. do {
  182. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  183. --len;
  184. } while (len);
  185. } else {
  186. bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
  187. for (len = len - 2; len; --len)
  188. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  189. }
  190. len = i & 3;
  191. if (!len) {
  192. repeat = 1;
  193. } else {
  194. do {
  195. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  196. --len;
  197. } while (len);
  198. opcode = bytestream2_peek_byte(gb);
  199. }
  200. }
  201. bytestream2_skip(gb, 1);
  202. if (opcode < 0x10) {
  203. pos = -(opcode >> 2) - 1 - 4 * bytestream2_get_byte(gb);
  204. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  205. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  206. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  207. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  208. len = opcode & 3;
  209. if (!len) {
  210. repeat = 1;
  211. } else {
  212. do {
  213. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  214. --len;
  215. } while (len);
  216. opcode = bytestream2_peek_byte(gb);
  217. }
  218. continue;
  219. }
  220. len = opcode & 7;
  221. if (!len) {
  222. if (!bytestream2_peek_byte(gb)) {
  223. do {
  224. bytestream2_skip(gb, 1);
  225. len += 255;
  226. } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
  227. }
  228. len += bytestream2_get_byte(gb) + 7;
  229. }
  230. i = bytestream2_get_le16(gb);
  231. pos = bytestream2_tell_p(pb) - 2048 * (opcode & 8);
  232. pos = pos - (i >> 2);
  233. if (pos == bytestream2_tell_p(pb))
  234. break;
  235. pos = pos - 0x4000;
  236. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  237. bytestream2_seek(&gbc, pos, SEEK_SET);
  238. if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
  239. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  240. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  241. do {
  242. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  243. --len;
  244. } while (len);
  245. } else {
  246. bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
  247. for (len = len - 2; len; --len)
  248. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  249. }
  250. len = i & 3;
  251. if (!len) {
  252. repeat = 1;
  253. } else {
  254. do {
  255. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  256. --len;
  257. } while (len);
  258. opcode = bytestream2_peek_byte(gb);
  259. }
  260. }
  261. return 0;
  262. }
  263. static int decode_type1(GetByteContext *gb, PutByteContext *pb)
  264. {
  265. unsigned opcode = 0, len;
  266. int high = 0;
  267. int i, pos;
  268. while (bytestream2_get_bytes_left(gb) > 0) {
  269. GetByteContext gbc;
  270. while (bytestream2_get_bytes_left(gb) > 0) {
  271. while (bytestream2_get_bytes_left(gb) > 0) {
  272. opcode = bytestream2_get_byte(gb);
  273. high = opcode >= 0x20;
  274. if (high)
  275. break;
  276. if (opcode)
  277. break;
  278. opcode = bytestream2_get_byte(gb);
  279. if (opcode < 0xF8) {
  280. opcode += 32;
  281. break;
  282. }
  283. i = opcode - 0xF8;
  284. if (i) {
  285. len = 256;
  286. do {
  287. len *= 2;
  288. --i;
  289. } while (i);
  290. } else {
  291. len = 280;
  292. }
  293. do {
  294. bytestream2_put_le32(pb, bytestream2_get_le32(gb));
  295. bytestream2_put_le32(pb, bytestream2_get_le32(gb));
  296. len -= 8;
  297. } while (len && bytestream2_get_bytes_left(gb) > 0);
  298. }
  299. if (!high) {
  300. do {
  301. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  302. --opcode;
  303. } while (opcode && bytestream2_get_bytes_left(gb) > 0);
  304. while (bytestream2_get_bytes_left(gb) > 0) {
  305. GetByteContext gbc;
  306. opcode = bytestream2_get_byte(gb);
  307. if (opcode >= 0x20)
  308. break;
  309. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  310. pos = -(opcode | 32 * bytestream2_get_byte(gb)) - 1;
  311. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  312. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  313. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  314. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  315. bytestream2_put_byte(pb, bytestream2_get_byte(gb));
  316. }
  317. }
  318. high = 0;
  319. if (opcode < 0x40)
  320. break;
  321. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  322. pos = (-((opcode & 0x1F) | 32 * bytestream2_get_byte(gb)) - 1);
  323. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);
  324. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  325. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  326. len = (opcode >> 5) - 1;
  327. do {
  328. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  329. --len;
  330. } while (len && bytestream2_get_bytes_left(&gbc) > 0);
  331. }
  332. len = opcode & 0x1F;
  333. if (!len) {
  334. if (!bytestream2_peek_byte(gb)) {
  335. do {
  336. bytestream2_skip(gb, 1);
  337. len += 255;
  338. } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);
  339. }
  340. len += bytestream2_get_byte(gb) + 31;
  341. }
  342. pos = -bytestream2_get_byte(gb);
  343. bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);
  344. bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos - (bytestream2_get_byte(gb) << 8), SEEK_SET);
  345. if (bytestream2_tell_p(pb) == bytestream2_tell(&gbc))
  346. break;
  347. if (len < 5 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {
  348. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  349. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  350. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  351. } else {
  352. bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));
  353. len--;
  354. }
  355. do {
  356. bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));
  357. len--;
  358. } while (len && bytestream2_get_bytes_left(&gbc) > 0);
  359. }
  360. return 0;
  361. }
  362. static int decode_frame(AVCodecContext *avctx, void *data,
  363. int *got_frame, AVPacket *avpkt)
  364. {
  365. FMVCContext *s = avctx->priv_data;
  366. GetByteContext *gb = &s->gb;
  367. PutByteContext *pb = &s->pb;
  368. AVFrame *frame = data;
  369. int ret, y, x;
  370. if (avpkt->size < 8)
  371. return AVERROR_INVALIDDATA;
  372. if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
  373. return ret;
  374. bytestream2_init(gb, avpkt->data, avpkt->size);
  375. bytestream2_skip(gb, 2);
  376. frame->key_frame = !!bytestream2_get_le16(gb);
  377. frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
  378. if (frame->key_frame) {
  379. const uint8_t *src;
  380. unsigned type, size;
  381. uint8_t *dst;
  382. type = bytestream2_get_le16(gb);
  383. size = bytestream2_get_le16(gb);
  384. if (size > bytestream2_get_bytes_left(gb))
  385. return AVERROR_INVALIDDATA;
  386. bytestream2_init_writer(pb, s->buffer, s->buffer_size);
  387. if (type == 1) {
  388. decode_type1(gb, pb);
  389. } else if (type == 2){
  390. decode_type2(gb, pb);
  391. } else {
  392. avpriv_report_missing_feature(avctx, "Compression type %d", type);
  393. return AVERROR_PATCHWELCOME;
  394. }
  395. src = s->buffer;
  396. dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
  397. for (y = 0; y < avctx->height; y++) {
  398. memcpy(dst, src, avctx->width * s->bpp);
  399. dst -= frame->linesize[0];
  400. src += s->stride * 4;
  401. if (bytestream2_tell_p(pb) < y*s->stride * 4)
  402. break;
  403. }
  404. } else {
  405. unsigned block, nb_blocks;
  406. int type, k, l;
  407. uint8_t *ssrc, *ddst;
  408. const uint32_t *src;
  409. uint32_t *dst;
  410. for (block = 0; block < s->nb_blocks; block++)
  411. s->blocks[block].xor = 0;
  412. nb_blocks = bytestream2_get_le16(gb);
  413. if (nb_blocks > s->nb_blocks)
  414. return AVERROR_INVALIDDATA;
  415. bytestream2_init_writer(pb, s->pbuffer, s->pbuffer_size);
  416. type = bytestream2_get_le16(gb);
  417. for (block = 0; block < nb_blocks; block++) {
  418. unsigned size, offset;
  419. int start = 0;
  420. offset = bytestream2_get_le16(gb);
  421. if (offset >= s->nb_blocks)
  422. return AVERROR_INVALIDDATA;
  423. size = bytestream2_get_le16(gb);
  424. if (size > bytestream2_get_bytes_left(gb))
  425. return AVERROR_INVALIDDATA;
  426. start = bytestream2_tell_p(pb);
  427. if (type == 1) {
  428. decode_type1(gb, pb);
  429. } else if (type == 2){
  430. decode_type2(gb, pb);
  431. } else {
  432. avpriv_report_missing_feature(avctx, "Compression type %d", type);
  433. return AVERROR_PATCHWELCOME;
  434. }
  435. if (s->blocks[offset].size * 4 != bytestream2_tell_p(pb) - start)
  436. return AVERROR_INVALIDDATA;
  437. s->blocks[offset].xor = 1;
  438. }
  439. src = (const uint32_t *)s->pbuffer;
  440. dst = (uint32_t *)s->buffer;
  441. for (block = 0, y = 0; y < s->yb; y++) {
  442. int block_h = s->blocks[block].h;
  443. uint32_t *rect = dst;
  444. for (x = 0; x < s->xb; x++) {
  445. int block_w = s->blocks[block].w;
  446. uint32_t *row = dst;
  447. block_h = s->blocks[block].h;
  448. if (s->blocks[block].xor) {
  449. for (k = 0; k < block_h; k++) {
  450. uint32_t *column = dst;
  451. for (l = 0; l < block_w; l++)
  452. *dst++ ^= *src++;
  453. dst = &column[s->stride];
  454. }
  455. }
  456. dst = &row[block_w];
  457. ++block;
  458. }
  459. dst = &rect[block_h * s->stride];
  460. }
  461. ssrc = s->buffer;
  462. ddst = frame->data[0] + (avctx->height - 1) * frame->linesize[0];
  463. for (y = 0; y < avctx->height; y++) {
  464. memcpy(ddst, ssrc, avctx->width * s->bpp);
  465. ddst -= frame->linesize[0];
  466. ssrc += s->stride * 4;
  467. }
  468. }
  469. *got_frame = 1;
  470. return avpkt->size;
  471. }
  472. static av_cold int decode_init(AVCodecContext *avctx)
  473. {
  474. FMVCContext *s = avctx->priv_data;
  475. int i, j, m, block = 0, h = BLOCK_HEIGHT, w = BLOCK_WIDTH;
  476. switch (avctx->bits_per_coded_sample) {
  477. case 16:
  478. avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
  479. break;
  480. case 24:
  481. avctx->pix_fmt = AV_PIX_FMT_BGR24;
  482. break;
  483. case 32:
  484. avctx->pix_fmt = AV_PIX_FMT_BGRA;
  485. break;
  486. default:
  487. av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n",
  488. avctx->bits_per_coded_sample);
  489. return AVERROR_INVALIDDATA;
  490. }
  491. s->stride = (avctx->width * avctx->bits_per_coded_sample + 31) / 32;
  492. s->xb = s->stride / BLOCK_WIDTH;
  493. m = s->stride % BLOCK_WIDTH;
  494. if (m) {
  495. if (m < 37) {
  496. w = m + BLOCK_WIDTH;
  497. } else {
  498. w = m;
  499. s->xb++;
  500. }
  501. }
  502. s->yb = avctx->height / BLOCK_HEIGHT;
  503. m = avctx->height % BLOCK_HEIGHT;
  504. if (m) {
  505. if (m < 49) {
  506. h = m + BLOCK_HEIGHT;
  507. } else {
  508. h = m;
  509. s->yb++;
  510. }
  511. }
  512. s->nb_blocks = s->xb * s->yb;
  513. if (!s->nb_blocks)
  514. return AVERROR_INVALIDDATA;
  515. s->blocks = av_calloc(s->nb_blocks, sizeof(*s->blocks));
  516. if (!s->blocks)
  517. return AVERROR(ENOMEM);
  518. for (i = 0; i < s->yb; i++) {
  519. for (j = 0; j < s->xb; j++) {
  520. if (i != (s->yb - 1) || j != (s->xb - 1)) {
  521. if (i == s->yb - 1) {
  522. s->blocks[block].w = BLOCK_WIDTH;
  523. s->blocks[block].h = h;
  524. s->blocks[block].size = BLOCK_WIDTH * h;
  525. } else if (j == s->xb - 1) {
  526. s->blocks[block].w = w;
  527. s->blocks[block].h = BLOCK_HEIGHT;
  528. s->blocks[block].size = BLOCK_HEIGHT * w;
  529. } else {
  530. s->blocks[block].w = BLOCK_WIDTH;
  531. s->blocks[block].h = BLOCK_HEIGHT;
  532. s->blocks[block].size = BLOCK_WIDTH * BLOCK_HEIGHT;
  533. }
  534. } else {
  535. s->blocks[block].w = w;
  536. s->blocks[block].h = h;
  537. s->blocks[block].size = w * h;
  538. }
  539. block++;
  540. }
  541. }
  542. s->bpp = avctx->bits_per_coded_sample >> 3;
  543. s->buffer_size = avctx->width * avctx->height * 4;
  544. s->pbuffer_size = avctx->width * avctx->height * 4;
  545. s->buffer = av_mallocz(s->buffer_size);
  546. s->pbuffer = av_mallocz(s->pbuffer_size);
  547. if (!s->buffer || !s->pbuffer)
  548. return AVERROR(ENOMEM);
  549. return 0;
  550. }
  551. static av_cold int decode_close(AVCodecContext *avctx)
  552. {
  553. FMVCContext *s = avctx->priv_data;
  554. av_freep(&s->buffer);
  555. av_freep(&s->pbuffer);
  556. av_freep(&s->blocks);
  557. return 0;
  558. }
  559. AVCodec ff_fmvc_decoder = {
  560. .name = "fmvc",
  561. .long_name = NULL_IF_CONFIG_SMALL("FM Screen Capture Codec"),
  562. .type = AVMEDIA_TYPE_VIDEO,
  563. .id = AV_CODEC_ID_FMVC,
  564. .priv_data_size = sizeof(FMVCContext),
  565. .init = decode_init,
  566. .close = decode_close,
  567. .decode = decode_frame,
  568. .capabilities = AV_CODEC_CAP_DR1,
  569. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
  570. FF_CODEC_CAP_INIT_CLEANUP,
  571. };