⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 h263.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
/* * Adapted from: * * H263/MPEG4 backend for ffmpeg encoder and decoder * Copyright (c) 2000,2001 Gerard Lantau. * * This program 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. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include "../portab.h"#include "bitstream.h"#include "h263.h"/* VLC's */#define MAX_RUN    64#define MAX_LEVEL  64/* run length table */typedef struct RLTable {    int n; /* number of entries of table_vlc minus 1 */    int last; /* number of values for last = 0 */    const UINT16 (*table_vlc)[2];    const INT8 *table_run;    const INT8 *table_level;    UINT8 *index_run[2]; /* encoding only */    INT8 *max_level[2]; /* encoding & decoding */    INT8 *max_run[2];   /* encoding & decoding */    H263_VLC vlc;            /* decoding only */} RLTable;const UINT16 inter_vlc[103][2] = {{ 0x2, 2 },{ 0xf, 4 },{ 0x15, 6 },{ 0x17, 7 },{ 0x1f, 8 },{ 0x25, 9 },{ 0x24, 9 },{ 0x21, 10 },{ 0x20, 10 },{ 0x7, 11 },{ 0x6, 11 },{ 0x20, 11 },{ 0x6, 3 },{ 0x14, 6 },{ 0x1e, 8 },{ 0xf, 10 },{ 0x21, 11 },{ 0x50, 12 },{ 0xe, 4 },{ 0x1d, 8 },{ 0xe, 10 },{ 0x51, 12 },{ 0xd, 5 },{ 0x23, 9 },{ 0xd, 10 },{ 0xc, 5 },{ 0x22, 9 },{ 0x52, 12 },{ 0xb, 5 },{ 0xc, 10 },{ 0x53, 12 },{ 0x13, 6 },{ 0xb, 10 },{ 0x54, 12 },{ 0x12, 6 },{ 0xa, 10 },{ 0x11, 6 },{ 0x9, 10 },{ 0x10, 6 },{ 0x8, 10 },{ 0x16, 7 },{ 0x55, 12 },{ 0x15, 7 },{ 0x14, 7 },{ 0x1c, 8 },{ 0x1b, 8 },{ 0x21, 9 },{ 0x20, 9 },{ 0x1f, 9 },{ 0x1e, 9 },{ 0x1d, 9 },{ 0x1c, 9 },{ 0x1b, 9 },{ 0x1a, 9 },{ 0x22, 11 },{ 0x23, 11 },{ 0x56, 12 },{ 0x57, 12 },{ 0x7, 4 },{ 0x19, 9 },{ 0x5, 11 },{ 0xf, 6 },{ 0x4, 11 },{ 0xe, 6 },{ 0xd, 6 },{ 0xc, 6 },{ 0x13, 7 },{ 0x12, 7 },{ 0x11, 7 },{ 0x10, 7 },{ 0x1a, 8 },{ 0x19, 8 },{ 0x18, 8 },{ 0x17, 8 },{ 0x16, 8 },{ 0x15, 8 },{ 0x14, 8 },{ 0x13, 8 },{ 0x18, 9 },{ 0x17, 9 },{ 0x16, 9 },{ 0x15, 9 },{ 0x14, 9 },{ 0x13, 9 },{ 0x12, 9 },{ 0x11, 9 },{ 0x7, 10 },{ 0x6, 10 },{ 0x5, 10 },{ 0x4, 10 },{ 0x24, 11 },{ 0x25, 11 },{ 0x26, 11 },{ 0x27, 11 },{ 0x58, 12 },{ 0x59, 12 },{ 0x5a, 12 },{ 0x5b, 12 },{ 0x5c, 12 },{ 0x5d, 12 },{ 0x5e, 12 },{ 0x5f, 12 },{ 0x3, 7 },};const INT8 inter_level[102] = {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,  1,  2,  3,  4,  5,  6,  1,  2,  3,  4,  1,  2,  3,  1,  2,  3,  1,  2,  3,  1,  2,  3,  1,  2,  1,  2,  1,  2,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  3,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,};const INT8 inter_run[102] = {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,  5,  5,  5,  6,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,  0,  0,  0,  1,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,};static RLTable h263_rl_table = {    102,    58,    inter_vlc,    inter_run,    inter_level,};static void init_rl(RLTable *rl){    INT8 max_level[MAX_RUN+1], max_run[MAX_LEVEL+1];    UINT8 index_run[MAX_RUN+1];    int last, run, level, start, end, i;    /* compute max_level[], max_run[] and index_run[] */    for(last=0;last<2;last++) {        if (last == 0) {            start = 0;            end = rl->last;        } else {            start = rl->last;            end = rl->n;        }        memset(max_level, 0, MAX_RUN + 1);        memset(max_run, 0, MAX_LEVEL + 1);        memset(index_run, rl->n, MAX_RUN + 1);        for(i=start;i<end;i++) {            run = rl->table_run[i];            level = rl->table_level[i];            if (index_run[run] == rl->n)                index_run[run] = i;            if (level > max_level[run])                max_level[run] = level;            if (run > max_run[level])                max_run[level] = run;        }        rl->max_level[last] = malloc(MAX_RUN + 1);        memcpy(rl->max_level[last], max_level, MAX_RUN + 1);        rl->max_run[last] = malloc(MAX_LEVEL + 1);        memcpy(rl->max_run[last], max_run, MAX_LEVEL + 1);        rl->index_run[last] = malloc(MAX_RUN + 1);        memcpy(rl->index_run[last], index_run, MAX_RUN + 1);    }}inline int get_rl_index(const RLTable *rl, int last, int run, int level){    int index;    index = rl->index_run[last][run];    if (index >= rl->n)        return rl->n;    if (level > rl->max_level[last][run])        return rl->n;    return index + level - 1;}/* Encoding */void h263_encode_coeff(	Bitstream *bs,	int16_t block[64],	const uint16_t *zigzag,	uint16_t intra){    RLTable *rl = &h263_rl_table;    static int once = 0;    int level, run, last, i, j, last_index, last_non_zero, sign, slevel;    int code;    if (!once) {        once = 1;        init_rl(&h263_rl_table);    }    if (intra) {	i = 1;    } else {	i = 0;    }    last_index = i;    for (j = 63; j >= i; j--) {	if (block[zigzag[j]] != 0) {	    last_index = j;	    break;	}    }    last_non_zero = i - 1;    for (; i <= last_index; i++) {	j = zigzag[i];	level = block[j];	if (level) {// DEBUGprintf("xvid i %d j %d bspos %d ", i, j, BitstreamPos(bs));	    run = i - last_non_zero - 1;	    last = (i == last_index);	    sign = 0;	    slevel = level;	    if (level < 0) {		sign = 1;		level = -level;	    }            code = get_rl_index(rl, last, run, level);            BitstreamPutBits(bs,		rl->table_vlc[code][0], rl->table_vlc[code][1]);            if (code == rl->n) {                BitstreamPutBits(bs, last, 1);                BitstreamPutBits(bs, run, 6);                BitstreamPutBits(bs, slevel & 0xff, 8);            } else {                BitstreamPutBits(bs, sign, 1);            }// DEBUGprintf("code %d last %d run %d level %d vlc 0x%x (%d bits)\n",	  code, last, run, level, rl->table_vlc[code][0], rl->table_vlc[code][1]);	    last_non_zero = i;	}    }}#ifdef TBD/* Decoding */static void init_vlc_rl(RLTable *rl){    init_vlc(&rl->vlc, 9, rl->n + 1,              &rl->table_vlc[0][1], 4, 2,             &rl->table_vlc[0][0], 4, 2);}void h263_decode_init_vlc(){    static int done = 0;    if (!done) {        done = 1;        init_rl(&h263_rl_table);        init_vlc_rl(&h263_rl_table);    }}int h263_decode_block(MpegEncContext * s, DCTELEM * block,                             int n, int coded){    int code, level, i, j, last, run;    RLTable *rl = &h263_rl_table;    if (s->mb_intra) {	/* DC coef */	level = get_bits(&s->gb, 8);	if (level == 255)		level = 128;	block[0] = level;	i = 1;    } else {	i = 0;    }    if (!coded) {        s->block_last_index[n] = i - 1;        return 0;    }    for(;;) {        code = get_vlc(&s->gb, &rl->vlc);        if (code < 0)            return -1;        if (code == rl->n) {            /* escape */            last = get_bits1(&s->gb);            run = get_bits(&s->gb, 6);            level = (INT8)get_bits(&s->gb, 8);            if (s->h263_rv10 && level == -128) {                /* XXX: should patch encoder too */                level = get_bits(&s->gb, 12);                level = (level << 20) >> 20;            }        } else {            run = rl->table_run[code];            level = rl->table_level[code];            last = code >= rl->last;            if (get_bits1(&s->gb))                level = -level;        }        i += run;        if (i >= 64)            return -1;	j = zigzag_direct[i];        block[j] = level;        if (last)            break;        i++;    }    s->block_last_index[n] = i;    return 0;}#endif /* TBD */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -