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

📄 video_stream.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if(picture_header() == -1) {	  next_start_code();	  continue;  // Error, we need our picture header.	}	DINDENT(1);	if(picture_coding_extension() == -1) {	  next_start_code();	  continue;  // Error, we need the coding extension data (or ?) 	}		extension_and_user_data(2);		picture_data();	DINDENT(-1);      } while((nextbits(32) == MPEG2_VS_PICTURE_START_CODE) ||	      (nextbits(32) == MPEG2_VS_GROUP_START_CODE));      DINDENT(-1);      if(nextbits(32) != MPEG2_VS_SEQUENCE_END_CODE) {	if(nextbits(32) != MPEG2_VS_SEQUENCE_HEADER_CODE) {	  DPRINTF(0, "*** not a sequence header or end code\n");	  break;	}		sequence_header();	sequence_extension();      }    } while(nextbits(32) != MPEG2_VS_SEQUENCE_END_CODE);    DINDENT(-1);  } else {    /* ERROR: This is an ISO/IEC 11172-2 Stream */        /* No extension code following the sequence header implies MPEG-1 */    MPEG2 = 0;        // init values for MPEG-1    pic.coding_ext.picture_structure = PIC_STRUCT_FRAME_PICTURE;    pic.coding_ext.frame_pred_frame_dct = 1;    pic.coding_ext.intra_vlc_format = 0;    pic.coding_ext.concealment_motion_vectors = 0;    //mb.modes.frame_motion_type = 0x2; // This implies the ones below..    mb.prediction_type = PRED_TYPE_FRAME_BASED;    mb.motion_vector_count = 1;    mb.mv_format = MV_FORMAT_FRAME;    mb.dmv = 0;    seq.ext.chroma_format = 0x1;    /* Display init */    if(!shm_ready) {      cur_data_q = new_data_q(&data_q_head, 			      seq.mb_width * 16, seq.mb_height * 16,			      nr_of_buffers);      shm_ready = 1;    }    next_start_code();    extension_and_user_data(1);    do {      if(nextbits(32) == MPEG2_VS_GROUP_START_CODE) {	group_of_pictures_header();	extension_and_user_data(1);      }      if(picture_header() == -1) {	next_start_code();	continue;  // Error, we need out picture header      }      extension_and_user_data(1);      picture_data();    } while(nextbits(32) == MPEG2_VS_PICTURE_START_CODE ||	    (nextbits(32) == MPEG2_VS_GROUP_START_CODE));  }  DINDENT(-1);      /* If we are exiting there should be a sequence end code following. */  if(nextbits(32) == MPEG2_VS_SEQUENCE_END_CODE) {    GETBITS(32, "Sequence End Code");    DPRINTF(1, "Found Sequence End\n");  } else {    DPRINTF(0, "*** Didn't find Sequence End\n");  }}  /* 6.2.2.1 Sequence header */void sequence_header(void){  uint32_t sequence_header_code;  long int frame_interval_pts = 0;  DPRINTFI(1, "sequence_header()\n");  DINDENT(2);  sequence_header_code = GETBITS(32, "sequence header code");  if(sequence_header_code != MPEG2_VS_SEQUENCE_HEADER_CODE) {    WARNING("wrong start_code sequence_header_code: %08x\n", 	    sequence_header_code);  }    seq.header.horizontal_size_value = GETBITS(12, "horizontal_size_value");  seq.header.vertical_size_value = GETBITS(12, "vertical_size_value");  seq.header.aspect_ratio_information = GETBITS(4, "aspect_ratio_information");  seq.header.frame_rate_code = GETBITS(4, "frame_rate_code");  seq.header.bit_rate_value = GETBITS(18, "bit_rate_value");    marker_bit();  seq.header.vbv_buffer_size_value = GETBITS(10, "vbv_buffer_size_value");  seq.header.constrained_parameters_flag     = GETBITS(1, "constrained_parameters_flag");      /* When a sequence header is decoded all matrices shall either      be reset to their default values or downloaded from the bit stream. */  if(GETBITS(1, "load_intra_quantiser_matrix")) {    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]");    }      } else {    if(intra_inverse_quantiser_matrix_changed) {      reset_to_default_intra_quantiser_matrix();      intra_inverse_quantiser_matrix_changed = 0;    }  }    if(GETBITS(1, "load_non_intra_quantiser_matrix")) {    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]");    }      } else {    if(non_intra_inverse_quantiser_matrix_changed) {      reset_to_default_non_intra_quantiser_matrix();      non_intra_inverse_quantiser_matrix_changed = 0;    }  }  DPRINTFI(2, "horizontal_size_value: %u\n", seq.header.horizontal_size_value);  DPRINTFI(2, "vertical_size_value: %u\n", seq.header.vertical_size_value);  DPRINTFI(2, "aspect_ratio_information:(0x%01x) ",  seq.header.aspect_ratio_information);#ifdef DEBUG  switch(seq.header.aspect_ratio_information) {  case 0x0:    DPRINTF(2, "forbidden\n");    break;  case 0x1:    DPRINTF(2, "SAR = 1.0\n");    break;  case 0x2:    DPRINTF(2, "DAR = 3/4\n");    break;  case 0x3:    DPRINTF(2, "DAR = 9/16\n");    break;  case 0x4:    DPRINTF(2, "DAR = 1/2.21\n");    break;  default:    DPRINTF(2, "reserved\n");    break;  }#endif  DPRINTFI(2, "frame_rate_code:(0x%01x) ", seq.header.frame_rate_code);  switch(seq.header.frame_rate_code) {  case 0x0:    DPRINTF(2, "forbidden\n");    break;  case 0x1:    DPRINTF(2, "24000/1001 (23.976)\n");    frame_interval_pts = 3754;    break;  case 0x2:    DPRINTF(2, "24\n");    frame_interval_pts = 3750;    break;  case 0x3:    DPRINTF(2, "25\n");    frame_interval_pts = 3600;    break;  case 0x4:    DPRINTF(2, "30000/1001 (29.97)\n");    /* TODO hack for 24fps progressive */    if(last_gop_had_repeat_field_progressive_frame) {      /* it's probably coded as 24 fps progressive */      frame_interval_pts = 3754;    } else {      frame_interval_pts = 3003;    }    break;  case 0x5:    DPRINTF(2, "30\n");    frame_interval_pts = 3000;    break;  case 0x6:    DPRINTF(2, "50\n");    frame_interval_pts = 1800;    break;  case 0x7:    DPRINTF(2, "60000/1001 (59.94)\n");    frame_interval_pts = 1502;    break;  case 0x8:    DPRINTF(2, "60\n");    frame_interval_pts = 1500;    break;  default:    DPRINTF(2, "Reserved\n");    WARNING("%s", "reserved framerate found in sequence header\n");    break;  }      if(forced_frame_rate == -1) { /* No forced frame rate */    //buf_ctrl_head->frame_interval = frame_interval_pts;    frame_interval = frame_interval_pts;  } else {    if(forced_frame_rate == 0) {      //buf_ctrl_head->frame_interval = 1;      frame_interval = 1;    } else {      //buf_ctrl_head->frame_interval = PTS_BASE/forced_frame_rate;      frame_interval = PTS_BASE/forced_frame_rate;    }  }  DPRINTFI(2, "bit_rate_value: (0x%03x) %d bits/second\n",	  seq.header.bit_rate_value,	  seq.header.bit_rate_value*400);  DPRINTFI(2, "vbv_buffer_size_value: (0x%02x) min %d bits\n",	  seq.header.vbv_buffer_size_value,	  16*1024*seq.header.vbv_buffer_size_value);  DPRINTFI(2, "constrained_parameters_flag: %01x\n",	  seq.header.constrained_parameters_flag);     seq.horizontal_size = seq.header.horizontal_size_value;  seq.vertical_size = seq.header.vertical_size_value;    seq.mb_width  = (seq.horizontal_size+15)/16;  seq.mb_height = (seq.vertical_size+15)/16;  DINDENT(-2);}#define INC_8b_ALIGNMENT(a) ((a+7)/8*8)int detach_data_q(int q_shmid, data_q_t **data_q_list){  MsgEvent_t ev;  data_q_t **data_q_p;  data_q_t *data_q_tmp;  q_head_t *q_head;  data_buf_head_t *data_head;  int data_shmid;    //  fprintf(stderr, "DEBUG[vs]: detach_data_q q_shmid: %d\n", q_shmid);    for(data_q_p=data_q_list;      *data_q_p != NULL && (*data_q_p)->q_head->qid != q_shmid;      data_q_p = &(*data_q_p)->next) {  }  if(*data_q_p == NULL) {    ERROR("%s", "detach_data_q q_shmid not found\n");    return -1;  }  q_head = (*data_q_p)->q_head;  data_head = (*data_q_p)->data_head;  data_shmid = (*data_q_p)->data_head->shmid;    if(shmdt((char *)data_head) == -1) {    perror("ERROR[vs]: detach_data_q data_head");  }    if(shmdt((char *)q_head) == -1) {    perror("ERROR[vs]: detach_data_q q_head");  }  //TODO ugly hack  free((*data_q_p)->image_bufs);  data_q_tmp = *data_q_p;  *data_q_p = (*data_q_p)->next;  free(data_q_tmp);  ev.type = MsgEventQDestroyQ;  ev.detachq.q_shmid = q_shmid;  if(MsgSendEvent(msgq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) {    ERROR("%s", "couldn't send destroyq\n");  }    ev.type = MsgEventQDestroyBuf;  ev.destroybuf.shmid = data_shmid;  if(MsgSendEvent(msgq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) {    ERROR("%s", "couldn't send destroybuf\n");  }  return 0;}data_q_t *new_data_q(data_q_t **data_q_list,		     int padded_width, int padded_height,		     int nr_of_bufs){  data_q_t **data_q_p;  for(data_q_p = data_q_list; *data_q_p != NULL; data_q_p =&(*data_q_p)->next);      *data_q_p = malloc(sizeof(data_q_t));    if(get_output_buffer(*data_q_p,		       padded_width, padded_height,		       nr_of_bufs) == -1) {    free(*data_q_p);    *data_q_p = NULL;  }    return *data_q_p;}int get_output_buffer(data_q_t *data_q,		      int padded_width, int padded_height,		      int nr_of_bufs){  int picture_size;  int picture_bufs_size;  int picture_ctrl_size;  int buf_size;  MsgEvent_t ev;  int num_pels = padded_width * padded_height;  int pagesize = sysconf(_SC_PAGESIZE);  int y_size   = INC_8b_ALIGNMENT(num_pels);  int uv_size  = INC_8b_ALIGNMENT(num_pels/4);  int yuv_size = y_size + 2 * uv_size;   int data_shmid;  int q_shmid;  int picture_data_offset;  int n;  char *data_shmaddr;  char *q_shmaddr;  q_head_t *q_head = NULL;  q_elem_t *q_elems = NULL;  data_buf_head_t *data_head = NULL;  picture_data_elem_t *data_elems = NULL;  yuv_image_t *image_bufs = NULL;  DNOTE("%s", "get ouput buffer\n");  picture_size = ((yuv_size + (pagesize-1))/pagesize*pagesize);    /* Mlib reads ?8? bytes beyond the last pel (in the v-picture),      if that pel just before a page boundary then *boom*!! */    // TODO this is an ugly hack for not mixing in ref.frames#ifdef HAVE_XV  picture_bufs_size = (nr_of_bufs+1) * picture_size + pagesize;//Hack  picture_ctrl_size = sizeof(data_buf_head_t) +    sizeof(picture_data_elem_t)*(nr_of_bufs+1);#else  picture_bufs_size = nr_of_bufs * picture_size + pagesize;//Hack  picture_ctrl_size = sizeof(data_buf_head_t) +    sizeof(picture_data_elem_t)*nr_of_bufs;#endif  picture_ctrl_size = INC_8b_ALIGNMENT(picture_ctrl_size);  buf_size = picture_ctrl_size + picture_bufs_size;    // Get shared memory buffer      ev.type = MsgEventQReqBuf;  ev.reqbuf.size = buf_size;    if(MsgSendEvent(msgq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) {    ERROR("%s", "couldn't send buffer request\n");  }    while(1) {    if(MsgNextEvent(msgq, &ev) != -1) {      if(ev.type == MsgEventQGntBuf) {	DPRINTF(1, "video_decoder: got buffer id %d, size %d\n",		ev.gntbuf.shmid,		ev.gntbuf.size);	data_shmid = ev.gntbuf.shmid;	break;      } else {	handle_events(msgq, &ev);      }    }  }  if(data_shmid >= 0) {    if((data_shmaddr = shmat(data_shmid, NULL, SHM_SHARE_MMU)) == (void *)-1) {      perror("**video_decode: attach_buffer(), shmat()");      return -1;    }    data_head = (data_buf_head_t *)data_shmaddr;    data_head->shmid = data_shmid;    data_head->info.type = DataBufferType_Video;    data_head->info.video.format = 0;    data_head->info.video.width = padded_width;    data_head->info.video.height = padded_height;    data_head->info.video.stride = padded_width;    data_head->nr_of_dataelems = nr_of_bufs;    data_head->write_nr = 0;            image_bufs = malloc(nr_of_bufs*sizeof(yuv_image_t));        data_elems =(picture_data_elem_t *)(data_shmaddr + 					sizeof(data_buf_head_t));    picture_data_offset = picture_ctrl_size;  // TODO this is an ugly hack for not mixing in ref.frames#ifdef HAVE_XV    for(n = 0; n < (data_head->nr_of_dataelems+1); n++) {#else    for(n = 0; n < data_head->nr_of_dataelems; n++) {#endif      data_elems[n].displayed = 1;      data_elems[n].is_reference = 0;      data_elems[n].picture.y_offset = picture_data_offset;      image_bufs[n].y = data_shmaddr + picture_data_offset;      data_elems[n].picture.v_offset = picture_data_offset + y_size;      image_bufs[n].v = data_shmaddr + picture_data_offset + y_size;      data_elems[n].picture.u_offset = picture_data_offset + y_size + uv_size;      image_bufs[n].u = data_shmaddr + picture_data_offset+y_size+uv_size;      data_elems[n].picture.horizontal_size = seq.horizontal_size;      data_elems[n].picture.vertical_size = seq.vertical_size;      data_elems[n].picture.start_x = 0;      data_elems[n].picture.start_y = 0;      data_elems[n].picture.padded_width = padded_width;      data_elems[n].picture.padded_height = padded_height;            picture_data_offset += picture_size;          }    fwd_ref_image = &image_bufs[0];    bwd_ref_image = &image_bufs[1];        /* send create decoder request msg*/    ev.type = MsgEventQReqPicBuf;        ev.reqpicbuf.nr_of_elems = nr_of_bufs;    ev.reqpicbuf.data_buf_shmid = data_shmid;          if(MsgSendEvent(msgq, CLIENT_RESOURCE_MANAGER, &ev, 0) == -1) {      ERROR("%s", "couldn't send picbuf request\n");    }        /* wait for answer */        while(1) {      if(MsgNextEvent(msgq, &ev) != -1) {	if(ev.type == MsgEventQGntPicBuf) {

⌨️ 快捷键说明

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