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

📄 mpeg12.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * MPEG1 encoder / MPEG2 decoder * Copyright (c) 2000,2001 Fabrice Bellard. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *///#define DEBUG#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "mpeg12data.h"#if 1#define PRINT_QP(a, b) {}#else#define PRINT_QP(a, b) printf(a, b)#endif/* Start codes. */#define SEQ_END_CODE		0x000001b7#define SEQ_START_CODE		0x000001b3#define GOP_START_CODE		0x000001b8#define PICTURE_START_CODE	0x00000100#define SLICE_MIN_START_CODE	0x00000101#define SLICE_MAX_START_CODE	0x000001af#define EXT_START_CODE		0x000001b5#define USER_START_CODE		0x000001b2#define DC_VLC_BITS 9#define MV_VLC_BITS 9#define MBINCR_VLC_BITS 9#define MB_PAT_VLC_BITS 9#define MB_PTYPE_VLC_BITS 6#define MB_BTYPE_VLC_BITS 6#define TEX_VLC_BITS 9static void mpeg1_encode_block(MpegEncContext *s,                          DCTELEM *block,                          int component);static void mpeg1_encode_motion(MpegEncContext *s, int val);static void mpeg1_skip_picture(MpegEncContext *s, int pict_num);static inline int mpeg1_decode_block_inter(MpegEncContext *s,                               DCTELEM *block,                               int n);static inline int mpeg1_decode_block_intra(MpegEncContext *s,                               DCTELEM *block,                               int n);static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,                                         DCTELEM *block,                                         int n);static inline int mpeg2_decode_block_intra(MpegEncContext *s,                                     DCTELEM *block,                                     int n);static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);static UINT16 mv_penalty[MAX_FCODE+1][MAX_MV*2+1];static UINT8 fcode_tab[MAX_MV*2+1];static inline int get_bits_diff(MpegEncContext *s){    int bits,ret;        bits= get_bit_count(&s->pb);    ret= bits - s->last_bits;    s->last_bits=bits;        return ret;}static void init_2d_vlc_rl(RLTable *rl){    int i;        init_vlc(&rl->vlc, TEX_VLC_BITS, rl->n + 2,              &rl->table_vlc[0][1], 4, 2,             &rl->table_vlc[0][0], 4, 2);        rl->rl_vlc[0]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM));    for(i=0; i<rl->vlc.table_size; i++){        int code= rl->vlc.table[i][0];        int len = rl->vlc.table[i][1];        int level, run;            if(len==0){ // illegal code            run= 65;            level= MAX_LEVEL;        }else if(len<0){ //more bits needed            run= 0;            level= code;        }else{            if(code==rl->n){ //esc                run= 65;                level= 0;            }else if(code==rl->n+1){ //eob                run= 0;                level= 127;            }else{                run=   rl->table_run  [code] + 1;                level= rl->table_level[code];            }        }        rl->rl_vlc[0][i].len= len;        rl->rl_vlc[0][i].level= level;        rl->rl_vlc[0][i].run= run;    }}static void put_header(MpegEncContext *s, int header){    align_put_bits(&s->pb);    put_bits(&s->pb, 16, header>>16);    put_bits(&s->pb, 16, header&0xFFFF);}/* put sequence header if needed */static void mpeg1_encode_sequence_header(MpegEncContext *s){        unsigned int vbv_buffer_size;        unsigned int fps, v;        int n;        UINT64 time_code;                if (s->picture_in_gop_number == 0) {            /* mpeg1 header repeated every gop */            put_header(s, SEQ_START_CODE);                        /* search closest frame rate */            {                int i, dmin, d;                s->frame_rate_index = 0;                dmin = 0x7fffffff;                for(i=1;i<9;i++) {                    d = abs(s->frame_rate - frame_rate_tab[i]);                    if (d < dmin) {                        dmin = d;                        s->frame_rate_index = i;                    }                }            }             put_bits(&s->pb, 12, s->width);            put_bits(&s->pb, 12, s->height);            put_bits(&s->pb, 4, 1); /* 1/1 aspect ratio */            put_bits(&s->pb, 4, s->frame_rate_index);            v = s->bit_rate / 400;            if (v > 0x3ffff)                v = 0x3ffff;            put_bits(&s->pb, 18, v);            put_bits(&s->pb, 1, 1); /* marker */            if(s->avctx->rc_buffer_size)                vbv_buffer_size = s->avctx->rc_buffer_size;            else                /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */                vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024;	             put_bits(&s->pb, 10, (vbv_buffer_size + 16383) / 16384);             put_bits(&s->pb, 1, 1); /* constrained parameter flag */            put_bits(&s->pb, 1, 0); /* no custom intra matrix */            put_bits(&s->pb, 1, 0); /* no custom non intra matrix */            put_header(s, GOP_START_CODE);            put_bits(&s->pb, 1, 0); /* do drop frame */            /* time code : we must convert from the real frame rate to a               fake mpeg frame rate in case of low frame rate */            fps = frame_rate_tab[s->frame_rate_index];            time_code = (INT64)s->fake_picture_number * FRAME_RATE_BASE;            s->gop_picture_number = s->fake_picture_number;            put_bits(&s->pb, 5, (UINT32)((time_code / (fps * 3600)) % 24));            put_bits(&s->pb, 6, (UINT32)((time_code / (fps * 60)) % 60));            put_bits(&s->pb, 1, 1);            put_bits(&s->pb, 6, (UINT32)((time_code / fps) % 60));            put_bits(&s->pb, 6, (UINT32)((time_code % fps) / FRAME_RATE_BASE));            put_bits(&s->pb, 1, 1); /* closed gop */            put_bits(&s->pb, 1, 0); /* broken link */        }        if (s->frame_rate < (24 * FRAME_RATE_BASE) && s->picture_number > 0) {            /* insert empty P pictures to slow down to the desired               frame rate. Each fake pictures takes about 20 bytes */            fps = frame_rate_tab[s->frame_rate_index];            n = (((INT64)s->picture_number * fps) / s->frame_rate) - 1;            while (s->fake_picture_number < n) {                mpeg1_skip_picture(s, s->fake_picture_number -                                    s->gop_picture_number);                 s->fake_picture_number++;            }        }}/* insert a fake P picture */static void mpeg1_skip_picture(MpegEncContext *s, int pict_num){    unsigned int mb_incr;    /* mpeg1 picture header */    put_header(s, PICTURE_START_CODE);    /* temporal reference */    put_bits(&s->pb, 10, pict_num & 0x3ff);         put_bits(&s->pb, 3, P_TYPE);    put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */        put_bits(&s->pb, 1, 1); /* integer coordinates */    put_bits(&s->pb, 3, 1); /* forward_f_code */        put_bits(&s->pb, 1, 0); /* extra bit picture */        /* only one slice */    put_header(s, SLICE_MIN_START_CODE);    put_bits(&s->pb, 5, 1); /* quantizer scale */    put_bits(&s->pb, 1, 0); /* slice extra information */        mb_incr = 1;    put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],              mbAddrIncrTable[mb_incr - 1][0]);        /* empty macroblock */    put_bits(&s->pb, 3, 1); /* motion only */        /* zero motion x & y */    put_bits(&s->pb, 1, 1);     put_bits(&s->pb, 1, 1);     /* output a number of empty slice */    mb_incr = s->mb_width * s->mb_height - 1;    while (mb_incr > 33) {        put_bits(&s->pb, 11, 0x008);        mb_incr -= 33;    }    put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],              mbAddrIncrTable[mb_incr - 1][0]);        /* empty macroblock */    put_bits(&s->pb, 3, 1); /* motion only */        /* zero motion x & y */    put_bits(&s->pb, 1, 1);     put_bits(&s->pb, 1, 1); }static void common_init(MpegEncContext *s){    s->y_dc_scale_table=    s->c_dc_scale_table= ff_mpeg1_dc_scale_table;}void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number){    mpeg1_encode_sequence_header(s);    /* mpeg1 picture header */    put_header(s, PICTURE_START_CODE);    /* temporal reference */    put_bits(&s->pb, 10, (s->fake_picture_number -                           s->gop_picture_number) & 0x3ff);     s->fake_picture_number++;        put_bits(&s->pb, 3, s->pict_type);    put_bits(&s->pb, 16, 0xffff); /* non constant bit rate */        if (s->pict_type == P_TYPE) {        put_bits(&s->pb, 1, 0); /* half pel coordinates */        put_bits(&s->pb, 3, s->f_code); /* forward_f_code */    }        put_bits(&s->pb, 1, 0); /* extra bit picture */        /* only one slice */    put_header(s, SLICE_MIN_START_CODE);    put_bits(&s->pb, 5, s->qscale); /* quantizer scale */    put_bits(&s->pb, 1, 0); /* slice extra information */}void mpeg1_encode_mb(MpegEncContext *s,                     DCTELEM block[6][64],                     int motion_x, int motion_y){    int mb_incr, i, cbp, mb_x, mb_y;    mb_x = s->mb_x;    mb_y = s->mb_y;    /* compute cbp */    cbp = 0;    for(i=0;i<6;i++) {        if (s->block_last_index[i] >= 0)            cbp |= 1 << (5 - i);    }    /* skip macroblock, except if first or last macroblock of a slice */    if ((cbp | motion_x | motion_y) == 0 &&        (!((mb_x | mb_y) == 0 ||           (mb_x == s->mb_width - 1 && mb_y == s->mb_height - 1)))) {        s->mb_incr++;        s->qscale -= s->dquant;        s->skip_count++;        s->misc_bits++;        s->last_bits++;    } else {        /* output mb incr */        mb_incr = s->mb_incr;        while (mb_incr > 33) {            put_bits(&s->pb, 11, 0x008);            mb_incr -= 33;        }        put_bits(&s->pb, mbAddrIncrTable[mb_incr - 1][1],                  mbAddrIncrTable[mb_incr - 1][0]);                if (s->pict_type == I_TYPE) {            if(s->dquant && cbp){                put_bits(&s->pb, 2, 1); /* macroblock_type : macroblock_quant = 1 */                put_bits(&s->pb, 5, s->qscale);            }else{                put_bits(&s->pb, 1, 1); /* macroblock_type : macroblock_quant = 0 */                s->qscale -= s->dquant;            }            s->misc_bits+= get_bits_diff(s);            s->i_count++;        } else {            if (s->mb_intra) {                if(s->dquant && cbp){                    put_bits(&s->pb, 6, 0x01);                    put_bits(&s->pb, 5, s->qscale);                }else{                    put_bits(&s->pb, 5, 0x03);                    s->qscale -= s->dquant;                }                s->misc_bits+= get_bits_diff(s);                s->i_count++;            } else {                if (cbp != 0) {                    if (motion_x == 0 && motion_y == 0) {                        if(s->dquant){                            put_bits(&s->pb, 5, 1); /* macroblock_pattern & quant */                            put_bits(&s->pb, 5, s->qscale);                        }else{                            put_bits(&s->pb, 2, 1); /* macroblock_pattern only */                        }                        s->misc_bits+= get_bits_diff(s);                        put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);                    } else {                        if(s->dquant){                            put_bits(&s->pb, 5, 2); /* motion + cbp */                            put_bits(&s->pb, 5, s->qscale);                        }else{                            put_bits(&s->pb, 1, 1); /* motion + cbp */                        }                        s->misc_bits+= get_bits_diff(s);                        mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]);                         mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]);                         s->mv_bits+= get_bits_diff(s);                        put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);                    }                } else {                    put_bits(&s->pb, 3, 1); /* motion only */                    mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0]);                     mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1]);                     s->qscale -= s->dquant;                    s->mv_bits+= get_bits_diff(s);                }                s->f_count++;            }        }        for(i=0;i<6;i++) {            if (cbp & (1 << (5 - i))) {                mpeg1_encode_block(s, block[i], i);            }        }        s->mb_incr = 1;        if(s->mb_intra)            s->i_tex_bits+= get_bits_diff(s);        else            s->p_tex_bits+= get_bits_diff(s);    }    s->last_mv[0][0][0] = motion_x;    s->last_mv[0][0][1] = motion_y;}static void mpeg1_encode_motion(MpegEncContext *s, int val){

⌨️ 快捷键说明

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