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

📄 demux_ogg.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 4 页
字号:
  ogg_sync_init(sync);  while(1) {    /// Try to get a page    ogg_d->pos += ogg_d->last_size;    np = ogg_sync_pageseek(sync,page);    /// Error    if(np < 0) {      mp_msg(MSGT_DEMUX,MSGL_DBG2,"Ogg demuxer : Bad page sync\n");      goto err_out;    }    /// Need some more data    if(np == 0) {      int len;      buf = ogg_sync_buffer(sync,BLOCK_SIZE);      len = stream_read(s,buf,BLOCK_SIZE);            if(len == 0 && s->eof) {	goto err_out;      }      ogg_sync_wrote(sync,len);      continue;    }    ogg_d->last_size = np;    // We got one page now    if( ! ogg_page_bos(page) ) { // It's not a begining page      // Header parsing end here, we need to get the page otherwise it will be lost      int id = demux_ogg_get_page_stream(ogg_d,NULL);      if(id >= 0)	ogg_stream_pagein(&ogg_d->subs[id].stream,page);      else	mp_msg(MSGT_DEMUX,MSGL_ERR,"Ogg : Warning found none bos page from unknown stream %d\n",ogg_page_serialno(page));      break;    }    /// Init  the data structure needed for a logical stream    ogg_d->subs = (ogg_stream_t*)realloc(ogg_d->subs,(ogg_d->num_sub+1)*sizeof(ogg_stream_t));    memset(&ogg_d->subs[ogg_d->num_sub],0,sizeof(ogg_stream_t));    /// Get the stream serial number    s_no = ogg_page_serialno(page);    ogg_stream_init(&ogg_d->subs[ogg_d->num_sub].stream,s_no);    mp_msg(MSGT_DEMUX,MSGL_DBG2,"Ogg : Found a stream with serial=%d\n",s_no);    // Take the first page    ogg_stream_pagein(&ogg_d->subs[ogg_d->num_sub].stream,page);    // Get first packet of the page    ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream,&pack);    // Reset our vars    sh_a = NULL;    sh_v = NULL;    demux_aid_vid_mismatch = 1; // don't identify in new_sh_* since ids don't match    // Check for Vorbis    if(pack.bytes >= 7 && ! strncmp(&pack.packet[1],"vorbis", 6) ) {      sh_a = new_sh_audio(demuxer,ogg_d->num_sub);      sh_a->format = FOURCC_VORBIS;      ogg_d->subs[ogg_d->num_sub].vorbis = 1;      if (identify)        mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio);      ogg_d->subs[ogg_d->num_sub].id = n_audio;      n_audio++;      mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: audio (Vorbis), -aid %d\n",ogg_d->num_sub,n_audio-1);      // check for Theora#   ifdef HAVE_OGGTHEORA    } else if (pack.bytes >= 7 && !strncmp (&pack.packet[1], "theora", 6)) {	int errorCode = 0;	theora_info inf;	theora_comment cc;		theora_info_init (&inf);	theora_comment_init (&cc);		errorCode = theora_decode_header (&inf, &cc, &pack);	if (errorCode)	    mp_msg(MSGT_DEMUX,MSGL_ERR,"Theora header parsing failed: %i \n",		   errorCode);	else	{	    sh_v = new_sh_video(demuxer,ogg_d->num_sub);	    sh_v->context = NULL;	    sh_v->bih = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER));	    sh_v->bih->biSize=sizeof(BITMAPINFOHEADER);	    sh_v->bih->biCompression= sh_v->format = FOURCC_THEORA;	    sh_v->fps = ((double)inf.fps_numerator)/		(double)inf.fps_denominator;	    sh_v->frametime = ((double)inf.fps_denominator)/		(double)inf.fps_numerator;	    sh_v->disp_w = sh_v->bih->biWidth = inf.frame_width;	    sh_v->disp_h = sh_v->bih->biHeight = inf.frame_height;	    sh_v->bih->biBitCount = 24;	    sh_v->bih->biPlanes = 3;	    sh_v->bih->biSizeImage = ((sh_v->bih->biBitCount/8) * 				      sh_v->bih->biWidth*sh_v->bih->biHeight);	    ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;	    ogg_d->subs[ogg_d->num_sub].theora = 1;	    if (identify)	      mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video);	    ogg_d->subs[ogg_d->num_sub].id = n_video;	    n_video++;	    mp_msg(MSGT_DEMUX,MSGL_INFO,		   "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",		   ogg_d->num_sub,		   (int)inf.version_major, 		   (int)inf.version_minor, 		   (int)inf.version_subminor, 		   n_video - 1);	    if(verbose>0) print_video_header(sh_v->bih);	}#   endif /* HAVE_OGGTHEORA */#   ifdef HAVE_FLAC    } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) {	sh_a = new_sh_audio(demuxer,ogg_d->num_sub);	sh_a->format =  mmioFOURCC('f', 'L', 'a', 'C');	if (identify)	  mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio);	ogg_d->subs[ogg_d->num_sub].id = n_audio;	n_audio++;	ogg_d->subs[ogg_d->num_sub].flac = 1;	sh_a->wf = NULL;	mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: audio (FLAC), -aid %d\n",ogg_d->num_sub,n_audio-1);#   endif /* HAVE_FLAC */      /// Check for old header    } else if(pack.bytes >= 142 && ! strncmp(&pack.packet[1],"Direct Show Samples embedded in Ogg",35) ) {       // Old video header      if(get_uint32 (pack.packet+96) == 0x05589f80 && pack.bytes >= 184) {	sh_v = new_sh_video(demuxer,ogg_d->num_sub);	sh_v->bih = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER));	sh_v->bih->biSize=sizeof(BITMAPINFOHEADER);	sh_v->bih->biCompression=	sh_v->format = mmioFOURCC(pack.packet[68],pack.packet[69],				pack.packet[70],pack.packet[71]);	sh_v->frametime = get_uint64(pack.packet+164)*0.0000001;	sh_v->fps = 1/sh_v->frametime;	sh_v->disp_w = sh_v->bih->biWidth = get_uint32(pack.packet+176);	sh_v->disp_h = sh_v->bih->biHeight = get_uint32(pack.packet+180);	sh_v->bih->biBitCount = get_uint16(pack.packet+182);	if(!sh_v->bih->biBitCount) sh_v->bih->biBitCount=24; // hack, FIXME	sh_v->bih->biPlanes=1;	sh_v->bih->biSizeImage=(sh_v->bih->biBitCount>>3)*sh_v->bih->biWidth*sh_v->bih->biHeight;	ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;	if (identify)	  mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video);	ogg_d->subs[ogg_d->num_sub].id = n_video;	n_video++;	mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",	       ogg_d->num_sub,pack.packet[68],pack.packet[69],pack.packet[70],pack.packet[71],n_video-1);	if(verbose>0) print_video_header(sh_v->bih);	// Old audio header      } else if(get_uint32(pack.packet+96) == 0x05589F81) {	unsigned int extra_size;	sh_a = new_sh_audio(demuxer,ogg_d->num_sub);	extra_size = get_uint16(pack.packet+140);	sh_a->wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)+extra_size);	sh_a->format = sh_a->wf->wFormatTag = get_uint16(pack.packet+124);	sh_a->channels = sh_a->wf->nChannels = get_uint16(pack.packet+126);	sh_a->samplerate = sh_a->wf->nSamplesPerSec = get_uint32(pack.packet+128);	sh_a->wf->nAvgBytesPerSec = get_uint32(pack.packet+132);	sh_a->wf->nBlockAlign = get_uint16(pack.packet+136);	sh_a->wf->wBitsPerSample = get_uint16(pack.packet+138);	sh_a->samplesize = (sh_a->wf->wBitsPerSample+7)/8;	sh_a->wf->cbSize = extra_size;	if(extra_size > 0)	  memcpy(((char *)sh_a->wf)+sizeof(WAVEFORMATEX),pack.packet+142,extra_size);	ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;	if (identify)	  mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio);	ogg_d->subs[ogg_d->num_sub].id = n_audio;	n_audio++;	mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",ogg_d->num_sub,sh_a->format,n_audio-1);	if(verbose>0) print_wave_header(sh_a->wf);      } else	mp_msg(MSGT_DEMUX,MSGL_WARN,"Ogg stream %d contains an old header but the header type is unknown\n",ogg_d->num_sub);        // Check new header    } else if ( (*pack.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER && 	      pack.bytes >= (int)sizeof(stream_header)+1) {      stream_header *st = (stream_header*)(pack.packet+1);      /// New video header      if(strncmp(st->streamtype,"video",5) == 0) {	sh_v = new_sh_video(demuxer,ogg_d->num_sub);	sh_v->bih = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER));	sh_v->bih->biSize=sizeof(BITMAPINFOHEADER);	sh_v->bih->biCompression=	sh_v->format = mmioFOURCC(st->subtype[0],st->subtype[1],				  st->subtype[2],st->subtype[3]);	sh_v->frametime = get_uint64(&st->time_unit)*0.0000001;	sh_v->fps = 1.0/sh_v->frametime;	sh_v->bih->biBitCount = get_uint16(&st->bits_per_sample);	sh_v->disp_w = sh_v->bih->biWidth = get_uint32(&st->sh.video.width);	sh_v->disp_h = sh_v->bih->biHeight = get_uint32(&st->sh.video.height);	if(!sh_v->bih->biBitCount) sh_v->bih->biBitCount=24; // hack, FIXME	sh_v->bih->biPlanes=1;	sh_v->bih->biSizeImage=(sh_v->bih->biBitCount>>3)*sh_v->bih->biWidth*sh_v->bih->biHeight;	ogg_d->subs[ogg_d->num_sub].samplerate= sh_v->fps;	if (identify)	  mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", n_video);	ogg_d->subs[ogg_d->num_sub].id = n_video;	n_video++;	mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",	       ogg_d->num_sub,st->subtype[0],st->subtype[1],st->subtype[2],st->subtype[3],n_video-1);	if(verbose>0) print_video_header(sh_v->bih);	/// New audio header      } else if(strncmp(st->streamtype,"audio",5) == 0) {	char buffer[5];	unsigned int extra_size = get_uint32 (&st->size) - sizeof(stream_header);	memcpy(buffer,st->subtype,4);	buffer[4] = '\0';	sh_a = new_sh_audio(demuxer,ogg_d->num_sub);	sh_a->wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)+extra_size);	sh_a->format =  sh_a->wf->wFormatTag = strtol(buffer, NULL, 16);	sh_a->channels = sh_a->wf->nChannels = get_uint16(&st->sh.audio.channels);	sh_a->samplerate = sh_a->wf->nSamplesPerSec = get_uint64(&st->samples_per_unit);	sh_a->wf->nAvgBytesPerSec = get_uint32(&st->sh.audio.avgbytespersec);	sh_a->wf->nBlockAlign = get_uint16(&st->sh.audio.blockalign);	sh_a->wf->wBitsPerSample = get_uint16(&st->bits_per_sample);	sh_a->samplesize = (sh_a->wf->wBitsPerSample+7)/8;	sh_a->wf->cbSize = extra_size;	if(extra_size)	  memcpy(((char *)sh_a->wf)+sizeof(WAVEFORMATEX),st+1,extra_size);	ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;	if (identify)	  mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", n_audio);	ogg_d->subs[ogg_d->num_sub].id = n_audio;	n_audio++;	mp_msg(MSGT_DEMUX,MSGL_INFO,"[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",ogg_d->num_sub,sh_a->format,n_audio-1);	if(verbose>0) print_wave_header(sh_a->wf);	/// Check for text (subtitles) header      } else if (strncmp(st->streamtype, "text", 4) == 0) {          mp_msg(MSGT_DEMUX, MSGL_INFO, "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n", ogg_d->num_sub, ogg_d->n_text);	  ogg_d->subs[ogg_d->num_sub].samplerate= get_uint64(&st->time_unit)/10;	  ogg_d->subs[ogg_d->num_sub].text = 1;	  if (identify)	    mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", ogg_d->n_text);          ogg_d->subs[ogg_d->num_sub].id = ogg_d->n_text;          if (demuxer->sub->id == ogg_d->n_text)            text_id = ogg_d->num_sub;          ogg_d->n_text++;          ogg_d->text_ids = (int *)realloc(ogg_d->text_ids, sizeof(int) * ogg_d->n_text);          ogg_d->text_ids[ogg_d->n_text - 1] = ogg_d->num_sub;          ogg_d->text_langs = (char **)realloc(ogg_d->text_langs, sizeof(char *) * ogg_d->n_text);          ogg_d->text_langs[ogg_d->n_text - 1] = NULL;          demux_ogg_init_sub();	//// Unknown header type      } else	mp_msg(MSGT_DEMUX,MSGL_ERR,"Ogg stream %d has a header marker but is of an unknown type\n",ogg_d->num_sub);      /// Unknown (invalid ?) header    } else      mp_msg(MSGT_DEMUX,MSGL_ERR,"Ogg stream %d is of an unknown type\n",ogg_d->num_sub);    if(sh_a || sh_v) {      demux_stream_t* ds = NULL;      if(sh_a) {	// If the audio stream is not defined we took the first one	if(demuxer->audio->id == -1) {	  demuxer->audio->id = n_audio - 1;//	  if(sh_a->wf) print_wave_header(sh_a->wf);	}	/// Is it the stream we want	if(demuxer->audio->id == (n_audio - 1)) {	  demuxer->audio->sh = sh_a;	  sh_a->ds = demuxer->audio;	  ds = demuxer->audio;          audio_id = ogg_d->num_sub;	}      }      if(sh_v) {	/// Also for video	if(demuxer->video->id == -1) {	  demuxer->video->id = n_video - 1;//	  if(sh_v->bih) print_video_header(sh_v->bih);	}	if(demuxer->video->id == (n_video - 1)) {	  demuxer->video->sh = sh_v;	  sh_v->ds = demuxer->video;	  ds = demuxer->video;          video_id = ogg_d->num_sub;	}      }      /// Add the header packets if the stream isn't seekable      if(ds && !s->end_pos) {	/// Finish the page, otherwise packets will be lost	do {	  demux_ogg_add_packet(ds,&ogg_d->subs[ogg_d->num_sub],ogg_d->num_sub,&pack);	} while(ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream,&pack) == 1);      }    }    ogg_d->num_sub++;        }  if(!n_video && !n_audio) {    goto err_out;  }  /// Finish to setup the demuxer  demuxer->priv = ogg_d;  if(!n_video || (video_id < 0))    demuxer->video->id = -2;  else    demuxer->video->id = video_id;  if(!n_audio || (audio_id < 0))    demuxer->audio->id = -2;  else    demuxer->audio->id = audio_id;  /* Disable the subs only if there are no text streams at all.     Otherwise the stream to display might be chosen later when the comment     packet is encountered and the user used -slang instead of -sid. */  if(!ogg_d->n_text)    demuxer->sub->id = -2;  else if (text_id >= 0) {    demuxer->sub->id = text_id;    mp_msg(MSGT_DEMUX, MSGL_V, "Ogg demuxer: Displaying subtitle stream id %d\n", text_id);  }  ogg_d->final_granulepos=0;  if(!s->end_pos)    demuxer->seekable = 0;  else {    demuxer->movi_start = s->start_pos; // Needed for XCD (Ogg written in MODE2)    demuxer->movi_end = s->end_pos;    demuxer->seekable = 1;    demux_ogg_scan_stream(demuxer);  }  mp_msg(MSGT_DEMUX,MSGL_V,"Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",n_audio,n_audio>1?"s":"",n_video,n_video>1?"s":"",ogg_d->n_text,ogg_d->n_text>1?"s":"");  return 1;err_out:  demux_close_ogg(demuxer);  return 0;}int demux_ogg_fill_buffer(demuxer_t *d) {  ogg_demuxer_t* ogg_d;  stream_t *s;  demux_stream_t *ds;  ogg_sync_state* sync;  ogg_stream_state* os;  ogg_page* page;  ogg_packet pack;  int np = 0, id=0;  s = d->stream;  ogg_d = d->priv;  sync = &ogg_d->sync;  page = &ogg_d->page;  /// Find the stream we are working on  if ( (id = demux_ogg_get_page_stream(ogg_d,&os)) < 0) {      mp_msg(MSGT_DEMUX,MSGL_ERR,"Ogg demuxer : can't get current stream\n");      return 0;  }  while(1) {    np = 0;    ds = NULL;    /// Try to get some packet from the current page    while( (np = ogg_stream_packetout(os,&pack)) != 1) {      /// No packet we go the next page      if(np == 0) {	while(1) {	  int pa,len;	  char *buf;	  ogg_d->pos += ogg_d->last_size;	  /// Get the next page from the physical stream	  while( (pa = ogg_sync_pageseek(sync,page)) <= 0) {	    /// Error : we skip some bytes	    if(pa < 0) {	      mp_msg(MSGT_DEMUX,MSGL_WARN,"Ogg : Page out not synced, we skip some bytes\n");

⌨️ 快捷键说明

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