📄 mpeg12.c
字号:
v = get_bits(&s->gb, 8); j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; 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->dsp.idct_permutation[ ff_zigzag_direct[i] ]; s->chroma_inter_matrix[j] = v; } }}static void mpeg_decode_picture_coding_extension(MpegEncContext *s){ s->full_pel[0] = s->full_pel[1] = 0; s->mpeg_f_code[0][0] = get_bits(&s->gb, 4); s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); s->intra_dc_precision = get_bits(&s->gb, 2); s->picture_structure = get_bits(&s->gb, 2); s->top_field_first = get_bits1(&s->gb); s->frame_pred_frame_dct = get_bits1(&s->gb); s->concealment_motion_vectors = get_bits1(&s->gb); s->q_scale_type = get_bits1(&s->gb); s->intra_vlc_format = get_bits1(&s->gb); s->alternate_scan = get_bits1(&s->gb); s->repeat_first_field = get_bits1(&s->gb); s->chroma_420_type = get_bits1(&s->gb); s->progressive_frame = get_bits1(&s->gb); if(s->picture_structure == PICT_FRAME){ s->first_field=0; s->v_edge_pos= 16*s->mb_height; }else{ s->first_field ^= 1; s->v_edge_pos= 8*s->mb_height; memset(s->mbskip_table, 0, s->mb_stride*s->mb_height); } if(s->alternate_scan){ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); }else{ ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); } /* composite display not parsed */ dprintf(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision); dprintf(s->avctx, "picture_structure=%d\n", s->picture_structure); dprintf(s->avctx, "top field first=%d\n", s->top_field_first); dprintf(s->avctx, "repeat first field=%d\n", s->repeat_first_field); dprintf(s->avctx, "conceal=%d\n", s->concealment_motion_vectors); dprintf(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format); dprintf(s->avctx, "alternate_scan=%d\n", s->alternate_scan); dprintf(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct); dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame);}static void mpeg_decode_extension(AVCodecContext *avctx, const uint8_t *buf, int buf_size){ Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; int ext_type; init_get_bits(&s->gb, buf, buf_size*8); ext_type = get_bits(&s->gb, 4); switch(ext_type) { case 0x1: mpeg_decode_sequence_extension(s1); break; case 0x2: mpeg_decode_sequence_display_extension(s1); break; case 0x3: mpeg_decode_quant_matrix_extension(s); break; case 0x7: mpeg_decode_picture_display_extension(s1); break; case 0x8: mpeg_decode_picture_coding_extension(s); break; }}static void exchange_uv(MpegEncContext *s){ short * tmp = s->pblocks[4]; s->pblocks[4] = s->pblocks[5]; s->pblocks[5] = tmp;}static int mpeg_field_start(MpegEncContext *s){ AVCodecContext *avctx= s->avctx; Mpeg1Context *s1 = (Mpeg1Context*)s; /* start frame decoding */ if(s->first_field || s->picture_structure==PICT_FRAME){ if(MPV_frame_start(s, avctx) < 0) return -1; ff_er_frame_start(s); /* first check if we must repeat the frame */ s->current_picture_ptr->repeat_pict = 0; if (s->repeat_first_field) { if (s->progressive_sequence) { if (s->top_field_first) s->current_picture_ptr->repeat_pict = 4; else s->current_picture_ptr->repeat_pict = 2; } else if (s->progressive_frame) { s->current_picture_ptr->repeat_pict = 1; } } *s->current_picture_ptr->pan_scan= s1->pan_scan; }else{ //second field int i; if(!s->current_picture_ptr){ av_log(s->avctx, AV_LOG_ERROR, "first field missing\n"); return -1; } for(i=0; i<4; i++){ s->current_picture.data[i] = s->current_picture_ptr->data[i]; if(s->picture_structure == PICT_BOTTOM_FIELD){ s->current_picture.data[i] += s->current_picture_ptr->linesize[i]; } } }#ifdef HAVE_XVMC// MPV_frame_start will call this function too,// but we need to call it on every field if(s->avctx->xvmc_acceleration) XVMC_field_start(s,avctx);#endif return 0;}#define DECODE_SLICE_ERROR -1#define DECODE_SLICE_OK 0/** * decodes a slice. MpegEncContext.mb_y must be set to the MB row from the startcode * @return DECODE_SLICE_ERROR if the slice is damaged<br> * DECODE_SLICE_OK if this slice is ok<br> */static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, const uint8_t **buf, int buf_size){ MpegEncContext *s = &s1->mpeg_enc_ctx; AVCodecContext *avctx= s->avctx; const int field_pic= s->picture_structure != PICT_FRAME; const int lowres= s->avctx->lowres; s->resync_mb_x= s->resync_mb_y= -1; if (mb_y<<field_pic >= s->mb_height){ av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height); return -1; } init_get_bits(&s->gb, *buf, buf_size*8); ff_mpeg1_clean_buffers(s); s->interlaced_dct = 0; s->qscale = get_qscale(s); if(s->qscale == 0){ av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); return -1; } /* 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){ av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n"); return -1; } if (code >= 33) { if (code == 33) { s->mb_x += 33; } /* otherwise, stuffing, nothing to do */ } else { s->mb_x += code; break; } } if(s->mb_x >= (unsigned)s->mb_width){ av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n"); return -1; } s->resync_mb_x= s->mb_x; s->resync_mb_y= s->mb_y= mb_y; s->mb_skip_run= 0; ff_init_block_index(s); if (s->mb_y==0 && s->mb_x==0 && (s->first_field || s->picture_structure==PICT_FRAME)) { if(s->avctx->debug&FF_DEBUG_PICT_INFO){ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1], s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors, s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :""); } } for(;;) {#ifdef HAVE_XVMC //one 1 we memcpy blocks in xvmcvideo if(s->avctx->xvmc_acceleration > 1) XVMC_init_block(s);//set s->block#endif if(mpeg_decode_mb(s, s->block) < 0) return -1; if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride; int xy = s->mb_x*2 + s->mb_y*2*wrap; int motion_x, motion_y, dir, i; if(field_pic && !s->first_field) xy += wrap/2; for(i=0; i<2; i++){ for(dir=0; dir<2; dir++){ if (s->mb_intra || (dir==1 && s->pict_type != B_TYPE)) { motion_x = motion_y = 0; }else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)){ motion_x = s->mv[dir][0][0]; motion_y = s->mv[dir][0][1]; } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ { motion_x = s->mv[dir][i][0]; motion_y = s->mv[dir][i][1]; } s->current_picture.motion_val[dir][xy ][0] = motion_x; s->current_picture.motion_val[dir][xy ][1] = motion_y; s->current_picture.motion_val[dir][xy + 1][0] = motion_x; s->current_picture.motion_val[dir][xy + 1][1] = motion_y; s->current_picture.ref_index [dir][xy ]= s->current_picture.ref_index [dir][xy + 1]= s->field_select[dir][i]; assert(s->field_select[dir][i]==0 || s->field_select[dir][i]==1); } xy += wrap; } } s->dest[0] += 16 >> lowres; s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift; s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift; MPV_decode_mb(s, s->block); if (++s->mb_x >= s->mb_width) { const int mb_size= 16>>s->avctx->lowres; ff_draw_horiz_band(s, mb_size*s->mb_y, mb_size); s->mb_x = 0; s->mb_y++; if(s->mb_y<<field_pic >= s->mb_height){ int left= s->gb.size_in_bits - get_bits_count(&s->gb); int is_d10= s->chroma_format==2 && s->pict_type==I_TYPE && avctx->profile==0 && avctx->level==5 && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0 && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/; if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) || (avctx->error_resilience >= FF_ER_AGGRESSIVE && left>8)){ av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); return -1; }else goto eos; } ff_init_block_index(s); } /* skip mb handling */ if (s->mb_skip_run == -1) { /* read again increment */ s->mb_skip_run = 0; for(;;) { int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2); if (code < 0){ av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n"); return -1; } if (code >= 33) { if (code == 33) { s->mb_skip_run += 33; }else if(code == 35){ if(s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0){ av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n"); return -1; } goto eos; /* end of slice */ } /* otherwise, stuffing, nothing to do */ } else { s->mb_skip_run += code; break; } } if(s->mb_skip_run){ int i; if(s->pict_type == I_TYPE){ av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); return -1; } /* skip mb */ s->mb_intra = 0; for(i=0;i<12;i++) s->block_last_index[i] = -1; if(s->picture_structure == PICT_FRAME) s->mv_type = MV_TYPE_16X16; else s->mv_type = MV_TYPE_FIELD; if (s->pict_type == P_TYPE) { /* if P type, zero motion vector is implied */ s->mv_dir = MV_DIR_FORWARD; s->mv[0][0][0] = s->mv[0][0][1] = 0; s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; s->field_select[0][0]= s->picture_structure - 1; } else { /* if B type, reuse previous vectors and directions */ s->mv[0][0][0] = s->last_mv[0][0][0]; s->mv[0][0][1] = s->last_mv[0][0][1]; s->mv[1][0][0] = s->last_mv[1][0][0]; s->mv[1][0][1] = s->last_mv[1][0][1]; } } } }eos: // end of slice *buf += get_bits_count(&s->gb)/8 - 1;//printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); return 0;}static int slice_decode_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= arg; const uint8_t *buf= s->gb.buffer; int mb_y= s->start_mb_y; s->error_count= 3*(s->end_mb_y - s->start_mb_y)*s->mb_width; for(;;){ uint32_t start_code; int ret; ret= mpeg_decode_slice((Mpeg1Context*)s, mb_y, &buf, s->gb.buffer_end - buf); emms_c();//av_log(c, AV_LOG_DEBUG, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -