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

📄 demux_mpg.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
      c=stream_read_char(demux->stream); //pes_extension2 payload === substream id      hdrlen--;      if(c<0x55 || c>0x5F)   { mp_msg(MSGT_DEMUX,MSGL_V,"demux_mpg: unknown vc1 substream_id: 0x%x  \n", c); return -1;}      pes_ext2_subid=c;    }    if(hdrlen>0)      stream_skip(demux->stream,hdrlen); // skip header and stuffing bytes    if(id==0x1FD && pes_ext2_subid!=-1) {      //==== EVO VC1 STREAMS ===//      if(!demux->v_streams[pes_ext2_subid]) new_sh_video(demux,pes_ext2_subid);      if(demux->video->id==-1) demux->video->id=pes_ext2_subid;      if(demux->video->id==pes_ext2_subid){        ds=demux->video;        if(!ds->sh) ds->sh=demux->v_streams[pes_ext2_subid];        if(priv && ds->sh) {          sh_video_t *sh = (sh_video_t *)ds->sh;          sh->format = mmioFOURCC('W', 'V', 'C', '1');        }      }    }    //============== DVD Audio sub-stream ======================    if(id==0x1BD){      int aid, rawa52 = 0;      off_t tmppos;      unsigned int tmp;      tmppos = stream_tell(demux->stream);      tmp = stream_read_word(demux->stream);      stream_seek(demux->stream, tmppos);      /// vdr stores A52 without the 4 header bytes, so we have to check this condition first      if(tmp == 0x0B77) {        aid = 128;        rawa52 = 1;      }      else {        aid=stream_read_char(demux->stream);--len;        if(len<3) return -1; // invalid audio packet      }      // AID:      // 0x20..0x3F  subtitle      // 0x80..0x87 and 0xC0..0xCF  AC3 audio      // 0x88..0x8F and 0x98..0x9F  DTS audio      // 0xA0..0xBF  PCM audio      if((aid & 0xE0) == 0x20){        // subtitle:        aid&=0x1F;        if(!demux->s_streams[aid]){            sh_sub_t *sh = new_sh_sub(demux, aid);            if (sh) sh->type = 'v';            mp_msg(MSGT_DEMUX,MSGL_V,"==> Found subtitle: %d\n",aid);        }        if(demux->sub->id > -1)          demux->sub->id &= 0x1F;        if(!dvdsub_lang && demux->sub->id == -1)          demux->sub->id = aid;        if(demux->sub->id==aid){            ds=demux->sub;        }      } else if((aid >= 0x80 && aid <= 0x8F) || (aid >= 0x98 && aid <= 0xAF) || (aid >= 0xC0 && aid <= 0xCF)) {//        aid=128+(aid&0x7F);        // aid=0x80..0xBF        new_audio_stream(demux, aid);      if(demux->audio->id==aid){        int type;        ds=demux->audio;        if(!ds->sh) ds->sh=demux->a_streams[aid];        // READ Packet: Skip additional audio header data:        if(!rawa52) {        c=stream_read_char(demux->stream);//num of frames        type=stream_read_char(demux->stream);//startpos hi        type=(type<<8)|stream_read_char(demux->stream);//startpos lo//        printf("\r[%02X][%04X]",c,type);        len-=3;        }        if((aid&0xE0)==0xA0 && len>=3){	  unsigned char* hdr;	  // save audio header as codecdata!	  if(!((sh_audio_t*)(ds->sh))->codecdata_len){	      ((sh_audio_t*)(ds->sh))->codecdata=malloc(3);	      ((sh_audio_t*)(ds->sh))->codecdatatype = 1;	      ((sh_audio_t*)(ds->sh))->codecdata_len=3;	  }	  hdr=((sh_audio_t*)(ds->sh))->codecdata;          // read LPCM header:	  // emphasis[1], mute[1], rvd[1], frame number[5]:          hdr[0]=stream_read_char(demux->stream);//          printf(" [%01X:%02d]",c>>5,c&31);	  // quantization[2],freq[2],rvd[1],channels[3]          hdr[1]=stream_read_char(demux->stream);//          printf("[%01X:%01X] ",c>>4,c&15);	  // dynamic range control (0x80=off):          hdr[2]=stream_read_char(demux->stream);//          printf("[%02X] ",c);          len-=3;          if(len<=0) mp_msg(MSGT_DEMUX,MSGL_V,"End of packet while searching for PCM header\n");        }//        printf("  \n");      } //  if(demux->audio->id==aid)      } else mp_msg(MSGT_DEMUX,MSGL_V,"Unknown 0x1BD substream: 0x%02X  \n",aid);    } //if(id==0x1BD)  } else {    if(c!=0x0f){      mp_msg(MSGT_DEMUX,MSGL_V,"  {ERROR5,c=%d}  \n",c);      return -1;  // invalid packet !!!!!!    }  }  if(mpeg_pts_error) mp_msg(MSGT_DEMUX,MSGL_V,"  {PTS_err:%d}  \n",mpeg_pts_error);  mp_dbg(MSGT_DEMUX,MSGL_DBG3," => len=%d\n",len);//  if(len<=0 || len>MAX_PS_PACKETSIZE) return -1;  // Invalid packet size  if(len<=0 || len>MAX_PS_PACKETSIZE){    mp_dbg(MSGT_DEMUX,MSGL_DBG2,"Invalid PS data len: %d\n",len);    return -1;  // invalid packet !!!!!!  }  if(id>=0x1C0 && id<=0x1DF){    // mpeg audio    int aid=id-0x1C0;    new_audio_stream(demux, aid);    if(demux->audio->id==aid){      ds=demux->audio;      if(!ds->sh) ds->sh=demux->a_streams[aid];      if(priv && ds->sh) {        sh_audio_t *sh = (sh_audio_t *)ds->sh;        if(priv->es_map[id - 0x1B0])          sh->format = priv->es_map[id - 0x1B0];          mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);      }    }  } else  if(id>=0x1E0 && id<=0x1EF){    // mpeg video    int aid=id-0x1E0;    if(!demux->v_streams[aid]) new_sh_video(demux,aid);    if(demux->video->id==-1) demux->video->id=aid;    if(demux->video->id==aid){      ds=demux->video;      if(!ds->sh) ds->sh=demux->v_streams[aid];      if(priv && ds->sh) {        sh_video_t *sh = (sh_video_t *)ds->sh;        if(priv->es_map[id - 0x1B0]) {          sh->format = priv->es_map[id - 0x1B0];          mp_dbg(MSGT_DEMUX,MSGL_DBG2,"ASSIGNED TO STREAM %d CODEC %x\n", id, priv->es_map[id - 0x1B0]);        }      }    }  }  if(ds){    mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Read %d data bytes from packet %04X\n",len,id);//    printf("packet start = 0x%X  \n",stream_tell(demux->stream)-packet_start_pos);    dp=new_demux_packet(len);    if(!dp) {      mp_dbg(MSGT_DEMUX,MSGL_ERR,"DEMUX_MPG ERROR: couldn't create demux_packet(%d bytes)\n",len);      stream_skip(demux->stream,len);      return 0;    }    l = stream_read(demux->stream,dp->buffer,len);    if(l<len)      resize_demux_packet(dp, l);    len = l;    dp->pts=pts/90000.0f;    dp->pos=demux->filepos;    /*      workaround:      set dp->stream_pts only when feeding the video stream, or strangely interleaved files      (such as SWIII) will show strange alternations in the stream time, wildly going      back and forth    */    if(ds == demux->video && stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME,(void *)&stream_pts)!=STREAM_UNSUPPORTED)      dp->stream_pts = stream_pts;    ds_add_packet(ds,dp);    if (demux->priv && set_pts) ((mpg_demuxer_t*)demux->priv)->last_pts = pts/90000.0f;//    if(ds==demux->sub) parse_dvdsub(ds->last->buffer,ds->last->len);    return 1;  }  mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_MPG: Skipping %d data bytes from packet %04X\n",len,id);  if(len<=2356) stream_skip(demux->stream,len);  return 0;}static int num_elementary_packets100=0;static int num_elementary_packets101=0;static int num_elementary_packets12x=0;static int num_elementary_packets1B6=0;static int num_elementary_packetsPES=0;static int num_h264_slice=0; //combined slicestatic int num_h264_dpa=0; //DPA Slicestatic int num_h264_dpb=0; //DPB Slicestatic int num_h264_dpc=0; //DPC Slicestatic int num_h264_idr=0; //IDR Slicestatic int num_h264_sps=0;static int num_h264_pps=0;static int num_mp3audio_packets=0;static void clear_stats(void){  num_elementary_packets100=0;  num_elementary_packets101=0;  num_elementary_packets1B6=0;  num_elementary_packets12x=0;  num_elementary_packetsPES=0;  num_h264_slice=0; //combined slice  num_h264_dpa=0; //DPA Slice  num_h264_dpb=0; //DPB Slice  num_h264_dpc=0; //DPC Slice  num_h264_idr=0; //IDR Slice  num_h264_sps=0;  num_h264_pps=0;  num_mp3audio_packets=0;}//assumes demuxer->synced < 2static inline void update_stats(int head){  if(head==0x1B6) ++num_elementary_packets1B6;  else if(head==0x100) ++num_elementary_packets100;  else if(head==0x101) ++num_elementary_packets101;  else if(head==0x1BD || (0x1C0<=head && head<=0x1EF))    num_elementary_packetsPES++;  else if(head>=0x120 && head<=0x12F) ++num_elementary_packets12x;  if(head>=0x100 && head<0x1B0)  {    if((head&~0x60) == 0x101) ++num_h264_slice;    else if((head&~0x60) == 0x102) ++num_h264_dpa;    else if((head&~0x60) == 0x103) ++num_h264_dpb;    else if((head&~0x60) == 0x104) ++num_h264_dpc;    else if((head&~0x60) == 0x105 && head != 0x105) ++num_h264_idr;    else if((head&~0x60) == 0x107 && head != 0x107) ++num_h264_sps;    else if((head&~0x60) == 0x108 && head != 0x108) ++num_h264_pps;  }}static int demux_mpg_probe(demuxer_t *demuxer) {  int pes=1;  int tmp;  off_t tmppos;  int file_format = DEMUXER_TYPE_UNKNOWN;  tmppos=stream_tell(demuxer->stream);  tmp=stream_read_dword(demuxer->stream);  if(tmp==0x1E0 || tmp==0x1C0) {    tmp=stream_read_word(demuxer->stream);    if(tmp>1 && tmp<=2048) pes=0; // demuxer->synced=3; // PES...  }  stream_seek(demuxer->stream,tmppos);  clear_stats();  if(demux_mpg_open(demuxer))    file_format=DEMUXER_TYPE_MPEG_PS;  else {    mp_msg(MSGT_DEMUX,MSGL_V,"MPEG packet stats: p100: %d  p101: %d p1B6: %d p12x: %d sli: %d a: %d b: %d c: %d idr: %d sps: %d pps: %d PES: %d  MP3: %d, synced: %d\n",     num_elementary_packets100,num_elementary_packets101,     num_elementary_packets1B6,num_elementary_packets12x,     num_h264_slice, num_h264_dpa,     num_h264_dpb, num_h264_dpc=0,     num_h264_idr, num_h264_sps=0,     num_h264_pps,     num_elementary_packetsPES,num_mp3audio_packets, demuxer->synced);     //MPEG packet stats: p100: 458  p101: 458  PES: 0  MP3: 1103  (.m2v)     if(num_mp3audio_packets>50 && num_mp3audio_packets>2*num_elementary_packets100        && abs(num_elementary_packets100-num_elementary_packets101)>2)       return file_format;      // some hack to get meaningfull error messages to our unhappy users:      if(num_elementary_packets100>=2 && num_elementary_packets101>=2 &&         abs(num_elementary_packets101+8-num_elementary_packets100)<16) {         if(num_elementary_packetsPES>=4 && num_elementary_packetsPES>=num_elementary_packets100-4) {           return file_format;         }         file_format=DEMUXER_TYPE_MPEG_ES; //  <-- hack is here :)      } else          // fuzzy mpeg4-es detection. do NOT enable without heavy testing of mpeg formats detection!        if(num_elementary_packets1B6>3 && num_elementary_packets12x>=1 &&           num_elementary_packetsPES==0 && num_elementary_packets100<=num_elementary_packets12x &&           demuxer->synced<2) {             file_format=DEMUXER_TYPE_MPEG4_ES;        } else         // fuzzy h264-es detection. do NOT enable without heavy testing of mpeg formats detection!        if((num_h264_slice>3 || (num_h264_dpa>3 && num_h264_dpb>3 && num_h264_dpc>3)) &&           /* FIXME num_h264_sps>=1 && */ num_h264_pps>=1 && num_h264_idr>=1 &&          num_elementary_packets1B6==0 && num_elementary_packetsPES==0 &&          demuxer->synced<2) {            file_format=DEMUXER_TYPE_H264_ES;        } else        {          if(demuxer->synced==2)            mp_msg(MSGT_DEMUXER,MSGL_ERR,"MPEG: " MSGTR_MissingVideoStreamBug);          else            mp_msg(MSGT_DEMUXER,MSGL_V,MSGTR_NotSystemStream);        }  }  //FIXME this shouldn't be necessary  stream_seek(demuxer->stream,tmppos);  return file_format;}static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){  // Elementary video stream  if(demux->stream->eof) return 0;  demux->filepos=stream_tell(demux->stream);  ds_read_packet(demux->video,demux->stream,STREAM_BUFFER_SIZE,0,demux->filepos,0);  return 1;}/** * \brief discard until 0x100 header and return a filled buffer * \param b buffer-end pointer * \param pos current pos in stream, negative since b points to end of buffer * \param s stream to read from * \return new position, differs from original pos when eof hit and thus *             b was modified to point to the new end of buffer */static int find_end(unsigned char **b, int pos, stream_t *s) {  register int state = 0xffffffff;  unsigned char *buf = *b;  int start = pos;  int read, unused;  // search already read part  while (state != 0x100 && pos) {    state = state << 8 | buf[pos++];  }  // continue search in stream  while (state != 0x100) {    register int c = stream_read_char(s);    if (c < 0) break;    state = state << 8 | c;  }  // modify previous header (from 0x1bc or 0x1bf to 0x100)  buf[start++] = 0;  // copy remaining buffer part to current pos  memmove(&buf[start], &buf[pos], -pos);  unused = start + -pos; // -unused bytes in buffer  read = stream_read(s, &buf[unused], -unused);  unused += read;  // fix buffer so it ends at pos == 0 (eof case)  *b = &buf[unused];  start -= unused;  return start;}/** * This format usually uses an insane bitrate, which makes this function * performance-critical! * Be sure to benchmark any changes with different compiler versions. */static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {  demux_packet_t *pack;  int len;  demux->filepos = stream_tell(demux->stream);  pack = new_demux_packet(STREAM_BUFFER_SIZE);  len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);  if (len <= 0)  {    free_demux_packet(pack);    return 0;  }  {    register uint32_t state = (uint32_t)demux->priv;    register int pos = -len;    unsigned char *buf = &pack->buffer[len];    do {      state = state << 8 | buf[pos];      if (unlikely((state | 3) == 0x1bf))        pos = find_end(&buf, pos, demux->stream);    } while (++pos < 0);    demux->priv = (void *)state;    len = buf - pack->buffer;  }  if (len < STREAM_BUFFER_SIZE)    resize_demux_packet(pack, len);  ds_add_packet(ds, pack);  return 1;}int demux_mpg_fill_buffer(demuxer_t *demux, demux_stream_t *ds){unsigned int head=0;int skipped=0;int max_packs=256; // 512kbyteint ret=0;// System streamdo{  demux->filepos=stream_tell(demux->stream);#if 1  //lame workaround: this is needed to show the progress bar when playing dvdnav://  //(ths poor guy doesn't know teh length of the stream at startup)  demux->movi_end = demux->stream->end_pos;#endif  head=stream_read_dword(demux->stream);  if((head&0xFFFFFF00)!=0x100){   // sync...   demux->filepos-=skipped;   while(1){    int c=stream_read_char(demux->stream);    if(c<0) break; //EOF    head<<=8;    if(head!=0x100){

⌨️ 快捷键说明

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