Posted by Dark Shikari on Sun 11 May 03:14
report abuse | download | new post
- Index: libavcodec/Makefile
- ===================================================================
- --- libavcodec/Makefile (revision 13076)
- +++ libavcodec/Makefile (working copy)
- -143,6 +143,8 @@
- OBJS-$(CONFIG_PCX_DECODER) += pcx.o
- OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o
- OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o
- +OBJS-$(CONFIG_PHOTON_DECODER) += photon.o
- +OBJS-$(CONFIG_PHOTON_ENCODER) += photon.o
- OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o
- OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
- OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o
- Index: libavcodec/h264data.h
- ===================================================================
- --- libavcodec/h264data.h (revision 13076)
- +++ libavcodec/h264data.h (working copy)
- -545,6 +545,25 @@
- {36,32,58,34,46,43},
- };
- +static const int quant4_coeff_init[6][3] =
- +{
- + { 13107, 8066, 5243 },
- + { 11916, 7490, 4660 },
- + { 10082, 6554, 4194 },
- + { 9362, 5825, 3647 },
- + { 8192, 5243, 3355 },
- + { 7282, 4559, 2893 },
- +};
- +static const int quant8_coeff_init[6][6] =
- +{
- + { 13107, 11428, 20972, 12222, 16777, 15481 },
- + { 11916, 10826, 19174, 11058, 14980, 14290 },
- + { 10082, 8943, 15978, 9675, 12710, 11985 },
- + { 9362, 8228, 14913, 8931, 11984, 11259 },
- + { 8192, 7346, 13159, 7740, 10486, 9777 },
- + { 7282, 6428, 11570, 6830, 9118, 8640 }
- +};
- +
- #define QUANT_SHIFT 22
- static const int quant_coeff[52][16]={
- Index: libavcodec/photon.c
- ===================================================================
- --- libavcodec/photon.c (revision 0)
- +++ libavcodec/photon.c (revision 0)
- -0,0 +1,1316 @@
- +/*
- + * Photon (PHTN) Video Encoder and Decoder
- + * by Jason Garrett-Glaser (darkshikari@gmail.com)
- + *
- + * Copyright (C) 2008 the ffmpeg project
- + *
- + * This file is part of FFmpeg.
- + *
- + * FFmpeg is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public
- + * License as published by the Free Software Foundation; either
- + * version 2 of the License, or (at your option) any later version.
- + *
- + * FFmpeg is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- + * Lesser General Public License for more details.
- + *
- + * You should have received a copy of the GNU Lesser General Public
- + * License along with FFmpeg; if not, write to the Free Software
- + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- + */
- +
- + /**
- + * @file photon.c
- + * Photon Video Encoder and Decoder
- + */
- +
- +#include <stdio.h>
- +#include <stdlib.h>
- +#include <string.h>
- +#include <unistd.h>
- +
- +#include "avcodec.h"
- +#include "dsputil.h"
- +#include "bitstream.h"
- +#include "golomb.h"
- +#include "h264pred.h"
- +#include "h264pred.c"
- +#include "h264data.h"
- +#include "dsputil.h"
- +//#include "dsputil.c"
- +
- +#define GLOBAL_DEADZONE 0
- +
- +#define PHOTON_FRAMETYPE_P 1
- +#define PHOTON_FRAMETYPE_I 0
- +
- +#define PHOTON_MBTYPE_SKIP 2
- +#define PHOTON_MBTYPE_INTER 1
- +#define PHOTON_MBTYPE_INTRA 0
- +
- +#define PHOTON_INTRA_MODE_DC 0
- +#define PHOTON_INTRA_MODE_V 1
- +#define PHOTON_INTRA_MODE_H 2
- +
- +typedef struct PhotonContext {
- + AVCodecContext *avctx;
- + AVFrame frame;
- + GetBitContext gb;
- + PutBitContext pb;
- + int mb_x;
- + int mb_y;
- + int mb_xy;
- + int mb_width;
- + int mb_height;
- + int frame_type;
- + int frame_qp;
- + int block_type; /* 1 = inter, 0 = intra */
- + int mb_qp[6];
- + int last_mb_qp[6];
- + int mv[2];
- + int16_t (*mb_mv)[2]; /* array of framewide mb_mv values */
- + uint8_t *fdec[6];
- + uint8_t *fenc[6];
- + int fdec_stride[6];
- + int fenc_stride[6];
- +
- + int intra_pred_luma;
- + int intra_pred_chroma;
- +
- + int transform8x8[6];
- + int subcbp[6];
- + int16_t dct4x4[6][4][16];
- + int16_t dct8x8[6][64];
- +
- + int dequant4_mf[52][16];
- + int dequant8_mf[52][64];
- + int quant4_mf[52][16];
- + int quant8_mf[52][64];
- + int quant4_bias[52][16];
- + int quant8_bias[52][64];
- +} PhotonContext;
- +
- +#define SHIFT(x,s) ((s)<0 ? (x)<<-(s) : (s)==0 ? (x) : ((x)+(1<<((s)-1)))>>(s))
- +#define DIV(n,d) (((n) + ((d)>>1)) / (d))
- +
- +static void init_quant_tables(PhotonContext *s)
- +{
- + int def_quant4[6][16];
- + int def_quant8[6][64];
- + int def_dequant4[6][16];
- + int def_dequant8[6][64];
- + int quant4_mf[6][16];
- + int quant8_mf[6][64];
- + int q, i, j;
- + int deadzone = 32 - GLOBAL_DEADZONE; /* Constant deadzone to start */
- +
- + for( q = 0; q < 6; q++ )
- + {
- + for( i = 0; i < 16; i++ )
- + {
- + int j = (i&1) + ((i>>2)&1);
- + def_dequant4[q][i] = dequant4_coeff_init[q][j];
- + def_quant4[q][i] = quant4_coeff_init[q][j];
- + }
- + for( i = 0; i < 64; i++ )
- + {
- + int j = dequant8_coeff_init_scan[((i>>1)&12) | (i&3)];
- + def_dequant8[q][i] = dequant8_coeff_init[q][j];
- + def_quant8[q][i] = quant8_coeff_init[q][j];
- + }
- + }
- +
- + for( q = 0; q < 52; q++ )
- + {
- + for( i = 0; i < 16; i++ )
- + s->dequant4_mf[q][i] = (def_dequant4[q%6][i] * 16) << (q/6);
- + for( i = 0; i < 64; i++ )
- + s->dequant8_mf[q][i] = (def_dequant8[q%6][i] * 16) << (q/6);
- + }
- + for( q = 0; q < 6; q++ )
- + {
- + for( i = 0; i < 16; i++ )
- + quant4_mf[q][i] = def_quant4[q][i];
- + for( i = 0; i < 64; i++ )
- + quant8_mf[q][i] = def_quant8[q][i];
- + }
- + for( q = 0; q < 52; q++ )
- + {
- + for( i = 0; i < 16; i++ )
- + {
- + s-> quant4_mf[q][i] = j = SHIFT(quant4_mf[q%6][i], q/6 - 1);
- + s->quant4_bias[q][i] = FFMIN( DIV(deadzone<<10, j), (1<<15)/j );
- + }
- + for( i = 0; i < 64; i++ )
- + {
- + s-> quant8_mf[q][i] = j = SHIFT(quant8_mf[q%6][i], q/6);
- + s->quant8_bias[q][i] = FFMIN( DIV(deadzone<<10, j), (1<<15)/j );
- + }
- + }
- +}
- +
- +static int photon_decode_init(AVCodecContext *avctx)
- +{
- + PhotonContext *s = avctx->priv_data;
- +
- + /* Codec doesn't currently support non-mod16 resolutions. */
- + if(avctx->width % 16 != 0 || avctx->height % 16 != 0)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon does not support non-mod16 resolutions");
- + return -1;
- + }
- +
- + s->avctx = avctx;
- + s->mb_width = avctx->width / 16;
- + s->mb_height = avctx->height / 16;
- +
- + s->mb_mv = av_mallocz(s->mb_width * s->mb_height * sizeof(int16_t) * 2);
- +
- + if(!s->mb_mv)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: malloc failure");
- + return -1;
- + }
- +
- + avctx->pix_fmt = PIX_FMT_YUV420P;
- + init_quant_tables(s);
- +
- + return 0;
- +}
- +
- +static int photon_encode_init(AVCodecContext *avctx)
- +{
- + return photon_decode_init(avctx);
- +}
- +
- +static int photon_decode_close(AVCodecContext *avctx)
- +{
- + return 0;
- +}
- +
- +static int photon_encode_close(AVCodecContext *avctx)
- +{
- + return 0;
- +}
- +
- +#define SAD(num)\
- +static int sad##num##x##num(uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2)\
- +{\
- + int i,j,sum=0;\
- + for(i = 0; i < num; i++)\
- + {\
- + for(j = 0; j < num; j++)\
- + sum += abs(pix1[j]-pix2[j]);\
- + pix1 += i_pix1;\
- + pix2 += i_pix2;\
- + }\
- + return sum;\
- +}
- +
- +SAD(16)
- +SAD(8)
- +
- +#define SSD(num)\
- +static int ssd##num##x##num(uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2)\
- +{\
- + int i,j,sum=0;\
- + for(i = 0; i < num; i++)\
- + {\
- + for(j = 0; j < num; j++) {\
- + int n = pix1[j]-pix2[j];\
- + sum += n*n;\
- + }\
- + pix1 += i_pix1;\
- + pix2 += i_pix2;\
- + }\
- + return sum;\
- +}
- +
- +SSD(8)
- +
- +/* H.264 HCT */
- +/* Code from x264 */
- +
- +static void pixel_sub_wxh( int16_t *diff, int i_size,
- + uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
- +{
- + int y, x;
- + for( y = 0; y < i_size; y++ )
- + {
- + for( x = 0; x < i_size; x++ )
- + {
- + diff[x + y*i_size] = pix1[x] - pix2[x];
- + }
- + pix1 += i_pix1;
- + pix2 += i_pix2;
- + }
- +}
- +
- +static void sub4x4_dct( DCTELEM dct[4][4], uint8_t *pix1, uint8_t *pix2, int fenc_stride, int fdec_stride )
- +{
- + DCTELEM d[4][4];
- + DCTELEM tmp[4][4];
- + int i;
- +
- + pixel_sub_wxh( (DCTELEM*)d, 4, pix1, fenc_stride, pix2, fdec_stride );
- +
- + for( i = 0; i < 4; i++ )
- + {
- + const int s03 = d[i][0] + d[i][3];
- + const int s12 = d[i][1] + d[i][2];
- + const int d03 = d[i][0] - d[i][3];
- + const int d12 = d[i][1] - d[i][2];
- +
- + tmp[0][i] = s03 + s12;
- + tmp[1][i] = 2*d03 + d12;
- + tmp[2][i] = s03 - s12;
- + tmp[3][i] = d03 - 2*d12;
- + }
- +
- + for( i = 0; i < 4; i++ )
- + {
- + const int s03 = tmp[i][0] + tmp[i][3];
- + const int s12 = tmp[i][1] + tmp[i][2];
- + const int d03 = tmp[i][0] - tmp[i][3];
- + const int d12 = tmp[i][1] - tmp[i][2];
- +
- + dct[i][0] = s03 + s12;
- + dct[i][1] = 2*d03 + d12;
- + dct[i][2] = s03 - s12;
- + dct[i][3] = d03 - 2*d12;
- + }
- +}
- +
- +#define DCT8_1D {\
- + const int s07 = SRC(0) + SRC(7);\
- + const int s16 = SRC(1) + SRC(6);\
- + const int s25 = SRC(2) + SRC(5);\
- + const int s34 = SRC(3) + SRC(4);\
- + const int a0 = s07 + s34;\
- + const int a1 = s16 + s25;\
- + const int a2 = s07 - s34;\
- + const int a3 = s16 - s25;\
- + const int d07 = SRC(0) - SRC(7);\
- + const int d16 = SRC(1) - SRC(6);\
- + const int d25 = SRC(2) - SRC(5);\
- + const int d34 = SRC(3) - SRC(4);\
- + const int a4 = d16 + d25 + (d07 + (d07>>1));\
- + const int a5 = d07 - d34 - (d25 + (d25>>1));\
- + const int a6 = d07 + d34 - (d16 + (d16>>1));\
- + const int a7 = d16 - d25 + (d34 + (d34>>1));\
- + DST(0) = a0 + a1 ;\
- + DST(1) = a4 + (a7>>2);\
- + DST(2) = a2 + (a3>>1);\
- + DST(3) = a5 + (a6>>2);\
- + DST(4) = a0 - a1 ;\
- + DST(5) = a6 - (a5>>2);\
- + DST(6) = (a2>>1) - a3 ;\
- + DST(7) = (a4>>2) - a7 ;\
- +}
- +
- +static void sub8x8_dct8( DCTELEM dct[8][8], uint8_t *pix1, uint8_t *pix2, int fenc_stride, int fdec_stride )
- +{
- + int i;
- + DCTELEM tmp[8][8];
- +
- + pixel_sub_wxh( (DCTELEM*)tmp, 8, pix1, fenc_stride, pix2, fdec_stride );
- +
- +#define SRC(x) tmp[x][i]
- +#define DST(x) tmp[x][i]
- + for( i = 0; i < 8; i++ )
- + DCT8_1D
- +#undef SRC
- +#undef DST
- +
- +#define SRC(x) tmp[i][x]
- +#define DST(x) dct[x][i]
- + for( i = 0; i < 8; i++ )
- + DCT8_1D
- +#undef SRC
- +#undef DST
- +}
- +
- +static void add4x4_idct( uint8_t *p_dst, DCTELEM dct[4][4], int stride )
- +{
- + int16_t d[4][4];
- + int16_t tmp[4][4];
- + int x, y;
- + int i;
- +
- + for( i = 0; i < 4; i++ )
- + {
- + const int s02 = dct[0][i] + dct[2][i];
- + const int d02 = dct[0][i] - dct[2][i];
- + const int s13 = dct[1][i] + (dct[3][i]>>1);
- + const int d13 = (dct[1][i]>>1) - dct[3][i];
- +
- + tmp[i][0] = s02 + s13;
- + tmp[i][1] = d02 + d13;
- + tmp[i][2] = d02 - d13;
- + tmp[i][3] = s02 - s13;
- + }
- +
- + for( i = 0; i < 4; i++ )
- + {
- + const int s02 = tmp[0][i] + tmp[2][i];
- + const int d02 = tmp[0][i] - tmp[2][i];
- + const int s13 = tmp[1][i] + (tmp[3][i]>>1);
- + const int d13 = (tmp[1][i]>>1) - tmp[3][i];
- +
- + d[0][i] = ( s02 + s13 + 32 ) >> 6;
- + d[1][i] = ( d02 + d13 + 32 ) >> 6;
- + d[2][i] = ( d02 - d13 + 32 ) >> 6;
- + d[3][i] = ( s02 - s13 + 32 ) >> 6;
- + }
- +
- +
- + for( y = 0; y < 4; y++ )
- + {
- + for( x = 0; x < 4; x++ )
- + {
- + p_dst[x] = av_clip_uint8( p_dst[x] + d[y][x] );
- + }
- + p_dst += stride;
- + }
- +}
- +
- +#define IDCT8_1D {\
- + const int a0 = SRC(0) + SRC(4);\
- + const int a2 = SRC(0) - SRC(4);\
- + const int a4 = (SRC(2)>>1) - SRC(6);\
- + const int a6 = (SRC(6)>>1) + SRC(2);\
- + const int b0 = a0 + a6;\
- + const int b2 = a2 + a4;\
- + const int b4 = a2 - a4;\
- + const int b6 = a0 - a6;\
- + const int a1 = -SRC(3) + SRC(5) - SRC(7) - (SRC(7)>>1);\
- + const int a3 = SRC(1) + SRC(7) - SRC(3) - (SRC(3)>>1);\
- + const int a5 = -SRC(1) + SRC(7) + SRC(5) + (SRC(5)>>1);\
- + const int a7 = SRC(3) + SRC(5) + SRC(1) + (SRC(1)>>1);\
- + const int b1 = (a7>>2) + a1;\
- + const int b3 = a3 + (a5>>2);\
- + const int b5 = (a3>>2) - a5;\
- + const int b7 = a7 - (a1>>2);\
- + DST(0, b0 + b7);\
- + DST(1, b2 + b5);\
- + DST(2, b4 + b3);\
- + DST(3, b6 + b1);\
- + DST(4, b6 - b1);\
- + DST(5, b4 - b3);\
- + DST(6, b2 - b5);\
- + DST(7, b0 - b7);\
- +}
- +
- +static void add8x8_idct8( uint8_t *dst, DCTELEM dct[8][8], int stride )
- +{
- + int i;
- +
- + dct[0][0] += 32; // rounding for the >>6 at the end
- +
- +#define SRC(x) dct[x][i]
- +#define DST(x,rhs) dct[x][i] = (rhs)
- + for( i = 0; i < 8; i++ )
- + IDCT8_1D
- +#undef SRC
- +#undef DST
- +
- +#define SRC(x) dct[i][x]
- +#define DST(x,rhs) dst[i + x*stride] = av_clip_uint8( dst[i + x*stride] + ((rhs) >> 6) );
- + for( i = 0; i < 8; i++ )
- + IDCT8_1D
- +#undef SRC
- +#undef DST
- +}
- +
- +#define QUANT_ONE( coef, mf, f ) \
- +{ \
- + if( (coef) > 0 ) \
- + (coef) = (f + (coef)) * (mf) >> 16; \
- + else \
- + (coef) = - ((f - (coef)) * (mf) >> 16); \
- +}
- +
- +static void quant_8x8( DCTELEM dct[8][8], int mf[64], int bias[64] )
- +{
- + int i;
- + for( i = 0; i < 64; i++ )
- + QUANT_ONE( dct[0][i], mf[i], bias[i] );
- +}
- +
- +static void quant_4x4( DCTELEM dct[4][4], int mf[16], int bias[16] )
- +{
- + int i;
- + for( i = 0; i < 16; i++ )
- + QUANT_ONE( dct[0][i], mf[i], bias[i] );
- +}
- +
- +#define ZIG(i,y,x) level[i] = dct[x][y];
- +
- +static void zigzag_scan_8x8_frame( int16_t level[64], DCTELEM dct[8][8] )
- +{
- + ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
- + ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
- + ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,4,0) ZIG(11,3,1)
- + ZIG(12,2,2) ZIG(13,1,3) ZIG(14,0,4) ZIG(15,0,5)
- + ZIG(16,1,4) ZIG(17,2,3) ZIG(18,3,2) ZIG(19,4,1)
- + ZIG(20,5,0) ZIG(21,6,0) ZIG(22,5,1) ZIG(23,4,2)
- + ZIG(24,3,3) ZIG(25,2,4) ZIG(26,1,5) ZIG(27,0,6)
- + ZIG(28,0,7) ZIG(29,1,6) ZIG(30,2,5) ZIG(31,3,4)
- + ZIG(32,4,3) ZIG(33,5,2) ZIG(34,6,1) ZIG(35,7,0)
- + ZIG(36,7,1) ZIG(37,6,2) ZIG(38,5,3) ZIG(39,4,4)
- + ZIG(40,3,5) ZIG(41,2,6) ZIG(42,1,7) ZIG(43,2,7)
- + ZIG(44,3,6) ZIG(45,4,5) ZIG(46,5,4) ZIG(47,6,3)
- + ZIG(48,7,2) ZIG(49,7,3) ZIG(50,6,4) ZIG(51,5,5)
- + ZIG(52,4,6) ZIG(53,3,7) ZIG(54,4,7) ZIG(55,5,6)
- + ZIG(56,6,5) ZIG(57,7,4) ZIG(58,7,5) ZIG(59,6,6)
- + ZIG(60,5,7) ZIG(61,6,7) ZIG(62,7,6) ZIG(63,7,7)
- +}
- +
- +static void zigzag_scan_4x4_frame( int16_t level[16], DCTELEM dct[4][4] )
- +{
- + ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
- + ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
- + ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)
- + ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
- +}
- +
- +#define DEQUANT_SHL( x ) \
- + dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*4+x] ) << i_qbits
- +
- +#define DEQUANT_SHR( x ) \
- + dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*4+x] + f ) >> (-i_qbits)
- +
- +static void dequant_4x4( DCTELEM dct[4][4], int dequant_mf[6][16], int i_qp )
- +{
- + const int i_mf = i_qp%6;
- + const int i_qbits = i_qp/6 - 4;
- + int y;
- +
- + if( i_qbits >= 0 )
- + {
- + for( y = 0; y < 4; y++ )
- + {
- + DEQUANT_SHL( 0 );
- + DEQUANT_SHL( 1 );
- + DEQUANT_SHL( 2 );
- + DEQUANT_SHL( 3 );
- + }
- + }
- + else
- + {
- + const int f = 1 << (-i_qbits-1);
- + for( y = 0; y < 4; y++ )
- + {
- + DEQUANT_SHR( 0 );
- + DEQUANT_SHR( 1 );
- + DEQUANT_SHR( 2 );
- + DEQUANT_SHR( 3 );
- + }
- + }
- +}
- +
- +#undef DEQUANT_SHL
- +#define DEQUANT_SHL( x ) \
- + dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*8+x] ) << i_qbits
- +#undef DEQUANT_SHR
- +#define DEQUANT_SHR( x ) \
- + dct[y][x] = ( dct[y][x] * dequant_mf[i_mf][y*8+x] + f ) >> (-i_qbits)
- +
- +static void dequant_8x8( DCTELEM dct[8][8], int dequant_mf[6][64], int i_qp )
- +{
- + const int i_mf = i_qp%6;
- + const int i_qbits = i_qp/6 - 6;
- + int y;
- +
- + if( i_qbits >= 0 )
- + {
- + for( y = 0; y < 8; y++ )
- + {
- + DEQUANT_SHL( 0 );
- + DEQUANT_SHL( 1 );
- + DEQUANT_SHL( 2 );
- + DEQUANT_SHL( 3 );
- + DEQUANT_SHL( 4 );
- + DEQUANT_SHL( 5 );
- + DEQUANT_SHL( 6 );
- + DEQUANT_SHL( 7 );
- + }
- + }
- + else
- + {
- + const int f = 1 << (-i_qbits-1);
- + for( y = 0; y < 8; y++ )
- + {
- + DEQUANT_SHR( 0 );
- + DEQUANT_SHR( 1 );
- + DEQUANT_SHR( 2 );
- + DEQUANT_SHR( 3 );
- + DEQUANT_SHR( 4 );
- + DEQUANT_SHR( 5 );
- + DEQUANT_SHR( 6 );
- + DEQUANT_SHR( 7 );
- + }
- + }
- +}
- +
- +/* H.264-style MV prediction */
- +static void photon_predict_mv(PhotonContext *s)
- +{
- + const int top_left = s->mb_xy - s->mb_width - 1;
- + const int top_right = s->mb_xy - s->mb_width + 1;
- + const int top = s->mb_xy - s->mb_width;
- + const int left = s->mb_xy - 1;
- + if(s->mb_xy == 0)
- + {
- + s->mv[0] = 0;
- + s->mv[1] = 0;
- + }
- + else if(s->mb_x == 0)
- + {
- + s->mv[0] = mid_pred(0,s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(0,s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- + else if(s->mb_y == 0)
- + {
- + s->mv[0] = s->mb_mv[left][0];
- + s->mv[1] = s->mb_mv[left][1];
- + }
- + else if(s->mb_x == s->mb_width - 1)
- + {
- + s->mv[0] = mid_pred(s->mb_mv[top_left][0],s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(s->mb_mv[top_left][1],s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- + else
- + {
- + s->mv[0] = mid_pred(s->mb_mv[top_right][0],s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(s->mb_mv[top_right][1],s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- +}
- +
- +static void photon_predict_mv_skip(PhotonContext *s)
- +{
- + const int top_left = s->mb_xy - s->mb_width - 1;
- + const int top_right = s->mb_xy - s->mb_width + 1;
- + const int top = s->mb_xy - s->mb_width;
- + const int left = s->mb_xy - 1;
- + if(s->mb_xy == 0)
- + {
- + s->mv[0] = 0;
- + s->mv[1] = 0;
- + }
- + else if(s->mb_x == 0)
- + {
- + if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
- + (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0))
- + {
- + s->mv[0] = 0;
- + s->mv[1] = 0;
- + }
- + else
- + {
- + s->mv[0] = mid_pred(0,s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(0,s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- + }
- + else if(s->mb_y == 0)
- + {
- + s->mv[0] = s->mb_mv[left][0];
- + s->mv[1] = s->mb_mv[left][1];
- + }
- + else if(s->mb_x == s->mb_width - 1)
- + {
- + if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
- + (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0) ||
- + (s->mb_mv[top_left][0] == 0 && s->mb_mv[top_left][1] == 0))
- + {
- + s->mv[0] = 0;
- + s->mv[1] = 0;
- + }
- + else
- + {
- + s->mv[0] = mid_pred(s->mb_mv[top_left][0],s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(s->mb_mv[top_left][1],s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- + }
- + else
- + {
- + if((s->mb_mv[left][0] == 0 && s->mb_mv[left][1] == 0) ||
- + (s->mb_mv[top][0] == 0 && s->mb_mv[top][1] == 0) ||
- + (s->mb_mv[top_right][0] == 0 && s->mb_mv[top_right][1] == 0))
- + {
- + s->mv[0] = 0;
- + s->mv[1] = 0;
- + }
- + else
- + {
- + s->mv[0] = mid_pred(s->mb_mv[top_right][0],s->mb_mv[left][0],s->mb_mv[top][0]);
- + s->mv[1] = mid_pred(s->mb_mv[top_right][1],s->mb_mv[left][1],s->mb_mv[top][1]);
- + }
- + }
- +}
- +
- +static void photon_predict_intra_dc(PhotonContext *s)
- +{
- + if(s->mb_xy == 0) pred16x16_128_dc_c(s->fdec[0],s->fdec_stride[0]);
- + else if(s->mb_x == 0) pred16x16_top_dc_c(s->fdec[0],s->fdec_stride[0]);
- + else if(s->mb_y == 0) pred16x16_left_dc_c(s->fdec[0],s->fdec_stride[0]);
- + else pred16x16_dc_c(s->fdec[0],s->fdec_stride[0]);
- +}
- +
- +static void photon_predict_intra_chroma_dc(PhotonContext *s)
- +{
- + if(s->mb_xy == 0)
- + {
- + pred8x8_128_dc_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_128_dc_c(s->fdec[5],s->fdec_stride[5]);
- + }
- + else if(s->mb_x == 0)
- + {
- + pred8x8_top_dc_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_top_dc_c(s->fdec[5],s->fdec_stride[5]);
- + }
- + else if(s->mb_y == 0)
- + {
- + pred8x8_left_dc_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_left_dc_c(s->fdec[5],s->fdec_stride[5]);
- + }
- + else
- + {
- + pred8x8_dc_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_dc_c(s->fdec[5],s->fdec_stride[5]);
- + }
- +}
- +
- +static int photon_encode_8x8(PhotonContext *s, int idx, int idct)
- +{
- + int i,j,cbp = 0;
- + DCTELEM dct[8][8];
- + sub8x8_dct8(dct, s->fenc[idx], s->fdec[idx], s->fenc_stride[idx], s->fdec_stride[idx]);
- + quant_8x8(dct, s->quant8_mf[s->mb_qp[idx]], s->quant8_bias[s->mb_qp[idx]]);
- + zigzag_scan_8x8_frame( s->dct8x8[idx], dct);
- + dequant_8x8(dct, s->dequant8_mf, s->mb_qp[idx]);
- + for(i = 0; i < 8; i++)
- + for(j = 0; j < 8; j++)
- + if(dct[i][j])
- + {
- + cbp = 1;
- + break;
- + }
- + if(cbp && idct)
- + add8x8_idct8(s->fdec[idx], dct, s->fdec_stride[idx]);
- + return cbp;
- +}
- +
- +static int photon_encode_4x4(PhotonContext *s, int idx, int subidx, int idct)
- +{
- + int fdec_offset = s->fdec_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
- + int fenc_offset = s->fenc_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
- + int i,j,cbp = 1;
- + DCTELEM dct[4][4];
- + sub4x4_dct(dct, s->fenc[idx] + fenc_offset, s->fdec[idx] + fdec_offset,
- + s->fenc_stride[idx], s->fdec_stride[idx]);
- + quant_4x4(dct, s->quant4_mf[s->mb_qp[idx]], s->quant4_bias[s->mb_qp[idx]]);
- + zigzag_scan_4x4_frame( s->dct4x4[idx][subidx], dct);
- + dequant_4x4(dct, s->dequant4_mf, s->mb_qp[idx]);
- + for(i = 0; i < 4; i++)
- + for(j = 0; j < 4; j++)
- + if(dct[i][j])
- + {
- + cbp = 1;
- + break;
- + }
- + if(cbp && idct)
- + add4x4_idct(s->fdec[idx] + fdec_offset, dct, s->fdec_stride[idx]);
- + return cbp;
- +}
- +
- +static void photon_write_8x8(PhotonContext *s, int idx)
- +{
- + int i = 0;
- + while(1)
- + {
- + int coeff = s->dct8x8[idx][i];
- + int run = 0;
- + set_se_golomb(&s->pb,coeff);
- + i++;
- + while(i < 64 && s->dct8x8[idx][i] == 0)
- + {
- + run++;
- + i++;
- + }
- + if(i < 64) put_bits(&s->pb,1,0);
- + else {put_bits(&s->pb,1,1);break;}
- + set_ue_golomb(&s->pb,run);
- + }
- +}
- +
- +static void photon_write_4x4(PhotonContext *s, int idx, int subidx)
- +{
- + int i = 0;
- + while(1)
- + {
- + int coeff = s->dct4x4[idx][subidx][i];
- + int run = 0;
- + set_se_golomb(&s->pb,coeff);
- + i++;
- + while(i < 16 && s->dct4x4[idx][subidx][i] == 0)
- + {
- + run++;
- + i++;
- + }
- + if(i < 16) put_bits(&s->pb,1,0);
- + else {put_bits(&s->pb,1,1);break;}
- + set_ue_golomb(&s->pb,run);
- + }
- +}
- +
- +static void photon_decode_residual_8x8(PhotonContext *s, int idx, int *qmul)
- +{
- + int level, run, eob = 0, coeff = 0;
- + DCTELEM dct[64];
- + memset(dct,0,sizeof(int16_t)*64);
- + while(1)
- + {
- + level = get_se_golomb(&s->gb);
- + dct[zigzag_scan8x8[coeff]] = (level * qmul[zigzag_scan8x8[coeff]] + 32) >> 6;
- + eob = get_bits1(&s->gb);
- + if(eob) break;
- + run = get_ue_golomb(&s->gb);
- + coeff += run+1;
- + }
- + ff_h264_idct8_add_c(s->fdec[idx], dct, s->fdec_stride[idx]);
- +}
- +
- +static void photon_decode_residual_4x4(PhotonContext *s, int idx, int subidx, int *qmul)
- +{
- + int offset = s->fdec_stride[idx] * (subidx>>1) * 4 + (subidx&1) * 4;
- + int level, run, eob = 0, coeff = 0;
- + DCTELEM dct[16];
- + memset(dct,0,sizeof(DCTELEM)*16);
- + while(1)
- + {
- + level = get_se_golomb(&s->gb);
- + dct[zigzag_scan[coeff]] = (level * qmul[zigzag_scan[coeff]] + 8) >> 4;
- + eob = get_bits1(&s->gb);
- + if(eob) break;
- + run = get_ue_golomb(&s->gb);
- + coeff += run+1;
- + }
- + ff_h264_idct_add_c(s->fdec[idx] + offset, dct, s->fdec_stride[idx]);
- +}
- +
- +static void photon_decode_macroblock_residual(PhotonContext *s)
- +{
- + int idx, subidx, cbp, subcbp, transform8x8;
- +
- + cbp = get_bits(&s->gb, 6);
- + for(idx = 0; idx < 6; idx++)
- + {
- + if((cbp >> (5 - idx)) & 1)
- + {
- + /* decode delta quant */
- + if(get_bits1(&s->gb))
- + {
- + if(get_bits1(&s->gb))
- + do
- + {
- + s->mb_qp[idx]++;
- + } while(get_bits1(&s->gb));
- + else
- + do
- + {
- + s->mb_qp[idx]--;
- + } while(get_bits1(&s->gb));
- + if(s->mb_qp[idx] < 0 || s->mb_qp[idx] > 51)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: quantizer %d out of range, clipping\n",s->mb_qp[idx]);
- + s->mb_qp[idx] = av_clip(s->mb_qp[idx],0,51);
- + }
- + }
- +
- + transform8x8 = get_bits1(&s->gb);
- + if(transform8x8)
- + photon_decode_residual_8x8(s,idx,s->dequant8_mf[s->mb_qp[idx]]);
- + else
- + {
- + subcbp = get_bits(&s->gb, 4);
- + for(subidx = 0; subidx < 4; subidx++)
- + if((subcbp >> (3 - subidx)) & 1)
- + photon_decode_residual_4x4(s,idx,subidx,s->dequant4_mf[s->mb_qp[idx]]);
- + }
- + }
- + }
- +}
- +
- +static void photon_decode_macroblock(PhotonContext *s)
- +{
- + /* Check for skip */
- + int skip = 0;
- + if(s->frame_type == PHOTON_FRAMETYPE_P)
- + {
- + skip = get_bits1(&s->gb);
- + s->block_type = PHOTON_MBTYPE_SKIP;
- + photon_predict_mv_skip(s);
- + /* FIXME: MC needs to be done here. */
- + }
- + if(!skip)
- + {
- + /* MV prediction is done regardless of block type */
- + photon_predict_mv(s);
- +
- + /* Read block type */
- + if(s->frame_type == PHOTON_FRAMETYPE_P)
- + s->block_type = get_bits1(&s->gb);
- + else s->block_type = PHOTON_MBTYPE_INTRA;
- +
- + /* Read inter MVD */
- + if(s->block_type == PHOTON_MBTYPE_INTER)
- + {
- + s->mv[0] += get_se_golomb(&s->gb);
- + s->mv[1] += get_se_golomb(&s->gb);
- + /* FIXME: MC needs to be done here. */
- + }
- + /* Read intra prediction type */
- + else
- + {
- + if(get_bits1(&s->gb))
- + {
- + if(get_bits1(&s->gb))
- + pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
- + else pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
- + }
- + else photon_predict_intra_dc(s);
- +
- + if(get_bits1(&s->gb))
- + {
- + if(get_bits1(&s->gb))
- + {
- + pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
- + }
- + else
- + {
- + pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
- + }
- + }
- + else photon_predict_intra_chroma_dc(s);
- + }
- + photon_decode_macroblock_residual(s);
- + }
- +}
- +
- +static int photon_decode_frame(AVCodecContext *avctx,
- + void *data, int *data_size,
- + const uint8_t *buf, int buf_size)
- +{
- + int idx;
- + PhotonContext *s = avctx->priv_data;
- + if(s->frame.data[0])
- + avctx->release_buffer(avctx, &s->frame);
- + if(avctx->get_buffer(avctx, &s->frame) < 0)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: get_buffer() failed\n");
- + return -1;
- + }
- + init_get_bits(&s->gb, buf, buf_size);
- + /* 1 == P-frame, 0 == I-frame */
- + s->frame_type = get_bits1(&s->gb);
- + if(s->frame_type) av_log(s->avctx, AV_LOG_ERROR, "P-FRAMES NOT SUPPORTED: %d\n",s->mb_xy);
- + s->frame_qp = get_bits(&s->gb,6);
- + if(s->frame_qp > 51)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: frame quantizer (%d) is out of range\n", s->frame_qp);
- + return -1;
- + }
- +
- + /* For the first macroblock, the last MB QP is defined as the frame QP. */
- + for(idx = 0; idx < 6; idx++)
- + s->last_mb_qp[idx] = s->frame_qp;
- +
- + s->fdec_stride[0] = s->fdec_stride[1] = s->fdec_stride[2] = s->fdec_stride[3] = s->frame.linesize[0];
- + s->fdec_stride[4] = s->frame.linesize[1];
- + s->fdec_stride[5] = s->frame.linesize[2];
- +
- + for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++)
- + {
- + for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++)
- + {
- + s->mb_xy = s->mb_x + s->mb_y * s->mb_width;
- + for(idx = 0; idx < 6; idx++)
- + s->mb_qp[idx] = s->last_mb_qp[idx];
- +
- + /* Initialize block pointers */
- + s->fdec[0] = s->frame.data[0] + s->mb_x * 16 + s->fdec_stride[0] * s->mb_y * 16;
- + s->fdec[1] = s->fdec[0] + 8;
- + s->fdec[2] = s->fdec[0] + s->fdec_stride[0] * 8;
- + s->fdec[3] = s->fdec[2] + 8;
- + s->fdec[4] = s->frame.data[1] + s->mb_x * 8 + s->fdec_stride[4] * s->mb_y * 8;
- + s->fdec[5] = s->frame.data[2] + s->mb_x * 8 + s->fdec_stride[5] * s->mb_y * 8;
- +
- + photon_decode_macroblock(s);
- +
- + /* Store the MV for this block */
- + s->mb_mv[s->mb_xy][0] = s->mv[0];
- + s->mb_mv[s->mb_xy][1] = s->mv[1];
- + for(idx = 0; idx < 6; idx++)
- + s->last_mb_qp[idx] = s->mb_qp[idx];
- + }
- + }
- + *data_size = sizeof(AVFrame);
- + *(AVFrame*)data= s->frame;
- + return get_bits_count(&s->gb)/8;
- +}
- +
- +static void photon_analyse_intra(PhotonContext *s)
- +{
- + int bcost,cost;
- + s->intra_pred_luma = PHOTON_INTRA_MODE_DC;
- + photon_predict_intra_dc(s);
- + bcost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
- + if(s->mb_y > 0)
- + {
- + pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
- + cost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
- + if(cost < bcost)
- + {
- + s->intra_pred_luma = PHOTON_INTRA_MODE_V;
- + bcost = cost;
- + }
- + }
- + if(s->mb_x > 0)
- + {
- + pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
- + cost = sad16x16(s->fdec[0],s->fdec_stride[0],s->fenc[0],s->fenc_stride[0]);
- + if(cost < bcost)
- + {
- + s->intra_pred_luma = PHOTON_INTRA_MODE_H;
- + bcost = cost;
- + }
- + }
- +}
- +
- +static void photon_analyse_intra_chroma(PhotonContext *s)
- +{
- + int bcost,cost;
- + s->intra_pred_chroma = PHOTON_INTRA_MODE_DC;
- + photon_predict_intra_chroma_dc(s);
- + bcost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
- + + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
- + if(s->mb_y > 0)
- + {
- + pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
- + cost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
- + + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
- + if(cost < bcost)
- + {
- + s->intra_pred_chroma = PHOTON_INTRA_MODE_V;
- + bcost = cost;
- + }
- + }
- + if(s->mb_x > 0)
- + {
- + pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
- + cost = sad8x8(s->fdec[4],s->fdec_stride[4],s->fenc[4],s->fenc_stride[4]);
- + + sad8x8(s->fdec[5],s->fdec_stride[5],s->fenc[5],s->fenc_stride[5]);
- + if(cost < bcost)
- + {
- + s->intra_pred_chroma = PHOTON_INTRA_MODE_H;
- + bcost = cost;
- + }
- + }
- +}
- +
- +static int size_ue_golomb(int n)
- +{
- + return av_log2(n+1) * 2;
- +}
- +
- +static int size_se_golomb(int n)
- +{
- + if(n < 0) n = -2*n;
- + else n = 2*n - 1;
- + return size_ue_golomb(n);
- +}
- +
- +static int photon_cost_8x8(PhotonContext *s, int idx)
- +{
- + int cost = 0, i = 0;
- + while(1)
- + {
- + int coeff = s->dct8x8[idx][i];
- + int run = 0;
- + cost += size_se_golomb(coeff);
- + i++;
- + while(i < 64 && s->dct8x8[idx][i] == 0)
- + {
- + run++;
- + i++;
- + }
- + cost++;
- + if(i >= 64) break;
- + cost += size_ue_golomb(run);
- + }
- + return cost;
- +}
- +
- +static int photon_cost_4x4(PhotonContext *s, int idx, int subidx)
- +{
- + int cost = 0, i = 0;
- + while(1)
- + {
- + int coeff = s->dct4x4[idx][subidx][i];
- + int run = 0;
- + cost += size_se_golomb(coeff);
- + i++;
- + while(i < 16 && s->dct4x4[idx][subidx][i] == 0)
- + {
- + run++;
- + i++;
- + }
- + cost++;
- + if(i >= 16) break;
- + cost += size_ue_golomb(run);
- + }
- + return cost;
- +}
- +
- +static int photon_analyse_transform(PhotonContext *s, int idx)
- +{
- + int cost4x4 = 4, cost8x8 = 0, subidx, cbp = 0;
- + if(photon_encode_8x8(s, idx, 0))
- + cost8x8 = photon_cost_8x8(s, idx);
- + for(subidx = 0; subidx < 4; subidx++)
- + {
- + if(photon_encode_4x4(s, idx, subidx, 0))
- + {
- + cost4x4 += photon_cost_4x4(s, idx, subidx);
- + cbp = 1;
- + }
- + }
- + if(!cbp) cost4x4 = 0;
- + if(cost8x8 > cost4x4) return 0;
- + else return 1;
- +}
- +
- +static void photon_adaptive_quant(PhotonContext *s, int idx)
- +{
- + static uint8_t zero[8] = {0,0,0,0,0,0,0,0};
- + float qp_adj;
- + int sad, ssd, total;
- +
- + if(idx == 4 || idx == 5) /* no chroma QP offset for now */
- + {
- + s->mb_qp[idx] = s->frame_qp;
- + }
- + ssd = ssd8x8(s->fenc[idx],s->fenc_stride[idx],zero,0);
- + sad = sad8x8(s->fenc[idx],s->fenc_stride[idx],zero,0);
- + total = ssd - ((sad * sad) >> 6);
- + if(total == 0) total = 1;
- + qp_adj = 1.5 * (logf(total) - logf(1000));
- + s->mb_qp[idx] = av_clip(s->frame_qp + qp_adj + 0.5,0,51);
- +}
- +
- +static int photon_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data)
- +{
- + int idx, subidx, cbp;
- + int total_quant = 0, num_quant = 0;
- + PhotonContext *s = avctx->priv_data;
- + AVFrame *cur_frame = data;
- + if(s->frame.data[0])
- + avctx->release_buffer(avctx, &s->frame);
- + if(avctx->get_buffer(avctx, &s->frame) < 0)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: get_buffer() failed\n");
- + return -1;
- + }
- + avctx->coded_frame = &s->frame;
- +
- + s->fdec_stride[0] = s->fdec_stride[1] = s->fdec_stride[2] = s->fdec_stride[3] = s->frame.linesize[0];
- + s->fdec_stride[4] = s->frame.linesize[1];
- + s->fdec_stride[5] = s->frame.linesize[2];
- + s->fenc_stride[0] = s->fenc_stride[1] = s->fenc_stride[2] = s->fenc_stride[3] = cur_frame->linesize[0];
- + s->fenc_stride[4] = cur_frame->linesize[1];
- + s->fenc_stride[5] = cur_frame->linesize[2];
- + s->frame_qp = avctx->cqp == -1 ? 26 : avctx->cqp; /* CQP */
- + if(s->frame_qp < 0 || s->frame_qp > 51)
- + {
- + av_log(s->avctx, AV_LOG_ERROR, "photon: QP %d out of range\n",s->frame_qp);
- + return -1;
- + }
- + for(idx = 0; idx < 6; idx++)
- + s->last_mb_qp[idx] = s->frame_qp;
- +
- + init_put_bits(&s->pb, buf, buf_size);
- + /* I-frames only */
- + put_bits(&s->pb,1,PHOTON_FRAMETYPE_I);
- + s->frame.key_frame = 1;
- + s->frame.pict_type = FF_I_TYPE;
- +
- + put_bits(&s->pb,6,s->frame_qp);
- + assert(s->fdec_stride[0] == s->fenc_stride[0]);
- + for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++)
- + {
- + for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++)
- + {
- + s->mb_xy = s->mb_x + s->mb_y * s->mb_width;
- + for(idx = 0; idx < 6; idx++)
- + s->mb_qp[idx] = s->last_mb_qp[idx];
- +
- + s->fdec[0] = s->frame.data[0] + s->mb_x * 16 + s->fdec_stride[0] * s->mb_y * 16;
- + s->fdec[1] = s->fdec[0] + 8;
- + s->fdec[2] = s->fdec[0] + s->fdec_stride[0] * 8;
- + s->fdec[3] = s->fdec[2] + 8;
- + s->fdec[4] = s->frame.data[1] + s->mb_x * 8 + s->fdec_stride[4] * s->mb_y * 8;
- + s->fdec[5] = s->frame.data[2] + s->mb_x * 8 + s->fdec_stride[5] * s->mb_y * 8;
- +
- + s->fenc[0] = cur_frame->data[0] + s->mb_x * 16 + s->fenc_stride[0] * s->mb_y * 16;
- + s->fenc[1] = s->fenc[0] + 8;
- + s->fenc[2] = s->fenc[0] + s->fenc_stride[0] * 8;
- + s->fenc[3] = s->fenc[2] + 8;
- + s->fenc[4] = cur_frame->data[1] + s->mb_x * 8 + s->fenc_stride[4] * s->mb_y * 8;
- + s->fenc[5] = cur_frame->data[2] + s->mb_x * 8 + s->fenc_stride[5] * s->mb_y * 8;
- +
- + /* Intra prediction */
- + photon_analyse_intra(s);
- +
- + if(s->intra_pred_luma == PHOTON_INTRA_MODE_DC)
- + {
- + photon_predict_intra_dc(s);
- + put_bits(&s->pb,1,0);
- + }
- + else if(s->intra_pred_luma == PHOTON_INTRA_MODE_V)
- + {
- + pred16x16_vertical_c(s->fdec[0],s->fdec_stride[0]);
- + put_bits(&s->pb,1,1);
- + put_bits(&s->pb,1,0);
- + }
- + else if(s->intra_pred_luma == PHOTON_INTRA_MODE_H)
- + {
- + pred16x16_horizontal_c(s->fdec[0],s->fdec_stride[0]);
- + put_bits(&s->pb,1,1);
- + put_bits(&s->pb,1,1);
- + }
- +
- + photon_analyse_intra_chroma(s);
- +
- + if(s->intra_pred_chroma == PHOTON_INTRA_MODE_DC)
- + {
- + photon_predict_intra_chroma_dc(s);
- + put_bits(&s->pb,1,0);
- + }
- + else if(s->intra_pred_chroma == PHOTON_INTRA_MODE_V)
- + {
- + pred8x8_vertical_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_vertical_c(s->fdec[5],s->fdec_stride[5]);
- + put_bits(&s->pb,1,1);
- + put_bits(&s->pb,1,0);
- + }
- + else if(s->intra_pred_chroma == PHOTON_INTRA_MODE_H)
- + {
- + pred8x8_horizontal_c(s->fdec[4],s->fdec_stride[4]);
- + pred8x8_horizontal_c(s->fdec[5],s->fdec_stride[5]);
- + put_bits(&s->pb,1,1);
- + put_bits(&s->pb,1,1);
- + }
- +
- + cbp = 0;
- + for(idx = 0; idx < 6; idx++)
- + {
- + photon_adaptive_quant(s, idx);
- + s->transform8x8[idx] = photon_analyse_transform(s, idx);
- + cbp <<= 1;
- + if(s->transform8x8[idx])
- + {
- + s->subcbp[idx] = 0;
- + cbp += photon_encode_8x8(s, idx, 1);
- + }
- + else
- + {
- + s->subcbp[idx] = 0;
- + for(subidx = 0; subidx < 4; subidx++)
- + {
- + s->subcbp[idx] <<= 1;
- + s->subcbp[idx] += photon_encode_4x4(s, idx, subidx, 1);
- + }
- + cbp += (!!s->subcbp[idx]);
- + }
- + }
- + put_bits(&s->pb,6,cbp);
- + for(idx = 0; idx < 6; idx++)
- + {
- + if((cbp >> (5 - idx)) & 1)
- + {
- + /* encode delta quant */
- + if(s->mb_qp[idx] != s->last_mb_qp[idx])
- + {
- + int dqp = s->mb_qp[idx] - s->last_mb_qp[idx];
- + put_bits(&s->pb,1,1);
- + if(dqp > 0) put_bits(&s->pb,1,1);
- + else put_bits(&s->pb,1,0);
- + dqp = abs(dqp) - 1;
- + while(dqp)
- + {
- + dqp--;
- + put_bits(&s->pb,1,1);
- + }
- + }
- + put_bits(&s->pb,1,0);
- +
- + put_bits(&s->pb,1,s->transform8x8[idx]);
- + if(s->transform8x8[idx])
- + photon_write_8x8(s, idx);
- + else
- + {
- + put_bits(&s->pb,4,s->subcbp[idx]);
- + for(subidx = 0; subidx < 4; subidx++)
- + if(s->subcbp[idx] >> (3 - subidx))
- + photon_write_4x4(s, idx, subidx);
- + }
- + total_quant += s->mb_qp[idx];
- + num_quant++;
- + }
- + else s->mb_qp[idx] = s->last_mb_qp[idx];
- + }
- + for(idx = 0; idx < 6; idx++)
- + s->last_mb_qp[idx] = s->mb_qp[idx];
- + }
- + }
- + if(num_quant == 0)
- + s->frame.quality = 0;
- + else
- + s->frame.quality = (total_quant / num_quant) * FF_QP2LAMBDA;
- + flush_put_bits(&s->pb);
- + return put_bits_count(&s->pb)/8;
- +}
- +
- +AVCodec photon_decoder =
- +{
- + .name = "photon",
- + .type = CODEC_TYPE_VIDEO,
- + .id = CODEC_ID_PHOTON,
- + .priv_data_size = sizeof(PhotonContext),
- + .init = photon_decode_init,
- + .close = photon_decode_close,
- + .decode = photon_decode_frame,
- + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
- + .long_name = "Photon MPEG-like codec"
- +};
- +
- +AVCodec photon_encoder =
- +{
- + .name = "photon",
- + .type = CODEC_TYPE_VIDEO,
- + .id = CODEC_ID_PHOTON,
- + .priv_data_size = sizeof(PhotonContext),
- + .init = photon_encode_init,
- + .close = photon_encode_close,
- + .encode = photon_encode_frame,
- + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1},
- + .long_name = "Photon MPEG-like codec"
- +};
- +
- Property changes on: libavcodec/photon.c
- ___________________________________________________________________
- Name: svn:executable
- + *
- Index: libavcodec/allcodecs.c
- ===================================================================
- --- libavcodec/allcodecs.c (revision 13076)
- +++ libavcodec/allcodecs.c (working copy)
- -126,6 +126,7 @@
- REGISTER_DECODER (PCX, pcx);
- REGISTER_ENCODER (PGM, pgm);
- REGISTER_ENCODER (PGMYUV, pgmyuv);
- + REGISTER_ENCDEC (PHOTON, photon);
- REGISTER_ENCDEC (PNG, png);
- REGISTER_ENCODER (PPM, ppm);
- REGISTER_DECODER (PTX, ptx);
- Index: libavcodec/avcodec.h
- ===================================================================
- --- libavcodec/avcodec.h (revision 13076)
- +++ libavcodec/avcodec.h (working copy)
- -186,6 +186,7 @@
- CODEC_ID_ESCAPE124,
- CODEC_ID_DIRAC,
- CODEC_ID_BFI,
- + CODEC_ID_PHOTON,
- /* various PCM "codecs" */
- CODEC_ID_PCM_S16LE= 0x10000,
- Index: libavformat/riff.c
- ===================================================================
- --- libavformat/riff.c (revision 13076)
- +++ libavformat/riff.c (working copy)
- -160,6 +160,7 @@
- { CODEC_ID_VMNC, MKTAG('V', 'M', 'n', 'c') },
- { CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') },
- { CODEC_ID_CLJR, MKTAG('c', 'l', 'j', 'r') },
- + { CODEC_ID_PHOTON, MKTAG('P', 'H', 'T', 'N') },
- { CODEC_ID_NONE, 0 }
- };
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.