mpegvideo.c

来自「arm平台下的H264编码和解码源代码」· C语言 代码 · 共 1,779 行 · 第 1/5 页

C
1,779
字号
       s->hurry_up= s->avctx->hurry_up;    s->error_resilience= avctx->error_resilience;    /* set dequantizer, we cant do it during init as it might change for mpeg4       and we cant do it in the header decode as init isnt called for mpeg4 there yet */    if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){        s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;    }else if(s->out_format == FMT_H263){        s->dct_unquantize_intra = s->dct_unquantize_h263_intra;        s->dct_unquantize_inter = s->dct_unquantize_h263_inter;    }else{        s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;        s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;    }    if(s->dct_error_sum){
#ifndef WINCE //assert        assert(s->avctx->noise_reduction && s->encoding);#endif        update_noise_reduction(s);    }        #ifdef HAVE_XVMC    if(s->avctx->xvmc_acceleration)        return XVMC_field_start(s, avctx);#endif    return 0;}/* generic function for encode/decode called after a frame has been coded/decoded */void MPV_frame_end(MpegEncContext *s){    int i;    /* draw edge for correct motion prediction if outside */#ifdef HAVE_XVMC//just to make sure that all data is rendered.    if(s->avctx->xvmc_acceleration){        XVMC_field_end(s);    }else#endif    if(s->unrestricted_mv && s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {            draw_edges(s->current_picture.data[0], s->linesize  , s->h_edge_pos   , s->v_edge_pos   , EDGE_WIDTH  );            draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);            draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2);    }    emms_c();        s->last_pict_type    = s->pict_type;    if(s->pict_type!=B_TYPE){        s->last_non_b_pict_type= s->pict_type;    }#if 0        /* copy back current_picture variables */    for(i=0; i<MAX_PICTURE_COUNT; i++){        if(s->picture[i].data[0] == s->current_picture.data[0]){            s->picture[i]= s->current_picture;            break;        }        }    assert(i<MAX_PICTURE_COUNT);#endif        if(s->encoding){        /* release non refernce frames */        for(i=0; i<MAX_PICTURE_COUNT; i++){            if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){                s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[i]);            }        }    }    // clear copies, to avoid confusion#if 0    memset(&s->last_picture, 0, sizeof(Picture));    memset(&s->next_picture, 0, sizeof(Picture));    memset(&s->current_picture, 0, sizeof(Picture));#endif}/** * draws an line from (ex, ey) -> (sx, sy). * @param w width of the image * @param h height of the image * @param stride stride/linesize of the image * @param color color of the arrow */static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){    int t, x, y, fr, f;        sx= clip(sx, 0, w-1);    sy= clip(sy, 0, h-1);    ex= clip(ex, 0, w-1);    ey= clip(ey, 0, h-1);        buf[sy*stride + sx]+= color;        if(ABS(ex - sx) > ABS(ey - sy)){        if(sx > ex){            t=sx; sx=ex; ex=t;            t=sy; sy=ey; ey=t;        }        buf+= sx + sy*stride;        ex-= sx;        f= ((ey-sy)<<16)/ex;        for(x= 0; x <= ex; x++){            y = (x*f)>>16;            fr= (x*f)&0xFFFF;            buf[ y   *stride + x]+= (color*(0x10000-fr))>>16;            buf[(y+1)*stride + x]+= (color*         fr )>>16;        }    }else{        if(sy > ey){            t=sx; sx=ex; ex=t;            t=sy; sy=ey; ey=t;        }        buf+= sx + sy*stride;        ey-= sy;        if(ey) f= ((ex-sx)<<16)/ey;        else   f= 0;        for(y= 0; y <= ey; y++){            x = (y*f)>>16;            fr= (y*f)&0xFFFF;            buf[y*stride + x  ]+= (color*(0x10000-fr))>>16;;            buf[y*stride + x+1]+= (color*         fr )>>16;;        }    }}/** * draws an arrow from (ex, ey) -> (sx, sy). * @param w width of the image * @param h height of the image * @param stride stride/linesize of the image * @param color color of the arrow */static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h, int stride, int color){     int dx,dy;    sx= clip(sx, -100, w+100);    sy= clip(sy, -100, h+100);    ex= clip(ex, -100, w+100);    ey= clip(ey, -100, h+100);        dx= ex - sx;    dy= ey - sy;        if(dx*dx + dy*dy > 3*3){        int rx=  dx + dy;        int ry= -dx + dy;        int length= ff_sqrt((rx*rx + ry*ry)<<8);                //FIXME subpixel accuracy        rx= ROUNDED_DIV(rx*3<<4, length);        ry= ROUNDED_DIV(ry*3<<4, length);                draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color);        draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color);    }    draw_line(buf, sx, sy, ex, ey, w, h, stride, color);}/** * prints debuging info for the given picture. */void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){    if(!pict || !pict->mb_type) return;    if(s->avctx->debug&(FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)){        int x,y;                av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: ");        switch (pict->pict_type) {            case FF_I_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"I\n"); break;            case FF_P_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"P\n"); break;            case FF_B_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"B\n"); break;            case FF_S_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"S\n"); break;            case FF_SI_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); break;            case FF_SP_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); break;                    }        for(y=0; y<s->mb_height; y++){            for(x=0; x<s->mb_width; x++){                if(s->avctx->debug&FF_DEBUG_SKIP){                    int count= s->mbskip_table[x + y*s->mb_stride];                    if(count>9) count=9;                    av_log(s->avctx, AV_LOG_DEBUG, "%1d", count);                }                if(s->avctx->debug&FF_DEBUG_QP){                    av_log(s->avctx, AV_LOG_DEBUG, "%2d", pict->qscale_table[x + y*s->mb_stride]);                }                if(s->avctx->debug&FF_DEBUG_MB_TYPE){                    int mb_type= pict->mb_type[x + y*s->mb_stride];                    //Type & MV direction                    if(IS_PCM(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "P");                    else if(IS_INTRA(mb_type) && IS_ACPRED(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "A");                    else if(IS_INTRA4x4(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "i");                    else if(IS_INTRA16x16(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "I");                    else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "d");                    else if(IS_DIRECT(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "D");                    else if(IS_GMC(mb_type) && IS_SKIP(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "g");                    else if(IS_GMC(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "G");                    else if(IS_SKIP(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "S");                    else if(!USES_LIST(mb_type, 1))                        av_log(s->avctx, AV_LOG_DEBUG, ">");                    else if(!USES_LIST(mb_type, 0))                        av_log(s->avctx, AV_LOG_DEBUG, "<");                    else{
#ifndef WINCE //assert                        assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));#endif
						av_log(s->avctx, AV_LOG_DEBUG, "X");                    }                                        //segmentation                    if(IS_8X8(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "+");                    else if(IS_16X8(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "-");                    else if(IS_8X16(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, "?");                    else if(IS_INTRA(mb_type) || IS_16X16(mb_type))                        av_log(s->avctx, AV_LOG_DEBUG, " ");                    else                        av_log(s->avctx, AV_LOG_DEBUG, "?");                                                                if(IS_INTERLACED(mb_type) && s->codec_id == CODEC_ID_H264)                        av_log(s->avctx, AV_LOG_DEBUG, "=");                    else                        av_log(s->avctx, AV_LOG_DEBUG, " ");                }//                av_log(s->avctx, AV_LOG_DEBUG, " ");            }            av_log(s->avctx, AV_LOG_DEBUG, "\n");        }    }    if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){        const int shift= 1 + s->quarter_sample;        int mb_y;        uint8_t *ptr;        int i;        int h_chroma_shift, v_chroma_shift;        s->low_delay=0; //needed to see the vectors without trashing the buffers        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);        for(i=0; i<3; i++){            memcpy(s->visualization_buffer[i], pict->data[i], (i==0) ? pict->linesize[i]*s->height:pict->linesize[i]*s->height >> v_chroma_shift);            pict->data[i]= s->visualization_buffer[i];        }        pict->type= FF_BUFFER_TYPE_COPY;        ptr= pict->data[0];        for(mb_y=0; mb_y<s->mb_height; mb_y++){            int mb_x;            for(mb_x=0; mb_x<s->mb_width; mb_x++){                const int mb_index= mb_x + mb_y*s->mb_stride;                if((s->avctx->debug_mv) && pict->motion_val){                  int type;                  for(type=0; type<3; type++){                    int direction;                    switch (type) {                      case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE))                                continue;                              direction = 0;                              break;                      case 1: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_FOR)) || (pict->pict_type!=FF_B_TYPE))                                continue;                              direction = 0;                              break;                      case 2: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_BACK)) || (pict->pict_type!=FF_B_TYPE))                                continue;                              direction = 1;                              break;                    }                    if(!USES_LIST(pict->mb_type[mb_index], direction))                        continue;                    //FIXME for h264                    if(IS_8X8(pict->mb_type[mb_index])){                      int i;                      for(i=0; i<4; i++){                        int sx= mb_x*16 + 4 + 8*(i&1);                        int sy= mb_y*16 + 4 + 8*(i>>1);                        int xy= mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride;                        int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;                        int my= (pict->motion_val[direction][xy][1]>>shift) + sy;                        draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);                      }                    }else if(IS_16X8(pict->mb_type[mb_index])){                      int i;                      for(i=0; i<2; i++){                        int sx=mb_x*16 + 8;                        int sy=mb_y*16 + 4 + 8*i;                        int xy= mb_x*2 + (mb_y*2 + i)*s->b8_stride;                        int mx=(pict->motion_val[direction][xy][0]>>shift) + sx;                        int my=(pict->motion_val[direction][xy][1]>>shift) + sy;                        draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);                      }                    }else{                      int sx= mb_x*16 + 8;                      int sy= mb_y*16 + 8;                      int xy= mb_x*2 + mb_y*2*s->b8_stride;                      int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;                      int my= (pict->motion_val[direction][xy][1]>>shift) + sy;                      draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);                    }                  }                                  }                if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){
