msvideo1enc.c 9.4 KB

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