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

📄 mpeg12.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
        fprintf(stderr, "slice below image (%d >= %d)\n", start_code, s->mb_height);        return DECODE_SLICE_ERROR;    }    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));    /* start frame decoding */    if (s->first_slice) {        s->first_slice = 0;        if(MPV_frame_start(s, avctx) < 0)            return DECODE_SLICE_FATAL_ERROR;    }    init_get_bits(&s->gb, buf, buf_size);    s->qscale = get_qscale(s);    /* extra slice info */    while (get_bits1(&s->gb) != 0) {        skip_bits(&s->gb, 8);    }    s->mb_x=0;    for(;;) {        int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);        if (code < 0)            return -1; /* error = end of slice, but empty slice is bad or?*/        if (code >= 33) {            if (code == 33) {                s->mb_x += 33;            }            /* otherwise, stuffing, nothing to do */        } else {            s->mb_x += code;            break;        }    }    s->mb_y = start_code;    s->mb_incr= 1;    for(;;) {	s->dsp.clear_blocks(s->block[0]);                ret = mpeg_decode_mb(s, s->block);        dprintf("ret=%d\n", ret);        if (ret < 0)            return -1;            MPV_decode_mb(s, s->block);        if (++s->mb_x >= s->mb_width) {            ff_draw_horiz_band(s);            s->mb_x = 0;            s->mb_y++;            PRINT_QP("%s", "\n");        }        PRINT_QP("%2d", s->qscale);        /* skip mb handling */        if (s->mb_incr == 0) {            /* read again increment */            s->mb_incr = 1;            for(;;) {                int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);                if (code < 0)                    goto eos; /* error = end of slice */                if (code >= 33) {                    if (code == 33) {                        s->mb_incr += 33;                    }                    /* otherwise, stuffing, nothing to do */                } else {                    s->mb_incr += code;                    break;                }            }        }        if(s->mb_y >= s->mb_height){            fprintf(stderr, "slice too long\n");            return DECODE_SLICE_ERROR;        }    }eos: //end of slice        emms_c();    /* end of slice reached */    if (/*s->mb_x == 0 &&*/        s->mb_y == s->mb_height) {        /* end of image */        UINT8 **picture;        MPV_frame_end(s);        if (s->pict_type == B_TYPE) {            picture = s->current_picture;            avctx->quality = s->qscale;        } else {            /* latency of 1 frame for I and P frames */            /* XXX: use another variable than picture_number */            if (s->picture_number == 0) {                picture = NULL;            } else {                picture = s->last_picture;                avctx->quality = s->last_qscale;            }            s->last_qscale = s->qscale;            s->picture_number++;        }        if(s->mpeg2)            avctx->quality>>=1;        if (picture) {            pict->data[0] = picture[0];            pict->data[1] = picture[1];            pict->data[2] = picture[2];            pict->linesize[0] = s->linesize;            pict->linesize[1] = s->uvlinesize;            pict->linesize[2] = s->uvlinesize;            return DECODE_SLICE_EOP;        } else {            return DECODE_SLICE_OK;        }    } else {        return DECODE_SLICE_OK;    }}static int mpeg1_decode_sequence(AVCodecContext *avctx,                                  UINT8 *buf, int buf_size){    Mpeg1Context *s1 = avctx->priv_data;    MpegEncContext *s = &s1->mpeg_enc_ctx;    int width, height, i, v, j;    init_get_bits(&s->gb, buf, buf_size);    width = get_bits(&s->gb, 12);    height = get_bits(&s->gb, 12);    skip_bits(&s->gb, 4);    s->frame_rate_index = get_bits(&s->gb, 4);    if (s->frame_rate_index == 0)        return -1;    s->bit_rate = get_bits(&s->gb, 18) * 400;    if (get_bits1(&s->gb) == 0) /* marker */        return -1;    if (width <= 0 || height <= 0 ||        (width % 2) != 0 || (height % 2) != 0)        return -1;    if (width != s->width ||        height != s->height) {        /* start new mpeg1 context decoding */        s->out_format = FMT_MPEG1;        if (s1->mpeg_enc_ctx_allocated) {            MPV_common_end(s);        }        s->width = width;        s->height = height;        avctx->has_b_frames= s->has_b_frames = 1;        s->avctx = avctx;        avctx->width = width;        avctx->height = height;        if (s->frame_rate_index >= 9) {            /* at least give a valid frame rate (some old mpeg1 have this) */            avctx->frame_rate = 25 * FRAME_RATE_BASE;        } else {            avctx->frame_rate = frame_rate_tab[s->frame_rate_index];        }        s->frame_rate = avctx->frame_rate;        avctx->bit_rate = s->bit_rate;                if (MPV_common_init(s) < 0)            return -1;        s1->mpeg_enc_ctx_allocated = 1;    }    skip_bits(&s->gb, 10); /* vbv_buffer_size */    skip_bits(&s->gb, 1);    /* get matrix */    if (get_bits1(&s->gb)) {        for(i=0;i<64;i++) {            v = get_bits(&s->gb, 8);            j = s->intra_scantable.permutated[i];            s->intra_matrix[j] = v;            s->chroma_intra_matrix[j] = v;        }#ifdef DEBUG        dprintf("intra matrix present\n");        for(i=0;i<64;i++)            dprintf(" %d", s->intra_matrix[s->intra_scantable.permutated[i]]);        printf("\n");#endif    } else {        for(i=0;i<64;i++) {            int j= s->idct_permutation[i];            v = ff_mpeg1_default_intra_matrix[i];            s->intra_matrix[j] = v;            s->chroma_intra_matrix[j] = v;        }    }    if (get_bits1(&s->gb)) {        for(i=0;i<64;i++) {            v = get_bits(&s->gb, 8);            j = s->intra_scantable.permutated[i];            s->inter_matrix[j] = v;            s->chroma_inter_matrix[j] = v;        }#ifdef DEBUG        dprintf("non intra matrix present\n");        for(i=0;i<64;i++)            dprintf(" %d", s->inter_matrix[s->intra_scantable.permutated[i]]);        printf("\n");#endif    } else {        for(i=0;i<64;i++) {            int j= s->idct_permutation[i];            v = ff_mpeg1_default_non_intra_matrix[i];            s->inter_matrix[j] = v;            s->chroma_inter_matrix[j] = v;        }    }    /* we set mpeg2 parameters so that it emulates mpeg1 */    s->progressive_sequence = 1;    s->progressive_frame = 1;    s->picture_structure = PICT_FRAME;    s->frame_pred_frame_dct = 1;    s->mpeg2 = 0;    avctx->sub_id = 1; /* indicates mpeg1 */    return 0;}/* handle buffering and image synchronisation */static int mpeg_decode_frame(AVCodecContext *avctx,                              void *data, int *data_size,                             UINT8 *buf, int buf_size){    Mpeg1Context *s = avctx->priv_data;    UINT8 *buf_end, *buf_ptr, *buf_start;    int len, start_code_found, ret, code, start_code, input_size;    AVPicture *picture = data;    MpegEncContext *s2 = &s->mpeg_enc_ctx;                dprintf("fill_buffer\n");    *data_size = 0;    /* special case for last picture */    if (buf_size == 0) {        if (s2->picture_number > 0) {            picture->data[0] = s2->next_picture[0];            picture->data[1] = s2->next_picture[1];            picture->data[2] = s2->next_picture[2];            picture->linesize[0] = s2->linesize;            picture->linesize[1] = s2->uvlinesize;            picture->linesize[2] = s2->uvlinesize;            *data_size = sizeof(AVPicture);        }        return 0;    }    buf_ptr = buf;    buf_end = buf + buf_size;#if 0        if (s->repeat_field % 2 == 1) {         s->repeat_field++;        //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number,        //        s2->picture_number, s->repeat_field);        if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) {            *data_size = sizeof(AVPicture);            goto the_end;        }    }#endif    while (buf_ptr < buf_end) {        buf_start = buf_ptr;        /* find start next code */        code = find_start_code(&buf_ptr, buf_end, &s->header_state);        if (code >= 0) {            start_code_found = 1;        } else {            start_code_found = 0;        }        /* copy to buffer */        len = buf_ptr - buf_start;        if (len + (s->buf_ptr - s->buffer) > s->buffer_size) {            /* data too big : flush */            s->buf_ptr = s->buffer;            if (start_code_found)                s->start_code = code;        } else {            memcpy(s->buf_ptr, buf_start, len);            s->buf_ptr += len;            if(   (!(s2->flags&CODEC_FLAG_TRUNCATED)) && (!start_code_found)                && s->buf_ptr+4<s->buffer+s->buffer_size){                start_code_found= 1;                code= 0x1FF;                s->header_state=0xFF;                s->buf_ptr[0]=0;                s->buf_ptr[1]=0;                s->buf_ptr[2]=1;                s->buf_ptr[3]=0xFF;                s->buf_ptr+=4;            }            if (start_code_found) {                /* prepare data for next start code */                input_size = s->buf_ptr - s->buffer;                start_code = s->start_code;                s->buf_ptr = s->buffer;                s->start_code = code;                switch(start_code) {                case SEQ_START_CODE:                    mpeg1_decode_sequence(avctx, s->buffer,                                           input_size);                    break;                                            case PICTURE_START_CODE:                    /* we have a complete image : we try to decompress it */                    mpeg1_decode_picture(avctx,                                          s->buffer, input_size);                    break;                case EXT_START_CODE:                    mpeg_decode_extension(avctx,                                          s->buffer, input_size);                    break;                default:                    if (start_code >= SLICE_MIN_START_CODE &&                        start_code <= SLICE_MAX_START_CODE && s2->avctx->hurry_up<5) {                        ret = mpeg_decode_slice(avctx, picture,                                                start_code, s->buffer, input_size);                        if (ret == DECODE_SLICE_EOP) {                            /* got a picture: exit */                            /* first check if we must repeat the frame */                            avctx->repeat_pict = 0;#if 0                            if (s2->progressive_frame && s2->repeat_first_field) {                                //fprintf(stderr,"\nRepeat this frame: %d! pict: %d",avctx->frame_number,s2->picture_number);                                //s2->repeat_first_field = 0;                                //s2->progressive_frame = 0;                                if (++s->repeat_field > 2)                                    s->repeat_field = 0;                                avctx->repeat_pict = 1;                            }#endif                                                  if (s2->repeat_first_field) {                                if (s2->progressive_sequence) {                                    if (s2->top_field_first)                                        avctx->repeat_pict = 4;                                    else                                        avctx->repeat_pict = 2;                                } else if (s2->progressive_frame) {                                    avctx->repeat_pict = 1;                                }                            }                                     *data_size = sizeof(AVPicture);                            goto the_end;                        }else if(ret<0){                            printf("Error while decoding slice\n");			    if(ret==DECODE_SLICE_FATAL_ERROR) return -1;                        }                    }                    break;                }            }        }    } the_end:    return buf_ptr - buf;}static int mpeg_decode_end(AVCodecContext *avctx){    Mpeg1Context *s = avctx->priv_data;    if (s->mpeg_enc_ctx_allocated)        MPV_common_end(&s->mpeg_enc_ctx);    return 0;}AVCodec mpeg_decoder = {    "mpegvideo",    CODEC_TYPE_VIDEO,    CODEC_ID_MPEG1VIDEO,    sizeof(Mpeg1Context),    mpeg_decode_init,    NULL,    mpeg_decode_end,    mpeg_decode_frame,    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,};

⌨️ 快捷键说明

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