pastebin - collaborative debugging

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

This site is developed to XHTML and CSS2 W3C standards. If you see this paragraph, your browser does not support those standards and you need to upgrade. Visit WaSP for a variety of options.

Diff pastebin - collaborative debugging tool View Help


Posted by Dark Shikari on Sun 11 May 03:14
report abuse | download | new post

  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.  };

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with @@


Remember me so that I can delete my post