#ifdef WINCE
                    uint64_t c= (pict->qscale_table[mb_index]*128/31) * (uint64_t) 0x0101010101010101;
#else                    uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL;#endif
					int y;                    for(y=0; y<8; y++){                        *(uint64_t*)(pict->data[1] + 8*mb_x + (8*mb_y + y)*pict->linesize[1])= c;                        *(uint64_t*)(pict->data[2] + 8*mb_x + (8*mb_y + y)*pict->linesize[2])= c;                    }                }                if((s->avctx->debug&FF_DEBUG_VIS_MB_TYPE) && pict->motion_val){                    int mb_type= pict->mb_type[mb_index];                    uint64_t u,v;                    int y;#define COLOR(theta, r)\u= (int)(128 + r*cos(theta*3.141592/180));\v= (int)(128 + r*sin(theta*3.141592/180));                                        u=v=128;                    if(IS_PCM(mb_type)){                        COLOR(120,48)                    }else if((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) || IS_INTRA16x16(mb_type)){                        COLOR(30,48)                    }else if(IS_INTRA4x4(mb_type)){                        COLOR(90,48)                    }else if(IS_DIRECT(mb_type) && IS_SKIP(mb_type)){//                        COLOR(120,48)                    }else if(IS_DIRECT(mb_type)){                        COLOR(150,48)                    }else if(IS_GMC(mb_type) && IS_SKIP(mb_type)){                        COLOR(170,48)                    }else if(IS_GMC(mb_type)){                  

⌨️ 快捷键说明

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