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.

312 lines
10KB

  1. /*
  2. * Microsoft Video-1 Encoder
  3. * Copyright (c) 2009 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 Video-1 encoder
  24. */
  25. #include "avcodec.h"
  26. #include "internal.h"
  27. #include "bytestream.h"
  28. #include "libavutil/lfg.h"
  29. #include "elbg.h"
  30. #include "libavutil/imgutils.h"
  31. /**
  32. * Encoder context
  33. */
  34. typedef struct Msvideo1EncContext {
  35. AVCodecContext *avctx;
  36. AVFrame pic;
  37. AVLFG rnd;
  38. uint8_t *prev;
  39. int block[16*3];
  40. int block2[16*3];
  41. int codebook[8*3];
  42. int codebook2[8*3];
  43. int output[16*3];
  44. int output2[16*3];
  45. int avg[3];
  46. int bestpos;
  47. int keyint;
  48. } Msvideo1EncContext;
  49. enum MSV1Mode{
  50. MODE_SKIP = 0,
  51. MODE_FILL,
  52. MODE_2COL,
  53. MODE_8COL,
  54. };
  55. #define SKIP_PREFIX 0x8400
  56. #define SKIPS_MAX 0x0FFF
  57. #define MKRGB555(in, off) ((in[off] << 10) | (in[off + 1] << 5) | (in[off + 2]))
  58. static const int remap[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 };
  59. static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
  60. const AVFrame *pict, int *got_packet)
  61. {
  62. Msvideo1EncContext * const c = avctx->priv_data;
  63. AVFrame * const p = &c->pic;
  64. uint16_t *src;
  65. uint8_t *prevptr;
  66. uint8_t *dst, *buf;
  67. int keyframe = 1;
  68. int no_skips = 1;
  69. int i, j, k, x, y, ret;
  70. int skips = 0;
  71. if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0)
  72. return ret;
  73. dst= buf= pkt->data;
  74. *p = *pict;
  75. if(!c->prev)
  76. c->prev = av_malloc(avctx->width * 3 * (avctx->height + 3));
  77. prevptr = c->prev + avctx->width * 3 * (FFALIGN(avctx->height, 4) - 1);
  78. src = (uint16_t*)(p->data[0] + p->linesize[0]*(FFALIGN(avctx->height, 4) - 1));
  79. if(c->keyint >= avctx->keyint_min)
  80. keyframe = 1;
  81. p->quality = 24;
  82. for(y = 0; y < avctx->height; y += 4){
  83. for(x = 0; x < avctx->width; x += 4){
  84. int bestmode = MODE_SKIP;
  85. int bestscore = INT_MAX;
  86. int flags = 0;
  87. int score;
  88. for(j = 0; j < 4; j++){
  89. for(i = 0; i < 4; i++){
  90. uint16_t val = src[x + i - j*p->linesize[0]/2];
  91. for(k = 0; k < 3; k++){
  92. c->block[(i + j*4)*3 + k] =
  93. c->block2[remap[i + j*4]*3 + k] = (val >> (10-k*5)) & 0x1F;
  94. }
  95. }
  96. }
  97. if(!keyframe){
  98. bestscore = 0;
  99. for(j = 0; j < 4; j++){
  100. for(i = 0; i < 4*3; i++){
  101. int t = prevptr[x*3 + i + j*p->linesize[0]] - c->block[i + j*4*3];
  102. bestscore += t*t;
  103. }
  104. }
  105. bestscore /= p->quality;
  106. }
  107. // try to find optimal value to fill whole 4x4 block
  108. score = 0;
  109. ff_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
  110. ff_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
  111. if(c->avg[0] == 1) // red component = 1 will be written as skip code
  112. c->avg[0] = 0;
  113. for(j = 0; j < 4; j++){
  114. for(i = 0; i < 4; i++){
  115. for(k = 0; k < 3; k++){
  116. int t = c->avg[k] - c->block[(i+j*4)*3+k];
  117. score += t*t;
  118. }
  119. }
  120. }
  121. score /= p->quality;
  122. score += 2;
  123. if(score < bestscore){
  124. bestscore = score;
  125. bestmode = MODE_FILL;
  126. }
  127. // search for optimal filling of 2-color block
  128. score = 0;
  129. ff_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
  130. ff_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
  131. // last output value should be always 1, swap codebooks if needed
  132. if(!c->output[15]){
  133. for(i = 0; i < 3; i++)
  134. FFSWAP(uint8_t, c->codebook[i], c->codebook[i+3]);
  135. for(i = 0; i < 16; i++)
  136. c->output[i] ^= 1;
  137. }
  138. for(j = 0; j < 4; j++){
  139. for(i = 0; i < 4; i++){
  140. for(k = 0; k < 3; k++){
  141. int t = c->codebook[c->output[i+j*4]*3 + k] - c->block[i*3+k+j*4*3];
  142. score += t*t;
  143. }
  144. }
  145. }
  146. score /= p->quality;
  147. score += 6;
  148. if(score < bestscore){
  149. bestscore = score;
  150. bestmode = MODE_2COL;
  151. }
  152. // search for optimal filling of 2-color 2x2 subblocks
  153. score = 0;
  154. for(i = 0; i < 4; i++){
  155. ff_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
  156. ff_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
  157. }
  158. // last value should be always 1, swap codebooks if needed
  159. if(!c->output2[15]){
  160. for(i = 0; i < 3; i++)
  161. FFSWAP(uint8_t, c->codebook2[i+18], c->codebook2[i+21]);
  162. for(i = 12; i < 16; i++)
  163. c->output2[i] ^= 1;
  164. }
  165. for(j = 0; j < 4; j++){
  166. for(i = 0; i < 4; i++){
  167. for(k = 0; k < 3; k++){
  168. int t = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3+k] - c->block[i*3+k + j*4*3];
  169. score += t*t;
  170. }
  171. }
  172. }
  173. score /= p->quality;
  174. score += 18;
  175. if(score < bestscore){
  176. bestscore = score;
  177. bestmode = MODE_8COL;
  178. }
  179. if(bestmode == MODE_SKIP){
  180. skips++;
  181. no_skips = 0;
  182. }
  183. if((bestmode != MODE_SKIP && skips) || skips == SKIPS_MAX){
  184. bytestream_put_le16(&dst, skips | SKIP_PREFIX);
  185. skips = 0;
  186. }
  187. switch(bestmode){
  188. case MODE_FILL:
  189. bytestream_put_le16(&dst, MKRGB555(c->avg,0) | 0x8000);
  190. for(j = 0; j < 4; j++)
  191. for(i = 0; i < 4; i++)
  192. for(k = 0; k < 3; k++)
  193. prevptr[i*3 + k - j*3*avctx->width] = c->avg[k];
  194. break;
  195. case MODE_2COL:
  196. for(j = 0; j < 4; j++){
  197. for(i = 0; i < 4; i++){
  198. flags |= (c->output[i + j*4]^1) << (i + j*4);
  199. for(k = 0; k < 3; k++)
  200. prevptr[i*3 + k - j*3*avctx->width] = c->codebook[c->output[i + j*4]*3 + k];
  201. }
  202. }
  203. bytestream_put_le16(&dst, flags);
  204. bytestream_put_le16(&dst, MKRGB555(c->codebook, 0));
  205. bytestream_put_le16(&dst, MKRGB555(c->codebook, 3));
  206. break;
  207. case MODE_8COL:
  208. for(j = 0; j < 4; j++){
  209. for(i = 0; i < 4; i++){
  210. flags |= (c->output2[remap[i + j*4]]^1) << (i + j*4);
  211. for(k = 0; k < 3; k++)
  212. prevptr[i*3 + k - j*3*avctx->width] = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3 + k];
  213. }
  214. }
  215. bytestream_put_le16(&dst, flags);
  216. bytestream_put_le16(&dst, MKRGB555(c->codebook2, 0) | 0x8000);
  217. for(i = 3; i < 24; i += 3)
  218. bytestream_put_le16(&dst, MKRGB555(c->codebook2, i));
  219. break;
  220. }
  221. }
  222. src -= p->linesize[0] << 1;
  223. prevptr -= avctx->width * 3 * 4;
  224. }
  225. if(skips)
  226. bytestream_put_le16(&dst, skips | SKIP_PREFIX);
  227. //EOF
  228. bytestream_put_byte(&dst, 0);
  229. bytestream_put_byte(&dst, 0);
  230. if(no_skips)
  231. keyframe = 1;
  232. if(keyframe)
  233. c->keyint = 0;
  234. else
  235. c->keyint++;
  236. p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
  237. p->key_frame= keyframe;
  238. if (keyframe) pkt->flags |= AV_PKT_FLAG_KEY;
  239. pkt->size = dst - buf;
  240. *got_packet = 1;
  241. return 0;
  242. }
  243. /**
  244. * init encoder
  245. */
  246. static av_cold int encode_init(AVCodecContext *avctx)
  247. {
  248. Msvideo1EncContext * const c = avctx->priv_data;
  249. c->avctx = avctx;
  250. if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
  251. return -1;
  252. }
  253. if((avctx->width&3) || (avctx->height&3)){
  254. av_log(avctx, AV_LOG_ERROR, "width and height must be multiplies of 4\n");
  255. return -1;
  256. }
  257. avcodec_get_frame_defaults(&c->pic);
  258. avctx->coded_frame = (AVFrame*)&c->pic;
  259. avctx->bits_per_coded_sample = 16;
  260. c->keyint = avctx->keyint_min;
  261. av_lfg_init(&c->rnd, 1);
  262. return 0;
  263. }
  264. /**
  265. * Uninit encoder
  266. */
  267. static av_cold int encode_end(AVCodecContext *avctx)
  268. {
  269. Msvideo1EncContext * const c = avctx->priv_data;
  270. av_freep(&c->prev);
  271. return 0;
  272. }
  273. AVCodec ff_msvideo1_encoder = {
  274. .name = "msvideo1",
  275. .type = AVMEDIA_TYPE_VIDEO,
  276. .id = CODEC_ID_MSVIDEO1,
  277. .priv_data_size = sizeof(Msvideo1EncContext),
  278. .init = encode_init,
  279. .encode2 = encode_frame,
  280. .close = encode_end,
  281. .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB555, PIX_FMT_NONE},
  282. .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"),
  283. };