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

📄 mpeg12.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * MPEG1/2 decoder * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * * FFmpeg 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.1 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 mpeg12.c * MPEG1/2 decoder *///#define DEBUG#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "mpeg12.h"#include "mpeg12data.h"#include "mpeg12decdata.h"#include "bytestream.h"#undef memcpy#define memcpy uc_memcpy//#undef NDEBUG//#include <assert.h>#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 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 mpeg1_fast_decode_block_inter(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 inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n);static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);static void exchange_uv(MpegEncContext *s);extern int XVMC_field_start(MpegEncContext *s, AVCodecContext *avctx);extern int XVMC_field_end(MpegEncContext *s);extern void XVMC_pack_pblocks(MpegEncContext *s,int cbp);extern void XVMC_init_block(MpegEncContext *s);//set s->blockstatic const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,-1};static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,-1};static const enum PixelFormat pixfmt_yuv_444[]= {PIX_FMT_YUV444P,-1};static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {                                           PIX_FMT_XVMC_MPEG2_IDCT,                                           PIX_FMT_XVMC_MPEG2_MC,                                           -1};uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];static void init_2d_vlc_rl(RLTable *rl, int use_static){    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, use_static);    if(use_static)        rl->rl_vlc[0]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM));    else        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;    }}void ff_mpeg12_common_init(MpegEncContext *s){    s->y_dc_scale_table=    s->c_dc_scale_table= mpeg2_dc_scale_table[s->intra_dc_precision];}void ff_mpeg1_clean_buffers(MpegEncContext *s){    s->last_dc[0] = 1 << (7 + s->intra_dc_precision);    s->last_dc[1] = s->last_dc[0];    s->last_dc[2] = s->last_dc[0];    memset(s->last_mv, 0, sizeof(s->last_mv));}/******************************************//* decoding */static VLC dc_lum_vlc;static VLC dc_chroma_vlc;static VLC mv_vlc;static VLC mbincr_vlc;static VLC mb_ptype_vlc;static VLC mb_btype_vlc;static VLC mb_pat_vlc;static int done = 0;void mpeg12_init(){	F("%s\n",__FUNCTION__);	done = 0;}static void init_vlcs(void){        if (!done)     {        done = 1;        init_vlc(&dc_lum_vlc, DC_VLC_BITS, 12,                 ff_mpeg12_vlc_dc_lum_bits, 1, 1,                 ff_mpeg12_vlc_dc_lum_code, 2, 2, 1);        init_vlc(&dc_chroma_vlc,  DC_VLC_BITS, 12,                 ff_mpeg12_vlc_dc_chroma_bits, 1, 1,                 ff_mpeg12_vlc_dc_chroma_code, 2, 2, 1);        init_vlc(&mv_vlc, MV_VLC_BITS, 17,                 &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,                 &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 1);        init_vlc(&mbincr_vlc, MBINCR_VLC_BITS, 36,                 &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,                 &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 1);        init_vlc(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,                 &ff_mpeg12_mbPatTable[0][1], 2, 1,                 &ff_mpeg12_mbPatTable[0][0], 2, 1, 1);        init_vlc(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,                 &table_mb_ptype[0][1], 2, 1,                 &table_mb_ptype[0][0], 2, 1, 1);        init_vlc(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,                 &table_mb_btype[0][1], 2, 1,                 &table_mb_btype[0][0], 2, 1, 1);        init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);        init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);        init_2d_vlc_rl(&ff_rl_mpeg1, 1);        init_2d_vlc_rl(&ff_rl_mpeg2, 1);    }}static inline int get_dmv(MpegEncContext *s){    if(get_bits1(&s->gb))        return 1 - (get_bits1(&s->gb) << 1);    else        return 0;}static inline int get_qscale(MpegEncContext *s){    int qscale = get_bits(&s->gb, 5);    if (s->q_scale_type) {        return non_linear_qscale[qscale];    } else {        return qscale << 1;    }}/* motion type (for mpeg2) */#define MT_FIELD 1#define MT_FRAME 2#define MT_16X8  2#define MT_DMV   3static int mpeg_decode_mb(MpegEncContext *s,                          DCTELEM block[12][64]){    int i, j, k, cbp, val, mb_type, motion_type;    const int mb_block_count = 4 + (1<< s->chroma_format);    dprintf(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);    assert(s->mb_skipped==0);    if (s->mb_skip_run-- != 0) {        if (s->pict_type == P_TYPE) {            s->mb_skipped = 1;            s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;        } else {            int mb_type;            if(s->mb_x)                mb_type= s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1];            else                mb_type= s->current_picture.mb_type[ s->mb_width + (s->mb_y-1)*s->mb_stride - 1]; // FIXME not sure if this is allowed in mpeg at all,            if(IS_INTRA(mb_type))                return -1;            s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]=                mb_type | MB_TYPE_SKIP;//            assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8));            if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0)                s->mb_skipped = 1;        }        return 0;    }    switch(s->pict_type) {    default:    case I_TYPE:        if (get_bits1(&s->gb) == 0) {            if (get_bits1(&s->gb) == 0){                av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);                return -1;            }            mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;        } else {            mb_type = MB_TYPE_INTRA;        }        break;    case P_TYPE:        mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);        if (mb_type < 0){            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);            return -1;        }        mb_type = ptype2mb_type[ mb_type ];        break;    case B_TYPE:        mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);        if (mb_type < 0){            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);            return -1;        }        mb_type = btype2mb_type[ mb_type ];        break;    }    dprintf(s->avctx, "mb_type=%x\n", mb_type);//    motion_type = 0; /* avoid warning */    if (IS_INTRA(mb_type)) {        s->dsp.clear_blocks(s->block[0]);        if(!s->chroma_y_shift){            s->dsp.clear_blocks(s->block[6]);        }        /* compute dct type */        if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var?            !s->frame_pred_frame_dct) {            s->interlaced_dct = get_bits1(&s->gb);        }        if (IS_QUANT(mb_type))            s->qscale = get_qscale(s);        if (s->concealment_motion_vectors) {            /* just parse them */            if (s->picture_structure != PICT_FRAME)                skip_bits1(&s->gb); /* field select */            s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =                mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);            s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =                mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);            skip_bits1(&s->gb); /* marker */        }else            memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */        s->mb_intra = 1;#ifdef HAVE_XVMC        //one 1 we memcpy blocks in xvmcvideo        if(s->avctx->xvmc_acceleration > 1){            XVMC_pack_pblocks(s,-1);//inter are always full blocks            if(s->swap_uv){                exchange_uv(s);            }        }#endif        if (s->codec_id == CODEC_ID_MPEG2VIDEO) {            if(s->flags2 & CODEC_FLAG2_FAST){                for(i=0;i<6;i++) {                    mpeg2_fast_decode_block_intra(s, s->pblocks[i], i);                }            }else{                for(i=0;i<mb_block_count;i++) {                    if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0)                        return -1;                }            }        } else {            for(i=0;i<6;i++) {                if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0)                    return -1;            }        }    } else {        if (mb_type & MB_TYPE_ZERO_MV){            assert(mb_type & MB_TYPE_CBP);            s->mv_dir = MV_DIR_FORWARD;            if(s->picture_structure == PICT_FRAME){                if(!s->frame_pred_frame_dct)                    s->interlaced_dct = get_bits1(&s->gb);                s->mv_type = MV_TYPE_16X16;            }else{                s->mv_type = MV_TYPE_FIELD;                mb_type |= MB_TYPE_INTERLACED;                s->field_select[0][0]= s->picture_structure - 1;            }            if (IS_QUANT(mb_type))                s->qscale = get_qscale(s);            s->last_mv[0][0][0] = 0;            s->last_mv[0][0][1] = 0;            s->last_mv[0][1][0] = 0;            s->last_mv[0][1][1] = 0;            s->mv[0][0][0] = 0;            s->mv[0][0][1] = 0;        }else{            assert(mb_type & MB_TYPE_L0L1);//FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED            /* get additional motion vector type */            if (s->frame_pred_frame_dct)                motion_type = MT_FRAME;            else{                motion_type = get_bits(&s->gb, 2);                if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))                    s->interlaced_dct = get_bits1(&s->gb);            }            if (IS_QUANT(mb_type))

⌨️ 快捷键说明

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