📄 mpeg12.c
字号:
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 + -