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.

227 lines
6.0KB

  1. /*
  2. * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
  3. * Copyright (c) 2012 Konstantin Shishkov
  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. * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
  24. */
  25. #include "avcodec.h"
  26. #include "internal.h"
  27. #include "mss12.h"
  28. typedef struct MSS1Context {
  29. MSS12Context ctx;
  30. AVFrame *pic;
  31. SliceContext sc;
  32. } MSS1Context;
  33. static void arith_normalise(ArithCoder *c)
  34. {
  35. for (;;) {
  36. if (c->high >= 0x8000) {
  37. if (c->low < 0x8000) {
  38. if (c->low >= 0x4000 && c->high < 0xC000) {
  39. c->value -= 0x4000;
  40. c->low -= 0x4000;
  41. c->high -= 0x4000;
  42. } else {
  43. return;
  44. }
  45. } else {
  46. c->value -= 0x8000;
  47. c->low -= 0x8000;
  48. c->high -= 0x8000;
  49. }
  50. }
  51. c->value <<= 1;
  52. c->low <<= 1;
  53. c->high <<= 1;
  54. c->high |= 1;
  55. c->value |= get_bits1(c->gbc.gb);
  56. }
  57. }
  58. ARITH_GET_BIT(arith)
  59. static int arith_get_bits(ArithCoder *c, int bits)
  60. {
  61. int range = c->high - c->low + 1;
  62. int val = (((c->value - c->low + 1) << bits) - 1) / range;
  63. int prob = range * val;
  64. c->high = ((prob + range) >> bits) + c->low - 1;
  65. c->low += prob >> bits;
  66. arith_normalise(c);
  67. return val;
  68. }
  69. static int arith_get_number(ArithCoder *c, int mod_val)
  70. {
  71. int range = c->high - c->low + 1;
  72. int val = ((c->value - c->low + 1) * mod_val - 1) / range;
  73. int prob = range * val;
  74. c->high = (prob + range) / mod_val + c->low - 1;
  75. c->low += prob / mod_val;
  76. arith_normalise(c);
  77. return val;
  78. }
  79. static int arith_get_prob(ArithCoder *c, int16_t *probs)
  80. {
  81. int range = c->high - c->low + 1;
  82. int val = ((c->value - c->low + 1) * probs[0] - 1) / range;
  83. int sym = 1;
  84. while (probs[sym] > val)
  85. sym++;
  86. c->high = range * probs[sym - 1] / probs[0] + c->low - 1;
  87. c->low += range * probs[sym] / probs[0];
  88. return sym;
  89. }
  90. ARITH_GET_MODEL_SYM(arith)
  91. static void arith_init(ArithCoder *c, GetBitContext *gb)
  92. {
  93. c->low = 0;
  94. c->high = 0xFFFF;
  95. c->value = get_bits(gb, 16);
  96. c->gbc.gb = gb;
  97. c->get_model_sym = arith_get_model_sym;
  98. c->get_number = arith_get_number;
  99. }
  100. static int decode_pal(MSS12Context *ctx, ArithCoder *acoder)
  101. {
  102. int i, ncol, r, g, b;
  103. uint32_t *pal = ctx->pal + 256 - ctx->free_colours;
  104. if (!ctx->free_colours)
  105. return 0;
  106. ncol = arith_get_number(acoder, ctx->free_colours + 1);
  107. for (i = 0; i < ncol; i++) {
  108. r = arith_get_bits(acoder, 8);
  109. g = arith_get_bits(acoder, 8);
  110. b = arith_get_bits(acoder, 8);
  111. *pal++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
  112. }
  113. return !!ncol;
  114. }
  115. static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
  116. AVPacket *avpkt)
  117. {
  118. MSS1Context *ctx = avctx->priv_data;
  119. MSS12Context *c = &ctx->ctx;
  120. GetBitContext gb;
  121. ArithCoder acoder;
  122. int pal_changed = 0;
  123. int ret;
  124. if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
  125. return ret;
  126. arith_init(&acoder, &gb);
  127. if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0)
  128. return ret;
  129. c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1);
  130. c->pal_stride = -ctx->pic->linesize[0];
  131. c->keyframe = !arith_get_bit(&acoder);
  132. if (c->keyframe) {
  133. c->corrupted = 0;
  134. ff_mss12_slicecontext_reset(&ctx->sc);
  135. pal_changed = decode_pal(c, &acoder);
  136. ctx->pic->key_frame = 1;
  137. ctx->pic->pict_type = AV_PICTURE_TYPE_I;
  138. } else {
  139. if (c->corrupted)
  140. return AVERROR_INVALIDDATA;
  141. ctx->pic->key_frame = 0;
  142. ctx->pic->pict_type = AV_PICTURE_TYPE_P;
  143. }
  144. c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0,
  145. avctx->width, avctx->height);
  146. if (c->corrupted)
  147. return AVERROR_INVALIDDATA;
  148. memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE);
  149. ctx->pic->palette_has_changed = pal_changed;
  150. if ((ret = av_frame_ref(data, ctx->pic)) < 0)
  151. return ret;
  152. *got_frame = 1;
  153. /* always report that the buffer was completely consumed */
  154. return avpkt->size;
  155. }
  156. static av_cold int mss1_decode_init(AVCodecContext *avctx)
  157. {
  158. MSS1Context * const c = avctx->priv_data;
  159. int ret;
  160. c->ctx.avctx = avctx;
  161. c->pic = av_frame_alloc();
  162. if (!c->pic)
  163. return AVERROR(ENOMEM);
  164. ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL);
  165. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  166. return ret;
  167. }
  168. static av_cold int mss1_decode_end(AVCodecContext *avctx)
  169. {
  170. MSS1Context * const ctx = avctx->priv_data;
  171. av_frame_free(&ctx->pic);
  172. ff_mss12_decode_end(&ctx->ctx);
  173. return 0;
  174. }
  175. AVCodec ff_mss1_decoder = {
  176. .name = "mss1",
  177. .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"),
  178. .type = AVMEDIA_TYPE_VIDEO,
  179. .id = AV_CODEC_ID_MSS1,
  180. .priv_data_size = sizeof(MSS1Context),
  181. .init = mss1_decode_init,
  182. .close = mss1_decode_end,
  183. .decode = mss1_decode_frame,
  184. .capabilities = CODEC_CAP_DR1,
  185. };