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.

229 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 Libav.
  6. *
  7. * Libav 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. * Libav 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 Libav; 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()
  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()
  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++ = (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. const uint8_t *buf = avpkt->data;
  119. int buf_size = avpkt->size;
  120. MSS1Context *ctx = avctx->priv_data;
  121. MSS12Context *c = &ctx->ctx;
  122. GetBitContext gb;
  123. ArithCoder acoder;
  124. int pal_changed = 0;
  125. int ret;
  126. init_get_bits(&gb, buf, buf_size * 8);
  127. arith_init(&acoder, &gb);
  128. if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) {
  129. av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  130. return ret;
  131. }
  132. c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1);
  133. c->pal_stride = -ctx->pic->linesize[0];
  134. c->keyframe = !arith_get_bit(&acoder);
  135. if (c->keyframe) {
  136. c->corrupted = 0;
  137. ff_mss12_slicecontext_reset(&ctx->sc);
  138. pal_changed = decode_pal(c, &acoder);
  139. ctx->pic->key_frame = 1;
  140. ctx->pic->pict_type = AV_PICTURE_TYPE_I;
  141. } else {
  142. if (c->corrupted)
  143. return AVERROR_INVALIDDATA;
  144. ctx->pic->key_frame = 0;
  145. ctx->pic->pict_type = AV_PICTURE_TYPE_P;
  146. }
  147. c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0,
  148. avctx->width, avctx->height);
  149. if (c->corrupted)
  150. return AVERROR_INVALIDDATA;
  151. memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE);
  152. ctx->pic->palette_has_changed = pal_changed;
  153. if ((ret = av_frame_ref(data, ctx->pic)) < 0)
  154. return ret;
  155. *got_frame = 1;
  156. /* always report that the buffer was completely consumed */
  157. return buf_size;
  158. }
  159. static av_cold int mss1_decode_init(AVCodecContext *avctx)
  160. {
  161. MSS1Context * const c = avctx->priv_data;
  162. int ret;
  163. c->ctx.avctx = avctx;
  164. c->pic = av_frame_alloc();
  165. if (!c->pic)
  166. return AVERROR(ENOMEM);
  167. ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL);
  168. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  169. return ret;
  170. }
  171. static av_cold int mss1_decode_end(AVCodecContext *avctx)
  172. {
  173. MSS1Context * const ctx = avctx->priv_data;
  174. av_frame_free(&ctx->pic);
  175. ff_mss12_decode_end(&ctx->ctx);
  176. return 0;
  177. }
  178. AVCodec ff_mss1_decoder = {
  179. .name = "mss1",
  180. .long_name = NULL_IF_CONFIG_SMALL("MS Screen 1"),
  181. .type = AVMEDIA_TYPE_VIDEO,
  182. .id = AV_CODEC_ID_MSS1,
  183. .priv_data_size = sizeof(MSS1Context),
  184. .init = mss1_decode_init,
  185. .close = mss1_decode_end,
  186. .decode = mss1_decode_frame,
  187. .capabilities = AV_CODEC_CAP_DR1,
  188. };