Guest
Public paste!

Dark Shikari

By: a guest | May 10th, 2008 | Syntax: None | Size: 44.23 KB | Hits: 412 | Expires: Never
Copy text to clipboard
  1. Index: libavcodec/Makefile
  2. ===================================================================
  3. --- libavcodec/Makefile (revision 13076)
  4. +++ libavcodec/Makefile (working copy)
  5.  -143,6 +143,8 @@
  6.  OBJS-$(CONFIG_PCX_DECODER)             += pcx.o
  7.  OBJS-$(CONFIG_PGM_ENCODER)             += pnmenc.o pnm.o
  8.  OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o pnm.o
  9. +OBJS-$(CONFIG_PHOTON_DECODER)          += photon.o
  10. +OBJS-$(CONFIG_PHOTON_ENCODER)          += photon.o
  11.  OBJS-$(CONFIG_PNG_DECODER)             += png.o pngdec.o
  12.  OBJS-$(CONFIG_PNG_ENCODER)             += png.o pngenc.o
  13.  OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o pnm.o
  14. Index: libavcodec/h264data.h
  15. ===================================================================
  16. --- libavcodec/h264data.h       (revision 13076)
  17. +++ libavcodec/h264data.h       (working copy)
  18.  -545,6 +545,25 @@
  19.    {36,32,58,34,46,43},
  20.  };
  21.  
  22. +static const int quant4_coeff_init[6][3] =
  23. +{
  24. +    { 13107, 8066, 5243 },
  25. +    { 11916, 7490, 4660 },
  26. +    { 10082, 6554, 4194 },
  27. +    {  9362, 5825, 3647 },
  28. +    {  8192, 5243, 3355 },
  29. +    {  7282, 4559, 2893 },
  30. +};
  31. +static const int quant8_coeff_init[6][6] =
  32. +{
  33. +    { 13107, 11428, 20972, 12222, 16777, 15481 },
  34. +    { 11916, 10826, 19174, 11058, 14980, 14290 },
  35. +    { 10082,  8943, 15978,  9675, 12710, 11985 },
  36. +    {  9362,  8228, 14913,  8931, 11984, 11259 },
  37. +    {  8192,  7346, 13159,  7740, 10486,  9777 },
  38. +    {  7282,  6428, 11570,  6830,  9118,  8640 }
  39. +};
  40. +
  41.  #define QUANT_SHIFT 22
  42.  
  43.  static const int quant_coeff[52][16]={
  44. Index: libavcodec/photon.c
  45. ===================================================================
  46. --- libavcodec/photon.c (revision 0)
  47. +++ libavcodec/photon.c (revision 0)
  48.  -0,0 +1,1316 @@
  49. +/*
  50. + * Photon (PHTN) Video Encoder and Decoder
  51. + *   by Jason Garrett-Glaser (darkshikari@gmail.com)
  52. + *
  53. + * Copyright (C) 2008 the ffmpeg project
  54. + *
  55. + * This file is part of FFmpeg.
  56. + *
  57. + * FFmpeg is free software; you can redistribute it and/or
  58. + * modify it under the terms of the GNU General Public
  59. + * License as published by the Free Software Foundation; either
  60. + * version 2 of the License, or (at your option) any later version.
  61. + *
  62. + * FFmpeg is distributed in the hope that it will be useful,
  63. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  64. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  65. + * Lesser General Public License for more details.
  66. + *
  67. + * You should have received a copy of the GNU Lesser General Public
  68. + * License along with FFmpeg; if not, write to the Free Software
  69. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  70. + */
  71. +
  72. + /**
  73. + * @file photon.c
  74. + * Photon Video Encoder and Decoder
  75. + */
  76. +
  77. +#include <stdio.h>
  78. +#include <stdlib.h>
  79. +#include <string.h>
  80. +#include <unistd.h>
  81. +
  82. +#include "avcodec.h"
  83. +#include "dsputil.h"
  84. +#include "bitstream.h"
  85. +#include "golomb.h"
  86. +#include "h264pred.h"
  87. +#include "h264pred.c"
  88. +#include "h264data.h"
  89. +#include "dsputil.h"
  90. +//#include "dsputil.c"
  91. +
  92. +#define GLOBAL_DEADZONE 0
  93. +
  94. +#define PHOTON_FRAMETYPE_P 1
  95. +#define PHOTON_FRAMETYPE_I 0
  96. +
  97. +#define PHOTON_MBTYPE_SKIP  2
  98. +#define PHOTON_MBTYPE_INTER 1
  99. +#define PHOTON_MBTYPE_INTRA 0
  100. +
  101. +#define PHOTON_INTRA_MODE_DC 0
  102. +#define PHOTON_INTRA_MODE_V 1
  103. +#define PHOTON_INTRA_MODE_H 2
  104. +
  105. +typedef struct PhotonContext {
  106. +    AVCodecContext *avctx;
  107. +    AVFrame         frame;
  108. +    GetBitContext   gb;
  109. +    PutBitContext   pb;
  110. +    int     mb_x;
  111. +    int     mb_y;
  112. +    int     mb_xy;
  113. +    int     mb_width;
  114. +    int     mb_height;
  115. +    int     frame_type;
  116. +    int     frame_qp;
  117. +    int     block_type; /* 1 = inter, 0 = intra */
  118. +    int     mb_qp[6];
  119. +    int     last_mb_qp[6];
  120. +    int     mv[2];
  121. +    int16_t (*mb_mv)[2]; /* array of framewide mb_mv values */
  122. +    uint8_t *fdec[6];
  123. +    uint8_t *fenc[6];
  124. +    int     fdec_stride[6];
  125. +    int     fenc_stride[6];
  126. +    
  127. +    int     intra_pred_luma;
  128. +    int     intra_pred_chroma;
  129. +
  130. +    int     transform8x8[6];
  131. +    int     subcbp[6];
  132. +    int16_t dct4x4[6][4][16];
  133. +    int16_t dct8x8[6][64];
  134. +
  135. +    int     dequant4_mf[52][16];
  136. +    int     dequant8_mf[52][64];
  137. +    int     quant4_mf[52][16];
  138. +    int     quant8_mf[52][64];
  139. +    int     quant4_bias[52][16];
  140. +    int     quant8_bias[52][64];
  141. +} PhotonContext;
  142. +
  143. +#define SHIFT(x,s) ((s)<0 ? (x)<<-(s) : (s)==0 ? (x) : ((x)+(1<<((s)-1)))>>(s))
  144. +#define DIV(n,d) (((n) + ((d)>>1)) / (d))
  145. +
  146. +static void init_quant_tables(PhotonContext *s)
  147. +{
  148. +    int def_quant4[6][16];
  149. +    int def_quant8[6][64];
  150. +    int def_dequant4[6][16];
  151. +    int def_dequant8[6][64];
  152. +    int quant4_mf[6][16];
  153. +    int quant8_mf[6][64];
  154. +    int q, i, j;
  155. +    int deadzone = 32 - GLOBAL_DEADZONE; /* Constant deadzone to start */
  156. +
  157. +    for( q = 0; q < 6; q++ )
  158. +    {
  159. +        for( i = 0; i < 16; i++ )
  160. +        {
  161. +            int j = (i&1) + ((i>>2)&1);
  162. +            def_dequant4[q][i] = dequant4_coeff_init[q][j];
  163. +            def_quant4[q][i]   =   quant4_coeff_init[q][j];
  164. +        }
  165. +        for( i = 0; i < 64; i++ )
  166. +        {
  167. +            int j = dequant8_coeff_init_scan[((i>>1)&12) | (i&3)];
  168. +            def_dequant8[q][i] = dequant8_coeff_init[q][j];
  169. +            def_quant8[q][i]   =   quant8_coeff_init[q][j];
  170. +        }
  171. +    }
  172. +
  173. +    for( q = 0; q < 52; q++ )
  174. +    {
  175. +        for( i = 0; i < 16; i++ )
  176. +            s->dequant4_mf[q][i] = (def_dequant4[q%6][i] * 16) << (q/6);
  177. +        for( i = 0; i < 64; i++ )
  178. +            s->dequant8_mf[q][i] = (def_dequant8[q%6][i] * 16) << (q/6);
  179. +    }
  180. +    for( q = 0; q < 6; q++ )
  181. +    {
  182. +        for( i = 0; i < 16; i++ )
  183. +            quant4_mf[q][i] = def_quant4[q][i];
  184. +        for( i = 0; i < 64; i++ )
  185. +            quant8_mf[q][i] = def_quant8[q][i];
  186. +    }
  187. +    for( q = 0; q < 52; q++ )
  188. +    {
  189. +        for( i = 0; i < 16; i++ )
  190. +        {
  191. +            s->  quant4_mf[q][i] = j = SHIFT(quant4_mf[q%6][i], q/6 - 1);
  192. +            s->quant4_bias[q][i] = FFMIN( DIV(deadzone<<10, j), (1<<15)/j );
  193. +        }
  194. +        for( i = 0; i < 64; i++ )
  195. +        {
  196. +            s->  quant8_mf[q][i] = j = SHIFT(quant8_mf[q%6][i], q/6);
  197. +            s->quant8_bias[q][i] = FFMIN( DIV(deadzone<<10, j), (1<<15)/j );
  198. +        }
  199. +    }
  200. +}
  201. +
  202. +static int photon_decode_init(AVCodecContext *avctx)
  203. +{
  204. +    PhotonContext *s = avctx->priv_data;
  205. +    
  206. +    /* Codec doesn't currently support non-mod16 resolutions. */
  207. +    if(avctx->width % 16 != 0 || avctx->height % 16 != 0)
  208. +    {
  209. +        av_log(s->avctx, AV_LOG_ERROR, "photon does not support non-mod16 resolutions");
  210. +        return -1;
  211. +    }
  212. +
  213. +    s->avctx = avctx;
  214. +    s->mb_width = avctx->width / 16;
  215. +    s->mb_height = avctx->height / 16;
  216. +    
  217. +    s->mb_mv = av_mallocz(s->mb_width * s->mb_height * sizeof(int16_t) * 2);
  218. +    
  219. +    if(!s->mb_mv)
  220. +    {
  221. +        av_log(s->avctx, AV_LOG_ERROR, "photon: malloc failure");
  222. +        return -1;
  223. +    }
  224. +
  225. +    avctx->pix_fmt = PIX_FMT_YUV420P;
  226. +    init_quant_tables(s);
  227. +
  228. +    return 0;
  229. +}
  230. +
  231. +static int photon_encode_init(AVCodecContext *avctx)
  232. +{
  233. +    return photon_decode_init(avctx);
  234. +}
  235. +
  236. +static int photon_decode_close(AVCodecContext *avctx)
  237. +{
  238. +    return 0;
  239. +}
  240. +
  241. +static int photon_encode_close(AVCodecContext *avctx)
  242. +{
  243. +    return 0;
  244. +}
  245. +
  246. +#define SAD(num)\
  247. +static int sad##num##x##num(uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2)\
  248. +{\
  249. +    int i,j,sum=0;\
  250. +    for(i = 0; i < num; i++)\
  251. +    {\
  252. +        for(j = 0; j < num; j++)\
  253. +            sum += abs(pix1[j]-pix2[j]);\
  254. +        pix1 += i_pix1;\
  255. +        pix2 += i_pix2;\
  256. +    }\
  257. +    return sum;\
  258. +}
  259. +
  260. +SAD(16)
  261. +SAD(8)
  262. +
  263. +#define SSD(num)\
  264. +static int ssd##num##x##num(uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2)\
  265. +{\
  266. +    int i,j,sum=0;\
  267. +    for(i = 0; i < num; i++)\
  268. +    {\
  269. +        for(j = 0; j < num; j++) {\
  270. +            int n = pix1[j]-pix2[j];\
  271. +            sum += n*n;\
  272. +        }\
  273. +        pix1 += i_pix1;\
  274. +        pix2 += i_pix2;\
  275. +    }\
  276. +    return sum;\
  277. +}
  278. +
  279. +SSD(8)
  280. +
  281. +/* H.264 HCT */
  282. +/* Code from x264 */
  283. +
  284. +static void pixel_sub_wxh( int16_t *diff, int i_size,
  285. +                                  uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
  286. +{
  287. +    int y, x;
  288. +    for( y = 0; y < i_size; y++ )
  289. +    {
  290. +        for( x = 0; x < i_size; x++ )
  291. +        {
  292. +            diff[x + y*i_size] = pix1[x] - pix2[x];
  293. +        }
  294. +        pix1 += i_pix1;
  295. +        pix2 += i_pix2;
  296. +    }
  297. +}
  298. +
  299. +static void sub4x4_dct( DCTELEM dct[4][4], uint8_t *pix1, uint8_t *pix2, int fenc_stride, int fdec_stride )
  300. +{
  301. +    DCTELEM d[4][4];
  302. +    DCTELEM tmp[4][4];
  303. +    int i;
  304. +
  305. +    pixel_sub_wxh( (DCTELEM*)d, 4, pix1, fenc_stride, pix2, fdec_stride );
  306. +
  307. +    for( i = 0; i < 4; i++ )
  308. +    {
  309. +        const int s03 = d[i][0] + d[i][3];
  310. +        const int s12 = d[i][1] + d[i][2];
  311. +        const int d03 = d[i][0] - d[i][3];
  312. +        const int d12 = d[i][1] - d[i][2];
  313. +
  314. +        tmp[0][i] =   s03 +   s12;
  315. +        tmp[1][i] = 2*d03 +   d12;
  316. +        tmp[2][i] =   s03 -   s12;
  317. +        tmp[3][i] =   d03 - 2*d12;
  318. +    }
  319. +
  320. +    for( i = 0; i < 4; i++ )
  321. +    {
  322. +        const int s03 = tmp[i][0] + tmp[i][3];
  323. +        const int s12 = tmp[i][1] + tmp[i][2];
  324. +        const int d03 = tmp[i][0] - tmp[i][3];
  325. +        const int d12 = tmp[i][1] - tmp[i][2];
  326. +
  327. +        dct[i][0] =   s03 +   s12;
  328. +        dct[i][1] = 2*d03 +   d12;
  329. +        dct[i][2] =   s03 -   s12;
  330. +        dct[i][3] =   d03 - 2*d12;
  331. +    }
  332. +}
  333. +
  334. +#define DCT8_1D {\
  335. +    const int s07 = SRC(0) + SRC(7);\
  336. +    const int s16 = SRC(1) + SRC(6);\
  337. +    const int s25 = SRC(2) + SRC(5);\
  338. +    const int s34 = SRC(3) + SRC(4);\
  339. +    const int a0 = s07 + s34;\
  340. +    const int a1 = s16 + s25;\
  341. +    const int a2 = s07 - s34;\
  342. +    const int a3 = s16 - s25;\
  343. +    const int d07 = SRC(0) - SRC(7);\
  344. +    const int d16 = SRC(1) - SRC(6);\
  345. +    const int d25 = SRC(2) - SRC(5);\
  346. +    const int d34 = SRC(3) - SRC(4);\
  347. +    const int a4 = d16 + d25 + (d07 + (d07>>1));\
  348. +    const int a5 = d07 - d34 - (d25 + (d25>>1));\
  349. +    const int a6 = d07 + d34 - (d16 + (d16>>1));\
  350. +    const int a7 = d16 - d25 + (d34 + (d34>>1));\
  351. +    DST(0) =  a0 + a1     ;\
  352. +    DST(1) =  a4 + (a7>>2);\
  353. +    DST(2) =  a2 + (a3>>1);\
  354. +    DST(3) =  a5 + (a6>>2);\
  355. +    DST(4) =  a0 - a1     ;\
  356. +    DST(5) =  a6 - (a5>>2);\
  357. +    DST(6) = (a2>>1) - a3 ;\
  358. +    DST(7) = (a4>>2) - a7 ;\
  359. +}
  360. +
  361. +static void sub8x8_dct8( DCTELEM dct[8][8], uint8_t *pix1, uint8_t *pix2, int fenc_stride, int fdec_stride )
  362. +{
  363. +    int i;
  364. +    DCTELEM tmp[8][8];
  365. +
  366. +    pixel_sub_wxh( (DCTELEM*)tmp, 8, pix1, fenc_stride, pix2, fdec_stride );
  367. +
  368. +#define SRC(x) tmp[x][i]
  369. +#define DST(x) tmp[x][i]
  370. +    for( i = 0; i < 8; i++ )
  371. +        DCT8_1D
  372. +#undef SRC
  373. +#undef DST
  374. +
  375. +#define SRC(x) tmp[i][x]
  376. +#define DST(x) dct[x][i]
  377. +    for( i = 0; i < 8; i++ )
  378. +        DCT8_1D
  379. +#undef SRC
  380. +#undef DST
  381. +}
  382. +
  383. +static void add4x4_idct( uint8_t *p_dst, DCTELEM dct[4][4], int stride )
  384. +{
  385. +    int16_t d[4][4];
  386. +    int16_t tmp[4][4];
  387. +    int x, y;
  388. +    int i;
  389. +
  390. +    for( i = 0; i < 4; i++ )
  391. +    {
  392. +        const int s02 =  dct[0][i]     +  dct[2][i];
  393. +        const int d02 =  dct[0][i]     -  dct[2][i];
  394. +        const int s13 =  dct[1][i]     + (dct[3][i]>>1);
  395. +        const int d13 = (dct[1][i]>>1) -  dct[3][i];
  396. +
  397. +        tmp[i][0] = s02 + s13;
  398. +        tmp[i][1] = d02 + d13;
  399. +        tmp[i][2] = d02 - d13;
  400. +        tmp[i][3] = s02 - s13;
  401. +    }
  402. +
  403. +    for( i = 0; i < 4; i++ )
  404. +    {
  405. +        const int s02 =  tmp[0][i]     +  tmp[2][i];
  406. +        const int d02 =  tmp[0][i]     -  tmp[2][i];
  407. +        const int s13 =  tmp[1][i]     + (tmp[3][i]>>1);
  408. +        const int d13 = (tmp[1][i]>>1) -  tmp[3][i];
  409. +
  410. +        d[0][i] = ( s02 + s13 + 32 ) >> 6;
  411. +        d[1][i] = ( d02 + d13 + 32 ) >> 6;
  412. +        d[2][i] = ( d02 - d13 + 32 ) >> 6;
  413. +        d[3][i] = ( s02 - s13 + 32 ) >> 6;
  414. +    }
  415. +
  416. +
  417. +    for( y = 0; y < 4; y++ )
  418. +    {
  419. +        for( x = 0; x < 4; x++ )
  420. +        {
  421. +            p_dst[x] = av_clip_uint8( p_dst[x] + d[y][x] );
  422. +        }
  423. +        p_dst += stride;
  424. +    }
  425. +}
  426. +
  427. +#define IDCT8_1D {\
  428. +    const int a0 =  SRC(0) + SRC(4);\
  429. +    const int a2 =  SRC(0) - SRC(4);\
  430. +    const int a4 = (SRC(2)>>1) - SRC(6);\
  431. +    const int a6 = (SRC(6)>>1) + SRC(2);\
  432. +    const int b0 = a0 + a6;\
  433. +    const int b2 = a2 + a4;\
  434. +    const int b4 = a2 - a4;\
  435. +    const int b6 = a0 - a6;\
  436. +    const int a1 = -SRC(3) + SRC(5) - SRC(7) - (SRC(7)>>1);\
  437. +    const int a3 =  SRC(1) + SRC(7) - SRC(3) - (SRC(3)>>1);\
  438. +    const int a5 = -SRC(1) + SRC(7) + SRC(5) + (SRC(5)>>1);\
  439. +    const int a7 =  SRC(3) + SRC(5) + SRC(1) + (SRC(1)>>1);\
  440. +    const int b1 = (a7>>2) + a1;\
  441. +    const int b3 =  a3 + (a5>>2);\
  442. +    const int b5 = (a3>>2) - a5;\
  443. +    const int b7 =  a7 - (a1>>2);\
  444. +    DST(0, b0 + b7);\
  445. +    DST(1, b2 + b5);\
  446. +    DST(2, b4 + b3);\
  447. +    DST(3, b6 + b1);\
  448. +    DST(4, b6 - b1);\
  449. +    DST(5, b4 - b3);\
  450. +    DST(6, b2 - b5);\
  451. +    DST(7, b0 - b7);\
  452. +}
  453. +
  454. +static void add8x8_idct8( uint8_t *dst, DCTELEM dct[8][8], int stride )
  455. +{
  456. +    int i;
  457. +
  458. +    dct[0][0] += 32; // rounding for the >>6 at the end
  459. +
  460. +#define SRC(x)     dct[x][i]
  461. +#define DST(x,rhs) dct[x][i] = (rhs)
  462. +    for( i = 0; i < 8; i++ )
  463. +        IDCT8_1D
  464. +#undef SRC
  465. +#undef DST
  466. +
  467. +#define SRC(x)     dct[i][x]
  468. +#define DST(x,rhs) dst[i + x*stride] = av_clip_uint8( dst[i + x*stride] + ((rhs) >> 6) );
  469. +    for( i = 0; i < 8; i++ )
  470. +        IDCT8_1D
  471. +#undef SRC
  472. +#undef DST
  473. +}
  474. +
  475. +#define QUANT_ONE( coef, mf, f ) \
  476. +{ \
  477. +    if( (coef) > 0 ) \
  478. +        (coef) = (f + (coef)) * (mf) >> 16; \
  479. +    else \
  480. +        (coef) = - ((f - (coef)) * (mf) >> 16); \
  481. +}
  482. +
  483. +static void quant_8x8( DCTELEM dct[8][8], int mf[64], int bias[64] )
  484. +{
  485. +    int i;
  486. +    for( i = 0; i < 64; i++ )
  487. +        QUANT_ONE( dct[0][i], mf[i], bias[i] );
  488. +}
  489. +
  490. +static void quant_4x4( DCTELEM dct[4][4], int mf[16], int bias[16] )
  491. +{
  492. +    int i;
  493. +    for( i = 0; i < 16; i++ )
  494. +        QUANT_ONE( dct[0][i], mf[i], bias[i] );
  495. +}
  496. +
  497. +#define ZIG(i,y,x) level[i] = dct[x][y];
  498. +
  499. +static void zigzag_scan_8x8_frame( int16_t level[64], DCTELEM dct[8][8] )
  500. +{
  501. +    ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
  502. +    ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
  503. +    ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,4,0) ZIG(11,3,1)
  504. +    ZIG(12,2,2) ZIG(13,1,3) ZIG(14,0,4) ZIG(15,0,5)
  505. +    ZIG(16,1,4) ZIG(17,2,3) ZIG(18,3,2) ZIG(19,4,1)
  506. +    ZIG(20,5,0) ZIG(21,6,0) ZIG(22,5,1) ZIG(23,4,2)
  507. +    ZIG(24,3,3) ZIG(25,2,4) ZIG(26,1,5) ZIG(27,0,6)
  508. +    ZIG(28,0,7) ZIG(29,1,6) ZIG(30,2,5) ZIG(31,3,4)
  509. +    ZIG(32,4,3) ZIG(33,5,2) ZIG(34,6,1) ZIG(35,7,0)
  510. +    ZIG(36,7,1) ZIG(37,6,2) ZIG(38,5,3) ZIG(39,4,4)
  511. +    ZIG(40,3,5) ZIG(41,2,6) ZIG(42,1,7) ZIG(43,2,7)
  512. +    ZIG(44,3,6) ZIG(45,4,5) ZIG(46,5,4) ZIG(47,6,3)
  513. +    ZIG(48,7,2) ZIG(49,7,3) ZIG(50,6,4) ZIG(51,5,5)
  514. +    ZIG(52,4,6) ZIG(53,3,7) ZIG(54,4,7) ZIG(55,5,6)
  515. +    ZIG(56,6,5) ZIG(57,7,4) ZIG(58,7,5) ZIG(59,6,6)
  516. +    ZIG(60,5,7) ZIG(61,6,7) ZIG(62,7,6) ZIG(63,7,7)
  517. +}
  518. +
  519. +static void zigzag_scan_4x4_frame( int16_t level[16], DCTELEM dct[4][4] )
  520. +{
  521. +    ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
  522. +    ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
  523. +    ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)
  524. +    ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
  525. +}
  526. +
  527. +#define DEQUANT_SHL( x ) \
  528. +    dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*4+x] ) << i_qbits
  529. +
  530. +#define DEQUANT_SHR( x ) \
  531. +    dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*4+x] + f ) >> (-i_qbits)
  532. +
  533. +static void dequant_4x4( DCTELEM dct[4][4], int dequant_mf[6][16], int i_qp )
  534. +{
  535. +    const int i_mf = i_qp%6;
  536. +    const int i_qbits = i_qp/6 - 4;
  537. +    int y;
  538. +
  539. +    if( i_qbits >= 0 )
  540. +    {
  541. +        for( y = 0; y < 4; y++ )
  542. +        {
  543. +            DEQUANT_SHL( 0 );
  544. +            DEQUANT_SHL( 1 );
  545. +            DEQUANT_SHL( 2 );
  546. +            DEQUANT_SHL( 3 );
  547. +        }
  548. +    }
  549. +    else
  550. +    {
  551. +        const int f = 1 << (-i_qbits-1);
  552. +        for( y = 0; y < 4; y++ )
  553. +        {
  554. +            DEQUANT_SHR( 0 );
  555. +            DEQUANT_SHR( 1 );
  556. +            DEQUANT_SHR( 2 );
  557. +            DEQUANT_SHR( 3 );
  558. +        }
  559. +    }
  560. +}
  561. +
  562. +#undef DEQUANT_SHL
  563. +#define DEQUANT_SHL( x ) \
  564. +    dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*8+x] ) << i_qbits
  565. +#undef DEQUANT_SHR
  566. +#define DEQUANT_SHR( x ) \
  567. +    dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*8+x] + f ) >> (-i_qbits)
  568. +
  569. +static void dequant_8x8( DCTELEM dct[8][8], int dequant_mf[6][64], int i_qp )
  570. +{
  571. +    const int i_mf = i_qp%6;
  572. +    const int i_qbits = i_qp/6 - 6;
  573. +    int y;
  574. +
  575. +    if( i_qbits >= 0 )
  576. +    {
  577. +        for( y = 0; y < 8; y++ )
  578. +        {
  579. +            DEQUANT_SHL( 0 );
  580. +            DEQUANT_SHL( 1 );
  581. +            DEQUANT_SHL( 2 );
  582. +            DEQUANT_SHL( 3 );
  583. +            DEQUANT_SHL( 4 );
  584. +            DEQUANT_SHL( 5 );
  585. +            DEQUANT_SHL( 6 );
  586. +            DEQUANT_SHL( 7 );
  587. +        }
  588. +    }
  589. +    else
  590. +    {
  591. +        const int f = 1 << (-i_qbits-1);
  592. +        for( y = 0; y < 8; y++ )
  593. +        {
  594. +            DEQUANT_SHR( 0 );
  595. +            DEQUANT_SHR( 1 );
  596. +            DEQUANT_SHR( 2 );
  597. +            DEQUANT_SHR( 3 );
  598. +            DEQUANT_SHR( 4 );
  599. +            DEQUANT_SHR( 5 );
  600. +            DEQUANT_SHR( 6 );
  601. +            DEQUANT_SHR( 7 );
  602. +        }
  603. +    }
  604. +}
  605. +
  606. +/* H.264-style MV prediction */
  607. +static void photon_predict_mv(PhotonContext *s)
  608. +{
  609. +    const int top_left = s->mb_xy - s->mb_width - 1;
  610. +    const int top_right = s->mb_xy - s->mb_width + 1;
  611. +    const int top = s->mb_xy - s->mb_width;
  612. +    const int left = s->mb_xy - 1;
  613. +    if(s->mb_xy == 0)
  614. +    {
  615. +        s->mv[0] = 0;
  616. +        s->mv[1] = 0;
  617. +    }
  618. +    else if(s->mb_x == 0)
  619. +    {
  620. +        s->mv[0] = mid_pred(0,s->mb_mv[left][0],s->mb_mv[top][0]);
  621. +        s->mv[1] = mid_pred(0,s->mb_mv[left][1],s->mb_mv[top][1]);
  622. +    }
  623. +    else if(s->mb_y == 0)
  624. +    {
  625. +        s->mv[0] = s->mb_mv[left][0];
  626. +        s->mv[1] = s->mb_mv[left][1];
  627. +    }
  628. +    else if(s->mb_x == s->mb_width - 1)
  629. +    {
  630. +        s->mv[0] = mid_pred(s->mb_mv[top_left][0],s->mb_mv[left][0],s->mb_mv[top][0]);
  631. +        s->mv[1] = mid_pred(s->mb_mv[top_left][1],s->mb_mv[left][1],s->mb_mv[top][1]);
  632. +    }
  633. +    else
  634. +    {
  635. +        s->mv[0] = mid_pred(s->mb_mv[top_right][0],s->mb_mv[left][0],s->mb_mv[top][0]);
  636. +        s->mv[1] = mid_pred(s->mb_mv[top_right][1],s->mb_mv[left][1],s->mb_mv[top][1]);
  637. +    }
  638. +}
  639. +
  640. +static void photon_predict_mv_skip(PhotonContext *s)
  641. +{
  642. +    const int top_left = s->mb_xy - s->mb_width - 1;
  643. +    const int top_right = s->mb_xy - s->mb_width + 1;
  644. +    const int top = s->mb_xy - s->mb_width;
  645. +    const int left = s->mb_xy - 1;
  646. +    if(s->mb_xy == 0)
  647. +    {
  648. +        s->mv[0] = 0;
  649. +        s->mv[1] = 0;
  650. +    }
  651. +    else if(s->mb_x == 0)
  652. +    {
  653. +        if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
  654. +           (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0))
  655. +        {
  656. +            s->mv[0] = 0;
  657. +            s->mv[1] = 0;
  658. +        }
  659. +        else
  660. +        {
  661. +            s->mv[0] = mid_pred(0,s->mb_mv[left][0],s->mb_mv[top][0]);
  662. +            s->mv[1] = mid_pred(0,s->mb_mv[left][1],s->mb_mv[top][1]);
  663. +        }
  664. +    }
  665. +    else if(s->mb_y == 0)
  666. +    {
  667. +        s->mv[0] = s->mb_mv[left][0];
  668. +        s->mv[1] = s->mb_mv[left][1];
  669. +    }
  670. +    else if(s->mb_x == s->mb_width - 1)
  671. +    {
  672. +        if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
  673. +           (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0) ||
  674. +           (s->mb_mv[top_left][0] == 0 && s->mb_mv[top_left][1] == 0))
  675. +        {
  676. +            s->mv[0] = 0;
  677. +            s->mv[1] = 0;
  678. +        }
  679. +        else
  680. +        {
  681. +            s->mv[0] = mid_pred(s->mb_mv[top_left][0],s->mb_mv[left][0],s->mb_mv[top][0]);
  682. +            s->mv[1] = mid_pred(s->mb_mv[top_left][1],s->mb_mv[left][1],s->mb_mv[top][1]);
  683. +        }
  684. +    }
  685. +    else
  686. +    {
  687. +        if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
  688. +           (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0) ||
  689. +           (s->mb_mv[top_right][0] == 0 && s->mb_mv[top_right][1] == 0))
  690. +        {
  691. +            s->mv[0] = 0;
  692. +            s->mv[1] = 0;
  693. +        }
  694. +        else
  695. +        {
  696. +            s->mv[0] = mid_pred(s->mb_mv[top_right][0],s->mb_mv[left][0],s->mb_mv[top][0]);
  697. +            s->mv[1] = mid_pred(s->mb_mv[top_right][1],s->mb_mv[left][1],s->mb_mv[top][1]);
  698. +        }
  699. +    }
  700. +}
  701. +
  702. +static void photon_predict_intra_dc(PhotonContext *s)
  703. +{
  704. +    if(s->mb_xy == 0) pred16x16_128_dc_c(s->fdec[0],s->fdec_stride[0]);
  705. +    else if(s->mb_x == 0) pred16x16_top_dc_c(s->fdec[0],s->fdec_stride[0]);
  706. +    else if(s->mb_y == 0) pred16x16_left_dc_c(s->fdec[0],s->fdec_stride[0]);
  707. +    else pred16x16_dc_c(s->fdec[0],s->fdec_stride[0]);
  708. +}
  709. +
  710. +static void photon_predict_intra_chroma_dc(PhotonContext *s)
  711. +{
  712. +    if(s->mb_xy == 0)
  713. +    {
  714. +        pred8x8_128_dc_c(s->fdec[4],s->fdec_stride[4]);
  715. +        pred8x8_128_dc_c(s->fdec[5],s->fdec_stride[5]);
  716. +    }
  717. +    else if(s->mb_x == 0)
  718. +    {
  719. +        pred8x8_top_dc_c(s->fdec[4],s->fdec_stride[4]);
  720. +        pred8x8_top_dc_c(s->fdec[5],s->fdec_stride[5]);
  721. +    }
  722. +    else if(s->mb_y == 0)
  723. +    {
  724. +        pred8x8_left_dc_c(s->fdec[4],s->fdec_stride[4]);
  725. +        pred8x8_left_dc_c(s->fdec[5],s->fdec_stride[5]);
  726. +    }
  727. +    else
  728. +    {
  729. +        pred8x8_dc_c(s->fdec[4],s->fdec_stride[4]);
  730. +        pred8x8_dc_c(s->fdec[5],s->fdec_stride[5]);
  731. +    }
  732. +}
  733. +
  734. +static int photon_encode_8x8(PhotonContext *s, int idx, int idct)
  735. +{
  736. +    int i,j,cbp = 0;
  737. +    DCTELEM dct[8][8];
  738. +    sub8x8_dct8(dct, s->fenc[idx], s->fdec[idx], s->fenc_stride[idx], s->fdec_stride[idx]);
  739. +    quant_8x8(dct, s->quant8_mf[s->mb_qp[idx]], s->quant8_bias[s->mb_qp[idx]]);
  740. +    zigzag_scan_8x8_frame( s->dct8x8[idx], dct);
  741. +    dequant_8x8(dct, s->dequant8_mf, s->mb_qp[idx]);
  742. +    for(i = 0; i < 8; i++)
  743. +        for(j = 0; j < 8; j++)
  744. +            if(dct[i][j])
  745. +            {
  746. +                cbp = 1;
  747. +                break;
  748. +            }
  749. +    if(cbp && idct)
  750. +        add8x8_idct8(s->fdec[idx], dct, s->fdec_stride[idx]);
  751. +    return cbp;
  752. +}
  753. +
  754. +static int photon_encode_4x4(PhotonContext *s, int idx, int subidx, int idct)
  755. +{
  756. +    int fdec_offset = s->fdec_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
  757. +    int fenc_offset = s->fenc_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
  758. +    int i,j,cbp = 1;
  759. +    DCTELEM dct[4][4];
  760. +    sub4x4_dct(dct, s->fenc[idx] + fenc_offset, s->fdec[idx] + fdec_offset,
  761. +                    s->fenc_stride[idx], s->fdec_stride[idx]);
  762. +    quant_4x4(dct, s->quant4_mf[s->mb_qp[idx]], s->quant4_bias[s->mb_qp[idx]]);
  763. +    zigzag_scan_4x4_frame( s->dct4x4[idx][subidx], dct);
  764. +    dequant_4x4(dct, s->dequant4_mf, s->mb_qp[idx]);
  765. +    for(i = 0; i < 4; i++)
  766. +        for(j = 0; j < 4; j++)
  767. +            if(dct[i][j])
  768. +            {
  769. +                cbp = 1;
  770. +                break;
  771. +            }
  772. +    if(cbp && idct)
  773. +        add4x4_idct(s->fdec[idx] + fdec_offset, dct, s->fdec_stride[idx]);
  774. +    return cbp;
  775. +}
  776. +
  777. +static void photon_write_8x8(PhotonContext *s, int idx)
  778. +{
  779. +    int i = 0;
  780. +    while(1)
  781. +    {
  782. +        int coeff = s->dct8x8[idx][i];
  783. +        int run = 0;
  784. +        set_se_golomb(&s->pb,coeff);
  785. +        i++;
  786. +        while(i < 64 && s->dct8x8[idx][i] == 0)
  787. +        {
  788. +            run++;
  789. +            i++;
  790. +        }
  791. +        if(i < 64) put_bits(&s->pb,1,0);
  792. +        else {put_bits(&s->pb,1,1);break;}
  793. +        set_ue_golomb(&s->pb,run);
  794. +    }
  795. +}
  796. +
  797. +static void photon_write_4x4(PhotonContext *s, int idx, int subidx)
  798. +{
  799. +    int i = 0;
  800. +    while(1)
  801. +    {
  802. +        int coeff = s->dct4x4[idx][subidx][i];
  803. +        int run = 0;
  804. +        set_se_golomb(&s->pb,coeff);
  805. +        i++;
  806. +        while(i < 16 && s->dct4x4[idx][subidx][i] == 0)
  807. +        {
  808. +            run++;
  809. +            i++;
  810. +        }
  811. +        if(i < 16) put_bits(&s->pb,1,0);
  812. +        else {put_bits(&s->pb,1,1);break;}
  813. +        set_ue_golomb(&s->pb,run);
  814. +    }
  815. +}
  816. +
  817. +static void photon_decode_residual_8x8(PhotonContext *s, int idx, int *qmul)
  818. +{
  819. +    int level, run, eob = 0, coeff = 0;
  820. +    DCTELEM dct[64];
  821. +    memset(dct,0,sizeof(int16_t)*64);
  822. +    while(1)
  823. +    {
  824. +        level = get_se_golomb(&s->gb);
  825. +        dct[zigzag_scan8x8[coeff]] = (level * qmul[zigzag_scan8x8[coeff]] + 32) >> 6;
  826. +        eob = get_bits1(&s->gb);
  827. +        if(eob) break;
  828. +        run = get_ue_golomb(&s->gb);
  829. +        coeff += run+1;
  830. +    }
  831. +    ff_h264_idct8_add_c(s->fdec[idx], dct, s->fdec_stride[idx]);
  832. +}
  833. +
  834. +static void photon_decode_residual_4x4(PhotonContext *s, int idx, int subidx, int *qmul)
  835. +{
  836. +    int offset = s->fdec_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
  837. +    int level, run, eob = 0, coeff = 0;
  838. +    DCTELEM dct[16];
  839. +    memset(dct,0,sizeof(DCTELEM)*16);
  840. +    while(1)
  841. +    {
  842. +        level = get_se_golomb(&s->gb);
  843. +        dct[zigzag_scan[coeff]] = (level * qmul[zigzag_scan[coeff]] + 8) >> 4;
  844. +        eob = get_bits1(&s->gb);
  845. +        if(eob) break;
  846. +        run = get_ue_golomb(&s->gb);
  847. +        coeff += run+1;
  848. +    }
  849. +    ff_h264_idct_add_c(s->fdec[idx] + offset, dct, s->fdec_stride[idx]);
  850. +}
  851. +
  852. +static void photon_decode_macroblock_residual(PhotonContext *s)
  853. +{
  854. +    int idx, subidx, cbp, subcbp, transform8x8;
  855. +    
  856. +    cbp = get_bits(&s->gb, 6);
  857. +    for(idx = 0; idx < 6; idx++)
  858. +    {
  859. +        if((cbp >> (5 - idx)) & 1)
  860. +        {
  861. +            /* decode delta quant */
  862. +            if(get_bits1(&s->gb))
  863. +            {
  864. +                if(get_bits1(&s->gb))
  865. +                    do
  866. +                    {
  867. +                        s->mb_qp[idx]++;
  868. +                    } while(get_bits1(&s->gb));
  869. +                else
  870. +                    do
  871. +                    {
  872. +                        s->mb_qp[idx]--;
  873. +                    } while(get_bits1(&s->gb));
  874. +                if(s->mb_qp[idx] < 0 || s->mb_qp[idx] > 51)
  875. +                {
  876. +                    av_log(s->avctx, AV_LOG_ERROR, "photon: quantizer %d out of range, clipping\n",s->mb_qp[idx]);
  877. +                    s->mb_qp[idx] = av_clip(s->mb_qp[idx],0,51);
  878. +                }
  879. +            }
  880. +            
  881. +            transform8x8 = get_bits1(&s->gb);
  882. +            if(transform8x8)
  883. +                photon_decode_residual_8x8(s,idx,s->dequant8_mf[s->mb_qp[idx]]);
  884. +            else
  885. +            {
  886. +                subcbp = get_bits(&s->gb, 4);
  887. +                for(subidx = 0; subidx < 4; subidx++)
  888. +                    if((subcbp >> (3 - subidx)) & 1)
  889. +                        photon_decode_residual_4x4(s,idx,subidx,s->dequant4_mf[s->mb_qp[idx]]);
  890. +            }
  891. +        }
  892. +    }
  893. +}
  894. +
  895. +static void photon_decode_macroblock(PhotonContext *s)
  896. +{
  897. +    /* Check for skip */
  898. +    int skip = 0;
  899. +    if(s->frame_type == PHOTON_FRAMETYPE_P)
  900. +    {
  901. +        skip = get_bits1(&s->gb);
  902. +        s->block_type = PHOTON_MBTYPE_SKIP;
  903. +        photon_predict_mv_skip(s);
  904. +        /* FIXME: MC needs to be done here. */
  905. +    }
  906. +    if(!skip)
  907. +    {
  908. +        /* MV prediction is done regardless of block type */
  909. +        photon_predict_mv(s);
  910. +
  911. +        /* Read block type */
  912. +        if(s->frame_type == PHOTON_FRAMETYPE_P)
  913. +            s->block_type = get_bits1(&s->gb);
  914. +        else s->block_type = PHOTON_MBTYPE_INTRA;
  915. +
  916. +        /* Read inter MVD */
  917. +        if(s->block_type == PHOTON_MBTYPE_INTER)
  918. +        {
  919. +            s->mv[0] += get_se_golomb(&s->gb);
  920. +            s->mv[1] += get_se_golomb(&s->gb);
  921. +            /* FIXME: MC needs to be done here. */
  922. +        }
  923. +        /* Read intra prediction type */
  924. +        else
  925. +        {
  926. +            if(get_bits1(&s->gb))
  927. +            {
  928. +                if(get_bits1(&s->gb))
  929. +                    pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
  930. +                else pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
  931. +            }
  932. +            else photon_predict_intra_dc(s);
  933. +            
  934. +            if(get_bits1(&s->gb))
  935. +            {
  936. +                if(get_bits1(&s->gb))
  937. +                {
  938. +                    pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
  939. +                    pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
  940. +                }
  941. +                else
  942. +                {
  943. +                    pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
  944. +                    pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
  945. +                }
  946. +            }
  947. +            else photon_predict_intra_chroma_dc(s);
  948. +        }
  949. +        photon_decode_macroblock_residual(s);
  950. +    }
  951. +}
  952. +
  953. +static int photon_decode_frame(AVCodecContext *avctx,
  954. +                             void *data, int *data_size,
  955. +                             const uint8_t *buf, int buf_size)
  956. +{
  957. +    int idx;
  958. +    PhotonContext *s = avctx->priv_data;
  959. +    if(s->frame.data[0])
  960. +        avctx->release_buffer(avctx, &s->frame);
  961. +    if(avctx->get_buffer(avctx, &s->frame) < 0)
  962. +    {
  963. +        av_log(s->avctx, AV_LOG_ERROR, "photon: get_buffer() failed\n");
  964. +        return -1;
  965. +    }
  966. +    init_get_bits(&s->gb, buf, buf_size);
  967. +    /* 1 == P-frame, 0 == I-frame */
  968. +    s->frame_type = get_bits1(&s->gb);
  969. +    if(s->frame_type) av_log(s->avctx, AV_LOG_ERROR, "P-FRAMES NOT SUPPORTED: %d\n",s->mb_xy);
  970. +    s->frame_qp = get_bits(&s->gb,6);
  971. +    if(s->frame_qp > 51)
  972. +    {
  973. +        av_log(s->avctx, AV_LOG_ERROR, "photon: frame quantizer (%d) is out of range\n", s->frame_qp);
  974. +        return -1;
  975. +    }
  976. +    
  977. +    /* For the first macroblock, the last MB QP is defined as the frame QP. */
  978. +    for(idx = 0; idx < 6; idx++)
  979. +        s->last_mb_qp[idx] = s->frame_qp;
  980. +
  981. +    s->fdec_stride[0] = s->fdec_stride[1] = s->fdec_stride[2] = s->fdec_stride[3] = s->frame.linesize[0];
  982. +    s->fdec_stride[4] = s->frame.linesize[1];
  983. +    s->fdec_stride[5] = s->frame.linesize[2];
  984. +    
  985. +    for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++)
  986. +    {
  987. +        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++)
  988. +        {
  989. +            s->mb_xy = s->mb_x + s->mb_y * s->mb_width;            
  990. +            for(idx = 0; idx < 6; idx++)
  991. +                s->mb_qp[idx] = s->last_mb_qp[idx];
  992. +
  993. +            /* Initialize block pointers */
  994. +            s->fdec[0] = s->frame.data[0] + s->mb_x * 16 + s->fdec_stride[0] * s->mb_y * 16;
  995. +            s->fdec[1] = s->fdec[0] + 8;
  996. +            s->fdec[2] = s->fdec[0] + s->fdec_stride[0] * 8;
  997. +            s->fdec[3] = s->fdec[2] + 8;
  998. +            s->fdec[4] = s->frame.data[1] + s->mb_x * 8 + s->fdec_stride[4] * s->mb_y * 8;
  999. +            s->fdec[5] = s->frame.data[2] + s->mb_x * 8 + s->fdec_stride[5] * s->mb_y * 8;
  1000. +            
  1001. +            photon_decode_macroblock(s);
  1002. +
  1003. +            /* Store the MV for this block */
  1004. +            s->mb_mv[s->mb_xy][0] = s->mv[0];
  1005. +            s->mb_mv[s->mb_xy][1] = s->mv[1];
  1006. +            for(idx = 0; idx < 6; idx++)
  1007. +                s->last_mb_qp[idx] = s->mb_qp[idx];
  1008. +        }
  1009. +    }
  1010. +    *data_size = sizeof(AVFrame);
  1011. +    *(AVFrame*)data= s->frame;
  1012. +    return get_bits_count(&s->gb)/8;
  1013. +}
  1014. +
  1015. +static void photon_analyse_intra(PhotonContext *s)
  1016. +{
  1017. +    int bcost,cost;
  1018. +    s->intra_pred_luma = PHOTON_INTRA_MODE_DC;
  1019. +    photon_predict_intra_dc(s);
  1020. +    bcost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
  1021. +    if(s->mb_y > 0)
  1022. +    {
  1023. +        pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
  1024. +        cost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
  1025. +        if(cost < bcost)
  1026. +        {
  1027. +            s->intra_pred_luma = PHOTON_INTRA_MODE_V;
  1028. +            bcost = cost;
  1029. +        }
  1030. +    }
  1031. +    if(s->mb_x > 0)
  1032. +    {
  1033. +        pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
  1034. +        cost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
  1035. +        if(cost < bcost)
  1036. +        {
  1037. +            s->intra_pred_luma = PHOTON_INTRA_MODE_H;
  1038. +            bcost = cost;
  1039. +        }
  1040. +    }
  1041. +}
  1042. +
  1043. +static void photon_analyse_intra_chroma(PhotonContext *s)
  1044. +{
  1045. +    int bcost,cost;
  1046. +    s->intra_pred_chroma = PHOTON_INTRA_MODE_DC;
  1047. +    photon_predict_intra_chroma_dc(s);
  1048. +    bcost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
  1049. +          + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
  1050. +    if(s->mb_y > 0)
  1051. +    {
  1052. +        pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
  1053. +        pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
  1054. +        cost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
  1055. +             + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
  1056. +        if(cost < bcost)
  1057. +        {
  1058. +            s->intra_pred_chroma = PHOTON_INTRA_MODE_V;
  1059. +            bcost = cost;
  1060. +        }
  1061. +    }
  1062. +    if(s->mb_x > 0)
  1063. +    {
  1064. +        pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
  1065. +        pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
  1066. +        cost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
  1067. +             + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
  1068. +        if(cost < bcost)
  1069. +        {
  1070. +            s->intra_pred_chroma = PHOTON_INTRA_MODE_H;
  1071. +            bcost = cost;
  1072. +        }
  1073. +    }
  1074. +}
  1075. +
  1076. +static int size_ue_golomb(int n)
  1077. +{
  1078. +    return av_log2(n+1) * 2;
  1079. +}
  1080. +
  1081. +static int size_se_golomb(int n)
  1082. +{
  1083. +    if(n < 0) n = -2*n;
  1084. +    else      n = 2*n - 1;
  1085. +    return size_ue_golomb(n);
  1086. +}
  1087. +
  1088. +static int photon_cost_8x8(PhotonContext *s, int idx)
  1089. +{
  1090. +    int cost = 0, i = 0;
  1091. +    while(1)
  1092. +    {
  1093. +        int coeff = s->dct8x8[idx][i];
  1094. +        int run = 0;
  1095. +        cost += size_se_golomb(coeff);
  1096. +        i++;
  1097. +        while(i < 64 && s->dct8x8[idx][i] == 0)
  1098. +        {
  1099. +            run++;
  1100. +            i++;
  1101. +        }
  1102. +        cost++;
  1103. +        if(i >= 64) break;
  1104. +        cost += size_ue_golomb(run);
  1105. +    }
  1106. +    return cost;
  1107. +}
  1108. +
  1109. +static int photon_cost_4x4(PhotonContext *s, int idx, int subidx)
  1110. +{
  1111. +    int cost = 0, i = 0;
  1112. +    while(1)
  1113. +    {
  1114. +        int coeff = s->dct4x4[idx][subidx][i];
  1115. +        int run = 0;
  1116. +        cost += size_se_golomb(coeff);
  1117. +        i++;
  1118. +        while(i < 16 && s->dct4x4[idx][subidx][i] == 0)
  1119. +        {
  1120. +            run++;
  1121. +            i++;
  1122. +        }
  1123. +        cost++;
  1124. +        if(i >= 16) break;
  1125. +        cost += size_ue_golomb(run);
  1126. +    }
  1127. +    return cost;
  1128. +}
  1129. +
  1130. +static int photon_analyse_transform(PhotonContext *s, int idx)
  1131. +{
  1132. +    int cost4x4 = 4, cost8x8 = 0, subidx, cbp = 0;
  1133. +    if(photon_encode_8x8(s, idx, 0))
  1134. +        cost8x8 = photon_cost_8x8(s, idx);
  1135. +    for(subidx = 0; subidx < 4; subidx++)
  1136. +    {
  1137. +        if(photon_encode_4x4(s, idx, subidx, 0))
  1138. +        {
  1139. +            cost4x4 += photon_cost_4x4(s, idx, subidx);
  1140. +            cbp = 1;
  1141. +        }
  1142. +    }
  1143. +    if(!cbp) cost4x4 = 0;
  1144. +    if(cost8x8 > cost4x4) return 0;
  1145. +    else return 1;
  1146. +}
  1147. +
  1148. +static void photon_adaptive_quant(PhotonContext *s, int idx)
  1149. +{
  1150. +    static uint8_t zero[8] = {0,0,0,0,0,0,0,0};
  1151. +    float qp_adj;
  1152. +    int sad, ssd, total;
  1153. +
  1154. +    if(idx == 4 || idx == 5) /* no chroma QP offset for now */
  1155. +    {
  1156. +        s->mb_qp[idx] = s->frame_qp;
  1157. +    }
  1158. +    ssd = ssd8x8(s->fenc[idx],s->fenc_stride[idx],zero,0);
  1159. +    sad = sad8x8(s->fenc[idx],s->fenc_stride[idx],zero,0);
  1160. +    total = ssd - ((sad * sad) >> 6);
  1161. +    if(total == 0) total = 1;
  1162. +    qp_adj = 1.5 * (logf(total) - logf(1000));
  1163. +    s->mb_qp[idx] = av_clip(s->frame_qp + qp_adj + 0.5,0,51);
  1164. +}
  1165. +
  1166. +static int photon_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
  1167. +{
  1168. +    int idx, subidx, cbp;
  1169. +    int total_quant = 0, num_quant = 0;
  1170. +    PhotonContext *s = avctx->priv_data;
  1171. +    AVFrame *cur_frame = data;
  1172. +    if(s->frame.data[0])
  1173. +        avctx->release_buffer(avctx, &s->frame);
  1174. +    if(avctx->get_buffer(avctx, &s->frame) < 0)
  1175. +    {
  1176. +        av_log(s->avctx, AV_LOG_ERROR, "photon: get_buffer() failed\n");
  1177. +        return -1;
  1178. +    }
  1179. +    avctx->coded_frame = &s->frame;
  1180. +    
  1181. +    s->fdec_stride[0] = s->fdec_stride[1] = s->fdec_stride[2] = s->fdec_stride[3] = s->frame.linesize[0];
  1182. +    s->fdec_stride[4] = s->frame.linesize[1];
  1183. +    s->fdec_stride[5] = s->frame.linesize[2];
  1184. +    s->fenc_stride[0] = s->fenc_stride[1] = s->fenc_stride[2] = s->fenc_stride[3] = cur_frame->linesize[0];
  1185. +    s->fenc_stride[4] = cur_frame->linesize[1];
  1186. +    s->fenc_stride[5] = cur_frame->linesize[2];
  1187. +    s->frame_qp = avctx->cqp == -1 ? 26 : avctx->cqp; /* CQP */
  1188. +    if(s->frame_qp < 0 || s->frame_qp > 51)
  1189. +    {
  1190. +        av_log(s->avctx, AV_LOG_ERROR, "photon: QP %d out of range\n",s->frame_qp);
  1191. +        return -1;
  1192. +    }
  1193. +    for(idx = 0; idx < 6; idx++)
  1194. +        s->last_mb_qp[idx] = s->frame_qp;
  1195. +
  1196. +    init_put_bits(&s->pb, buf, buf_size);
  1197. +    /* I-frames only */
  1198. +    put_bits(&s->pb,1,PHOTON_FRAMETYPE_I);
  1199. +    s->frame.key_frame = 1;
  1200. +    s->frame.pict_type = FF_I_TYPE;
  1201. +    
  1202. +    put_bits(&s->pb,6,s->frame_qp);
  1203. +    assert(s->fdec_stride[0] == s->fenc_stride[0]);
  1204. +    for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++)
  1205. +    {
  1206. +        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++)
  1207. +        {
  1208. +            s->mb_xy = s->mb_x + s->mb_y * s->mb_width;
  1209. +            for(idx = 0; idx < 6; idx++)
  1210. +                s->mb_qp[idx] = s->last_mb_qp[idx];
  1211. +            
  1212. +            s->fdec[0] = s->frame.data[0] + s->mb_x * 16 + s->fdec_stride[0] * s->mb_y * 16;
  1213. +            s->fdec[1] = s->fdec[0] + 8;
  1214. +            s->fdec[2] = s->fdec[0] + s->fdec_stride[0] * 8;
  1215. +            s->fdec[3] = s->fdec[2] + 8;
  1216. +            s->fdec[4] = s->frame.data[1] + s->mb_x * 8 + s->fdec_stride[4] * s->mb_y * 8;
  1217. +            s->fdec[5] = s->frame.data[2] + s->mb_x * 8 + s->fdec_stride[5] * s->mb_y * 8;
  1218. +            
  1219. +            s->fenc[0] = cur_frame->data[0] + s->mb_x * 16 + s->fenc_stride[0] * s->mb_y * 16;
  1220. +            s->fenc[1] = s->fenc[0] + 8;
  1221. +            s->fenc[2] = s->fenc[0] + s->fenc_stride[0] * 8;
  1222. +            s->fenc[3] = s->fenc[2] + 8;
  1223. +            s->fenc[4] = cur_frame->data[1] + s->mb_x * 8 + s->fenc_stride[4] * s->mb_y * 8;
  1224. +            s->fenc[5] = cur_frame->data[2] + s->mb_x * 8 + s->fenc_stride[5] * s->mb_y * 8;
  1225. +            
  1226. +            /* Intra prediction */
  1227. +            photon_analyse_intra(s);
  1228. +            
  1229. +            if(s->intra_pred_luma == PHOTON_INTRA_MODE_DC)
  1230. +            {
  1231. +                photon_predict_intra_dc(s);
  1232. +                put_bits(&s->pb,1,0);
  1233. +            }
  1234. +            else if(s->intra_pred_luma == PHOTON_INTRA_MODE_V)
  1235. +            {
  1236. +                pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
  1237. +                put_bits(&s->pb,1,1);
  1238. +                put_bits(&s->pb,1,0);
  1239. +            }
  1240. +            else if(s->intra_pred_luma == PHOTON_INTRA_MODE_H)
  1241. +            {
  1242. +                pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
  1243. +                put_bits(&s->pb,1,1);
  1244. +                put_bits(&s->pb,1,1);
  1245. +            }
  1246. +            
  1247. +            photon_analyse_intra_chroma(s);
  1248. +            
  1249. +            if(s->intra_pred_chroma == PHOTON_INTRA_MODE_DC)
  1250. +            {
  1251. +                photon_predict_intra_chroma_dc(s);
  1252. +                put_bits(&s->pb,1,0);
  1253. +            }
  1254. +            else if(s->intra_pred_chroma == PHOTON_INTRA_MODE_V)
  1255. +            {
  1256. +                pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
  1257. +                pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
  1258. +                put_bits(&s->pb,1,1);
  1259. +                put_bits(&s->pb,1,0);
  1260. +            }
  1261. +            else if(s->intra_pred_chroma == PHOTON_INTRA_MODE_H)
  1262. +            {
  1263. +                pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
  1264. +                pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
  1265. +                put_bits(&s->pb,1,1);
  1266. +                put_bits(&s->pb,1,1);
  1267. +            }
  1268. +
  1269. +            cbp = 0;
  1270. +            for(idx = 0; idx < 6; idx++)
  1271. +            {
  1272. +                photon_adaptive_quant(s, idx);
  1273. +                s->transform8x8[idx] = photon_analyse_transform(s, idx);
  1274. +                cbp <<= 1;
  1275. +                if(s->transform8x8[idx])
  1276. +                {
  1277. +                    s->subcbp[idx] = 0;
  1278. +                    cbp += photon_encode_8x8(s, idx, 1);
  1279. +                }
  1280. +                else
  1281. +                {
  1282. +                    s->subcbp[idx] = 0;
  1283. +                    for(subidx = 0; subidx < 4; subidx++)
  1284. +                    {
  1285. +                        s->subcbp[idx] <<= 1;
  1286. +                        s->subcbp[idx] += photon_encode_4x4(s, idx, subidx, 1);
  1287. +                    }
  1288. +                    cbp += (!!s->subcbp[idx]);
  1289. +                }
  1290. +            }
  1291. +            put_bits(&s->pb,6,cbp);
  1292. +            for(idx = 0; idx < 6; idx++)
  1293. +            {
  1294. +                if((cbp >> (5 - idx)) & 1)
  1295. +                {
  1296. +                    /* encode delta quant */
  1297. +                    if(s->mb_qp[idx] != s->last_mb_qp[idx])
  1298. +                    {
  1299. +                        int dqp = s->mb_qp[idx] - s->last_mb_qp[idx];
  1300. +                        put_bits(&s->pb,1,1);
  1301. +                        if(dqp > 0) put_bits(&s->pb,1,1);
  1302. +                        else put_bits(&s->pb,1,0);
  1303. +                        dqp = abs(dqp) - 1;
  1304. +                        while(dqp)
  1305. +                        {
  1306. +                            dqp--;
  1307. +                            put_bits(&s->pb,1,1);
  1308. +                        }
  1309. +                    }
  1310. +                    put_bits(&s->pb,1,0);
  1311. +
  1312. +                    put_bits(&s->pb,1,s->transform8x8[idx]);
  1313. +                    if(s->transform8x8[idx])
  1314. +                        photon_write_8x8(s, idx);
  1315. +                    else
  1316. +                    {
  1317. +                        put_bits(&s->pb,4,s->subcbp[idx]);
  1318. +                        for(subidx = 0; subidx < 4; subidx++)
  1319. +                            if(s->subcbp[idx] >> (3 - subidx))
  1320. +                                photon_write_4x4(s, idx, subidx);
  1321. +                    }
  1322. +                    total_quant += s->mb_qp[idx];
  1323. +                    num_quant++;
  1324. +                }
  1325. +                else s->mb_qp[idx] = s->last_mb_qp[idx];
  1326. +            }
  1327. +            for(idx = 0; idx < 6; idx++)
  1328. +                s->last_mb_qp[idx] = s->mb_qp[idx];
  1329. +        }
  1330. +    }
  1331. +    if(num_quant == 0)
  1332. +        s->frame.quality = 0;
  1333. +    else
  1334. +        s->frame.quality = (total_quant / num_quant) * FF_QP2LAMBDA;
  1335. +    flush_put_bits(&s->pb);
  1336. +    return put_bits_count(&s->pb)/8;
  1337. +}
  1338. +
  1339. +AVCodec photon_decoder =
  1340. +{
  1341. +    .name = "photon",
  1342. +    .type = CODEC_TYPE_VIDEO,
  1343. +    .id = CODEC_ID_PHOTON,
  1344. +    .priv_data_size = sizeof(PhotonContext),
  1345. +    .init = photon_decode_init,
  1346. +    .close = photon_decode_close,
  1347. +    .decode = photon_decode_frame,
  1348. +    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
  1349. +    .long_name = "Photon MPEG-like codec"
  1350. +};
  1351. +
  1352. +AVCodec photon_encoder =
  1353. +{
  1354. +    .name = "photon",
  1355. +    .type = CODEC_TYPE_VIDEO,
  1356. +    .id = CODEC_ID_PHOTON,
  1357. +    .priv_data_size = sizeof(PhotonContext),
  1358. +    .init = photon_encode_init,
  1359. +    .close = photon_encode_close,
  1360. +    .encode = photon_encode_frame,
  1361. +    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
  1362. +    .long_name = "Photon MPEG-like codec"
  1363. +};
  1364. +
  1365.  
  1366. Property changes on: libavcodec/photon.c
  1367. ___________________________________________________________________
  1368. Name: svn:executable
  1369.    + *
  1370.  
  1371. Index: libavcodec/allcodecs.c
  1372. ===================================================================
  1373. --- libavcodec/allcodecs.c      (revision 13076)
  1374. +++ libavcodec/allcodecs.c      (working copy)
  1375.  -126,6 +126,7 @@
  1376.      REGISTER_DECODER (PCX, pcx);
  1377.      REGISTER_ENCODER (PGM, pgm);
  1378.      REGISTER_ENCODER (PGMYUV, pgmyuv);
  1379. +    REGISTER_ENCDEC  (PHOTON, photon);
  1380.      REGISTER_ENCDEC  (PNG, png);
  1381.      REGISTER_ENCODER (PPM, ppm);
  1382.      REGISTER_DECODER (PTX, ptx);
  1383. Index: libavcodec/avcodec.h
  1384. ===================================================================
  1385. --- libavcodec/avcodec.h        (revision 13076)
  1386. +++ libavcodec/avcodec.h        (working copy)
  1387.  -186,6 +186,7 @@
  1388.      CODEC_ID_ESCAPE124,
  1389.      CODEC_ID_DIRAC,
  1390.      CODEC_ID_BFI,
  1391. +    CODEC_ID_PHOTON,
  1392.  
  1393.      /* various PCM "codecs" */
  1394.      CODEC_ID_PCM_S16LE= 0x10000,
  1395. Index: libavformat/riff.c
  1396. ===================================================================
  1397. --- libavformat/riff.c  (revision 13076)
  1398. +++ libavformat/riff.c  (working copy)
  1399.  -160,6 +160,7 @@
  1400.      { CODEC_ID_VMNC,         MKTAG('V', 'M', 'n', 'c') },
  1401.      { CODEC_ID_TARGA,        MKTAG('t', 'g', 'a', ' ') },
  1402.      { CODEC_ID_CLJR,         MKTAG('c', 'l', 'j', 'r') },
  1403. +    { CODEC_ID_PHOTON,       MKTAG('P', 'H', 'T', 'N') },
  1404.      { CODEC_ID_NONE,         0 }
  1405.  };