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

📄 video_stream.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	    calc_pts = last_pts_to_dpy +	      (pic.header.temporal_reference - last_temporal_ref_to_dpy) *	      frame_interval;	    	  }   	}		pinfos[buf_id].PTS = calc_pts;	pinfos[buf_id].scr_nr = last_scr_nr;	/*	fprintf(stderr, "last_timestamped: %d\n",		last_timestamped_temp_ref);	fprintf(stderr, "last_pts: %lld\n",		last_pts);	fprintf(stderr, "last_pts_to_dpy: %lld\n",		last_pts_to_dpy);		fprintf(stderr, "pts_time %ld.%09ld\n",		TIME_S (pinfos[buf_id].pts_time),		TIME_SS(pinfos[buf_id].pts_time));		fprintf(stderr, "realtime_offset %ld.%09ld\n",		TIME_S (ctrl_time[last_scr_nr].realtime_offset),		TIME_SS(ctrl_time[last_scr_nr].realtime_offset));	*/		break;      case PIC_CODING_TYPE_B:	/* In case we don't have a previous displayed picture	 * we don't now what we should set this timestamp to	 * unless we look at the temporal reference.	 * To be able to use the temporal reference we need	 * to have a pts in the same temporal reference 'sequence'.	 * (the temporal reference sequence is reset to 0 for every	 * GOP	 */		/* In case we don't use temporal reference	 * we don't know what the pts should be, but we calculate it	 * anyway and hope we end up with a time that is earlier	 * than the next 'real' time stamp.	 */		/* We use temporal reference and calculate the timestamp	 * from the last decoded picture which had a timestamp	 */	/* TODO: Check if there is a valid 'last_pts_to_dpy' to predict from.*/	calc_pts = last_pts +	  (pic.header.temporal_reference - last_timestamped_temp_ref) *	  frame_interval;	/*	  calc_pts = last_pts_to_dpy + 	  buf_ctrl_head->frame_interval;	*/	pinfos[buf_id].PTS = calc_pts;	pinfos[buf_id].scr_nr = last_scr_nr;		break;      }    }        /* When it is a B-picture we are decoding we know that it is     * the picture that is going to be displayed next.     * We check to see if we are lagging behind the desired time     * and in that case we don't decode/show this picture     */    /* Calculate the time remaining until this picture shall be viewed. */    if(pic.header.picture_coding_type == PIC_CODING_TYPE_B) {      clocktime_t realtime, calc_rt, err_time, pts_time;      PTS_TO_CLOCKTIME(pts_time, pinfos[buf_id].PTS);      clocktime_get(&realtime);      if(ctrl_time[last_scr_nr].offset_valid == OFFSET_VALID) {	calc_realtime_left_to_scrtime(&err_time, &realtime, &pts_time,				      &ctrl_time[last_scr_nr].sync_point);      } else {	calc_rt = realtime;	timesub(&err_time, &calc_rt, &realtime);	DNOTE("%s", "time offset not valid yet\n");      }            /* If the picture should already have been displayed then drop it. */      /* TODO: More investigation needed. */      if((TIME_SS(err_time) < 0 || TIME_S(err_time) < 0) 	 && forced_frame_rate) {	fprintf(stderr, "!");		/*	  fprintf(stderr, "errpts %ld.%+010ld\n\n",	  TIME_S(err_time), TIME_SSerr_time));	*/		/* mark the frame to be dropped */	drop_frame = 1;      }    }  }/* else {      // either this is the second field of the frame or it is an error      fprintf(stderr, "*** error prev_temp_ref == cur_temp_ref\n");            }   */  { // Don't use floating point math!    int sar_frac_n = 1;    int sar_frac_d = 1;    //double sar = 1.0;    uint16_t hsize, vsize;          //wrong on some dvd's ?    if(seq.dpy_ext.display_horizontal_size) {       hsize = seq.dpy_ext.display_horizontal_size;      vsize = seq.dpy_ext.display_vertical_size;      /*      fprintf(stderr, "*****bepa %d, %d\n",	      hsize, vsize);      */    } else {      hsize = seq.horizontal_size;      vsize = seq.vertical_size;    }    switch(seq.header.aspect_ratio_information) {    case 0x0:      DPRINTF(2, "forbidden\n");      break;    case 0x1:      DPRINTF(2, "SAR = 1.0\n");      sar_frac_n = 1;      sar_frac_d = 1;      //sar = 1.0;      break;    case 0x2:      DPRINTF(2, "DAR = 3/4\n");      sar_frac_n = 3 * hsize;      sar_frac_d = 4 * vsize;      //sar = 3.0/4.0*(double)hsize/(double)vsize;      break;    case 0x3:      DPRINTF(2, "DAR = 9/16\n");      if(seq.dpy_ext.display_horizontal_size) { 	if(seq.dpy_ext.display_horizontal_size != seq.horizontal_size) {	  // DVD with wrong mpeg display_extension	  hsize = seq.horizontal_size;	  vsize = seq.vertical_size;	}      }      sar_frac_n = 9 * hsize;      sar_frac_d = 16 * vsize;      //sar = 9.0/16.0*(double)hsize/(double)vsize;      break;    case 0x4:      DPRINTF(2, "DAR = 1/2.21\n");      sar_frac_n = 100 * hsize;      sar_frac_d = 221 * vsize;      //sar = 1.0/2.21*(double)hsize/(double)vsize;      break;    default:      DPRINTF(2, "reserved\n");      break;    }    pinfos[buf_id].picture.sar_frac_n = sar_frac_n;    pinfos[buf_id].picture.sar_frac_d = sar_frac_d;    //TODO add frame_center__offset compensation and    // handle bigger display__size than _size    if(seq.dpy_ext.display_horizontal_size > 0 &&       seq.dpy_ext.display_horizontal_size <= seq.horizontal_size) {            pinfos[buf_id].picture.display_start_x = 	(seq.horizontal_size - seq.dpy_ext.display_horizontal_size) / 2;      pinfos[buf_id].picture.display_width =	seq.dpy_ext.display_horizontal_size;     } else {      pinfos[buf_id].picture.display_start_x = 0;      pinfos[buf_id].picture.display_width = 0;     }    if(seq.dpy_ext.display_vertical_size > 0 &&       seq.dpy_ext.display_vertical_size <= seq.vertical_size) {            pinfos[buf_id].picture.display_start_y = 	(seq.vertical_size - seq.dpy_ext.display_vertical_size) / 2;      pinfos[buf_id].picture.display_height =	seq.dpy_ext.display_vertical_size;     } else {      pinfos[buf_id].picture.display_start_y = 0;      pinfos[buf_id].picture.display_height = 0;     }  }    if(flush_to_scrid != -1) {    //    fprintf(stderr, "vs: flush picture\n");  }  /* now we can decode the picture if it shouldn't be dropped */  if(!drop_frame && (flush_to_scrid == -1)) {    /* Decode the slices. */    if( MPEG2 ) {      do {	int slice_nr;	slice_nr = nextbits(32) & 0xff;	mpeg2_slice();	if(slice_nr >= seq.mb_height) {	  break;	}	next_start_code();            } while((nextbits(32) >= MPEG2_VS_SLICE_START_CODE_LOWEST) &&	      (nextbits(32) <= MPEG2_VS_SLICE_START_CODE_HIGHEST));    } else {      do {	err = mpeg1_slice();	if(err == -1) {	  drop_to_next_picture();	  break;	}      } while((nextbits(32) >= MPEG2_VS_SLICE_START_CODE_LOWEST) &&	      (nextbits(32) <= MPEG2_VS_SLICE_START_CODE_HIGHEST));    }  } else {    do {      //TODO change to fast startcode finder      GETBITS(8, "drop");      next_start_code();    } while((nextbits(32) >= MPEG2_VS_SLICE_START_CODE_LOWEST) &&	    (nextbits(32) <= MPEG2_VS_SLICE_START_CODE_HIGHEST));  }  // Check 'err' here?  /*  fprintf(stderr, "coding_type: %d, temp_ref: %d\n",	  pic.header.picture_coding_type,	  pic.header.temporal_reference);  */  // Picture decoded  if((prev_coded_temp_ref == pic.header.temporal_reference) ||     (pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE)) {        if(pic.header.picture_coding_type == PIC_CODING_TYPE_B) {      if(pic.header.temporal_reference == (last_temporal_ref_to_dpy+1)%1024) {		last_temporal_ref_to_dpy = pic.header.temporal_reference;	last_pts_to_dpy = pinfos[buf_id].PTS;	last_scr_nr_to_dpy = pinfos[buf_id].scr_nr;//?		if(drop_frame || (flush_to_scrid != -1)) {	  drop_frame = 0;	  pinfos[buf_id].is_reference = 0; //this is never set in a B picture?	  pinfos[buf_id].displayed = 1;	  	} else {	  	  dpy_q_put(buf_id, cur_data_q);	  	}		if(bwd_ref_buf_id == -1) {	  WARNING("%s", " **B-frame before any reference frame!!!\n");	}		if(fwd_ref_buf_id == -1) { // Test closed_gop too....	  WARNING("%s", "B-frame before forward ref frame\n");	}	      } else {	/* TODO: what should happen if the temporal reference is wrong */	WARNING("%s", "** temporal reference for B-picture incorrect\n");		temporal_reference_error =	  pic.header.temporal_reference - (last_temporal_ref_to_dpy + 1)%1024;		last_temporal_ref_to_dpy = pic.header.temporal_reference;	//last_temporal_ref_to_dpy++;	last_pts_to_dpy = pinfos[buf_id].PTS;	last_scr_nr_to_dpy = pinfos[buf_id].scr_nr;//?		dpy_q_put(buf_id, cur_data_q);      }    }    /*      if(temporal_reference_error) {        if((bwd_ref_temporal_reference != -1)) {          dpy_q_put(bwd_ref_buf_id);        }      }    */        if((bwd_ref_temporal_reference != -1) &&        (bwd_ref_temporal_reference == (last_temporal_ref_to_dpy+1)%1024)) {      last_temporal_ref_to_dpy = bwd_ref_temporal_reference;            /* bwd_ref should not be in the dpy_q more than one time */      bwd_ref_temporal_reference = -1;            /* put bwd_ref in dpy_q */      last_pts_to_dpy = pinfos[bwd_ref_buf_id].PTS;      last_scr_nr_to_dpy = pinfos[bwd_ref_buf_id].scr_nr;      if(flush_to_scrid != -1) {	pinfos[bwd_ref_buf_id].is_reference = 0;	pinfos[bwd_ref_buf_id].displayed = 1;      } else {		dpy_q_put(bwd_ref_buf_id, cur_data_q);      }    } else if(bwd_ref_temporal_reference < (last_temporal_ref_to_dpy+1)%1024) {            WARNING("%s", "** temporal reference in I or P picture incorrect\n");          }  }    prev_coded_temp_ref = pic.header.temporal_reference;    DINDENT(-2);  next_start_code();}/* 6.2.2.2.1 Extension data */void extension_data(const unsigned int i){  DPRINTFI(1, "extension_data(%d)", i);  DINDENT(2);    while(nextbits(32) == MPEG2_VS_EXTENSION_START_CODE) {    GETBITS(32, "extension_start_code");        if(i == 0) { /* follows sequence_extension() */            if(nextbits(4) == MPEG2_VS_SEQUENCE_DISPLAY_EXTENSION_ID) {	sequence_display_extension();      }      if(nextbits(4) == MPEG2_VS_SEQUENCE_SCALABLE_EXTENSION_ID) {	sequence_scalable_extension();      }    }    /* extension never follows a group_of_picture_header() */        if(i == 2) { /* follows picture_coding_extension() */      if(nextbits(4) == MPEG2_VS_QUANT_MATRIX_EXTENSION_ID) {	quant_matrix_extension();      }      if(nextbits(4) == MPEG2_VS_PICTURE_DISPLAY_EXTENSION_ID) {	/* the draft says picture_pan_scan_extension_id (must be wrong?) */	picture_display_extension();      }      if(nextbits(4) == MPEG2_VS_PICTURE_SPATIAL_SCALABLE_EXTENSION_ID) {	picture_spatial_scalable_extension();      }      if(nextbits(4) == MPEG2_VS_PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID) {	picture_temporal_scalable_extension();      }    }  }  DINDENT(-2);} void reset_to_default_quantiser_matrix(void){  memcpy(seq.header.intra_inverse_quantiser_matrix,	 default_intra_inverse_quantiser_matrix,	 sizeof(seq.header.intra_inverse_quantiser_matrix));  memcpy(seq.header.non_intra_inverse_quantiser_matrix,	 default_non_intra_inverse_quantiser_matrix,	 sizeof(seq.header.non_intra_inverse_quantiser_matrix));  }void reset_to_default_intra_quantiser_matrix(void){  memcpy(seq.header.intra_inverse_quantiser_matrix,	 default_intra_inverse_quantiser_matrix,	 sizeof(seq.header.intra_inverse_quantiser_matrix));}void reset_to_default_non_intra_quantiser_matrix(void){  memcpy(seq.header.non_intra_inverse_quantiser_matrix,	 default_non_intra_inverse_quantiser_matrix,	 sizeof(seq.header.non_intra_inverse_quantiser_matrix));}/* 6.2.3.2 Quant matrix extension */void quant_matrix_extension(void){  GETBITS(4, "extension_start_code_identifier");    DPRINTFI(1, "quant_matrix_extension()\n");  DINDENT(2);    if(GETBITS(1, "load_intra_quantiser_matrix")) {    unsigned int n;    intra_inverse_quantiser_matrix_changed = 1;    /* 7.3.1 Inverse scan for matrix download */    for(n = 0; n < 64; n++) {      seq.header.intra_inverse_quantiser_matrix[inverse_scan[0][n]] =	GETBITS(8, "intra_quantiser_matrix[n]");    }      }      if(GETBITS(1, "load_non_intra_quantiser_matrix")) {    unsigned int n;    non_intra_inverse_quantiser_matrix_changed = 1;        /*  7.3.1 Inverse scan for matrix download */    for(n = 0; n < 64; n++) {      seq.header.non_intra_inverse_quantiser_matrix[inverse_scan[0][n]] =	GETBITS(8, "non_intra_quantiser_matrix[n]");    }     }  GETBITS(1, "load_chroma_intra_quantiser_matrix (always 0 in 4:2:0)");  GETBITS(1, "load_chroma_non_intra_quantiser_matrix (always 0 in 4:2:0)");    DINDENT(-2);  next_start_code();}void picture_display_extension(void){  uint8_t extension_start_code_identifier;  uint16_t frame_centre_horizontal_offset;  uint16_t frame_centre_vertical_offset;  uint8_t number_of_frame_centre_offsets;  unsigned int i;  DPRINTFI(1, "picture_display_extension()\n");  DINDENT(2);    if((seq.ext.progressive_sequence == 1) ||      ((pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD) ||      (pic.coding_ext.picture_structure == PIC_STRUCT_BOTTOM_FIELD))) {    number_of_frame_centre_offsets = 1;  } else {    if(pic.coding_ext.repeat_first_field == 1) {      number_of_frame_centre_offsets = 3;    } else {      number_of_frame_centre_offsets = 2;    }  }    extension_start_code_identifier     = GETBITS(4,"extension_start_code_identifier");  for(i = 0; i < number_of_frame_centre_offsets; i++) {    frame_centre_horizontal_offset = GETBITS(16, "frame_centre_horizontal_offset");    marker_bit();    frame_centre_vertical_offset = GETBITS(16, "frame_centre_vertical_offset");    marker_bit();    DPRINTFI(2, "frame_centre_offset: %d, %d\n",	     frame_centre_horizontal_offset,	     frame_centre_vertical_offset);  }  DINDENT(-2);  next_start_code();}void picture_spatial_scalable_extension(void){  fprintf(stderr, "***ni picture_spatial_scalable_extension()\n");  exit(1);}void picture_temporal_

⌨️ 快捷键说明

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