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

📄 demux_mov.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
		    case MOV_FOURCC(0xa9,'f','m','t'):		    case MOV_FOURCC(0xa9,'i','n','f'):		    case MOV_FOURCC(0xa9,'p','r','d'):		    case MOV_FOURCC(0xa9,'p','r','f'):		    case MOV_FOURCC(0xa9,'r','e','q'):		    case MOV_FOURCC(0xa9,'s','r','c'):		    case MOV_FOURCC('n','a','m','e'):		    case MOV_FOURCC(0xa9,'n','a','m'):		    case MOV_FOURCC(0xa9,'A','R','T'):		    case MOV_FOURCC(0xa9,'c','m','t'):		    case MOV_FOURCC(0xa9,'a','u','t'):		    case MOV_FOURCC(0xa9,'s','w','r'):		    {			off_t text_len = stream_read_word(demuxer->stream);			char text[text_len+2+1];			stream_read(demuxer->stream, (char *)&text, text_len+2);			text[text_len+2] = 0x0;			switch(udta_id)			{			    case MOV_FOURCC(0xa9,'a','u','t'):				demux_info_add(demuxer, "author", &text[2]);				mp_msg(MSGT_DEMUX, MSGL_V, " Author: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'c','p','y'):				demux_info_add(demuxer, "copyright", &text[2]);				mp_msg(MSGT_DEMUX, MSGL_V, " Copyright: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'i','n','f'):				mp_msg(MSGT_DEMUX, MSGL_V, " Info: %s\n", &text[2]);				break;			    case MOV_FOURCC('n','a','m','e'):			    case MOV_FOURCC(0xa9,'n','a','m'):				demux_info_add(demuxer, "name", &text[2]);				mp_msg(MSGT_DEMUX, MSGL_V, " Name: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'A','R','T'):				mp_msg(MSGT_DEMUX, MSGL_V, " Artist: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'d','i','r'):				mp_msg(MSGT_DEMUX, MSGL_V, " Director: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'c','m','t'):				demux_info_add(demuxer, "comments", &text[2]);				mp_msg(MSGT_DEMUX, MSGL_V, " Comment: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'r','e','q'):				mp_msg(MSGT_DEMUX, MSGL_V, " Requirements: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'s','w','r'):				demux_info_add(demuxer, "encoder", &text[2]);				mp_msg(MSGT_DEMUX, MSGL_V, " Software: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'d','a','y'):				mp_msg(MSGT_DEMUX, MSGL_V, " Creation timestamp: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'f','m','t'):				mp_msg(MSGT_DEMUX, MSGL_V, " Format: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'p','r','d'):				mp_msg(MSGT_DEMUX, MSGL_V, " Producer: %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'p','r','f'):				mp_msg(MSGT_DEMUX, MSGL_V, " Performer(s): %s\n", &text[2]);				break;			    case MOV_FOURCC(0xa9,'s','r','c'):				mp_msg(MSGT_DEMUX, MSGL_V, " Source providers: %s\n", &text[2]);				break;			}			udta_size -= 4+text_len;			break;		    }		    /* some other shits:    WLOC - window location,					    LOOP - looping style,					    SelO - play only selected frames					    AllF - play all frames		    */		    case MOV_FOURCC('W','L','O','C'):		    case MOV_FOURCC('L','O','O','P'):		    case MOV_FOURCC('S','e','l','O'):		    case MOV_FOURCC('A','l','l','F'):		    default:		    {			if( udta_len>udta_size)				udta_len=udta_size;			{			char dump[udta_len-4];			stream_read(demuxer->stream, (char *)&dump, udta_len-4-4);			udta_size -= udta_len;			}		    }		}	    }	    break;	} /* eof udta */	default:	  id = be2me_32(id);	  mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",&id,(int)len);	} /* endof switch */	} /* endof else */	pos+=len+8;	if(pos>=endpos) break;	if(!stream_seek(demuxer->stream,pos)) break;    }}int mov_read_header(demuxer_t* demuxer){    mov_priv_t* priv=demuxer->priv;    int t_no;    int best_a_id=-1, best_a_len=0;    int best_v_id=-1, best_v_len=0;        mp_msg(MSGT_DEMUX, MSGL_DBG3, "mov_read_header!\n");    // Parse header:        stream_reset(demuxer->stream);    if(!stream_seek(demuxer->stream,priv->moov_start))    {	mp_msg(MSGT_DEMUX,MSGL_ERR,"MOV: Cannot seek to the beginning of the Movie header (0x%x)\n",	    priv->moov_start);	return 0;    }    lschunks(demuxer, 0, priv->moov_end, NULL);    // just in case we have hit eof while parsing...    demuxer->stream->eof = 0;//    mp_msg(MSGT_DEMUX, MSGL_INFO, "--------------\n");    // find the best (longest) streams:    for(t_no=0;t_no<priv->track_db;t_no++){        mov_track_t* trak=priv->tracks[t_no];	int len=(trak->samplesize) ? trak->chunks_size : trak->samples_size;	if(demuxer->a_streams[t_no]){ // need audio	    if(len>best_a_len){	best_a_len=len; best_a_id=t_no; }	}	if(demuxer->v_streams[t_no]){ // need video	    if(len>best_v_len){	best_v_len=len; best_v_id=t_no; }	}    }    mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: longest streams: A: #%d (%d samples)  V: #%d (%d samples)\n",	best_a_id,best_a_len,best_v_id,best_v_len);    if(demuxer->audio->id==-1 && best_a_id>=0) demuxer->audio->id=best_a_id;    if(demuxer->video->id==-1 && best_v_id>=0) demuxer->video->id=best_v_id;        // setup sh pointers:    if(demuxer->audio->id>=0){	sh_audio_t* sh=demuxer->a_streams[demuxer->audio->id];	if(sh){	    demuxer->audio->sh=sh; sh->ds=demuxer->audio;	} else {	    mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: selected audio stream (%d) does not exists\n",demuxer->audio->id);	    demuxer->audio->id=-2;	}    }    if(demuxer->video->id>=0){	sh_video_t* sh=demuxer->v_streams[demuxer->video->id];	if(sh){	    demuxer->video->sh=sh; sh->ds=demuxer->video;	} else {	    mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: selected video stream (%d) does not exists\n",demuxer->video->id);	    demuxer->video->id=-2;	}    }#if 1    if(verbose>2){	for(t_no=0;t_no<priv->track_db;t_no++){	    mov_track_t* trak=priv->tracks[t_no];	    if(trak->type==MOV_TRAK_GENERIC){		int i;		int fd;		char name[20];		mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Track #%d: Extracting %d data chunks to files\n",t_no,trak->samples_size);		for (i=0; i<trak->samples_size; i++)		{		    int len=trak->samples[i].size;		    char buf[len];		    stream_seek(demuxer->stream, trak->samples[i].pos);		    snprintf(name, 20, "t%02d-s%03d.%s", t_no,i,			(trak->media_handler==MOV_FOURCC('f','l','s','h')) ?			    "swf":"dump");		    fd = open(name, O_CREAT|O_WRONLY);//		    { int j;//			for(j=0;j<trak->stdata_len-3; j++)//			    printf("stdata[%d]=0x%X ize=0x%X\n",j,char2int(trak->stdata,j),MOV_FOURCC('z','l','i','b'));//		    }		    if( //trak->media_handler==MOV_FOURCC('s','p','r','t') &&			trak->stdata_len>=16 &&			char2int(trak->stdata,12)==MOV_FOURCC('z','l','i','b') 		    ){			int newlen=stream_read_dword(demuxer->stream);#ifdef HAVE_ZLIB			// unzip:			z_stream zstrm;			int zret;			char buf2[newlen];			len-=4;			stream_read(demuxer->stream, buf, len);	                zstrm.zalloc          = (alloc_func)0;	                zstrm.zfree           = (free_func)0;	                zstrm.opaque          = (voidpf)0;	                zstrm.next_in         = buf;	                zstrm.avail_in        = len;	                zstrm.next_out        = buf2;	                zstrm.avail_out       = newlen;	                zret = inflateInit(&zstrm);			zret = inflate(&zstrm, Z_NO_FLUSH);			if(newlen != zstrm.total_out)	    		    mp_msg(MSGT_DEMUX, MSGL_WARN, "Warning! unzipped frame size differs hdr: %d  zlib: %d\n",newlen,zstrm.total_out);						write(fd, buf2, newlen);		    } else {#else			len-=4;			printf("******* ZLIB COMPRESSED SAMPLE!!!!! (%d->%d bytes) *******\n",len,newlen);		    }		    {#endif			stream_read(demuxer->stream, buf, len);			write(fd, buf, len);		    }		    close(fd);		}	    }	}    }    demuxer->stream->eof = 0;#endif    return 1;}/** * \brief return the mov track that belongs to a demuxer stream * \param ds the demuxer stream, may be NULL * \return the mov track info structure belonging to the stream, *          NULL if not found */static mov_track_t *stream_track(mov_priv_t *priv, demux_stream_t *ds) {  if (ds && (ds->id >= 0) && (ds->id < priv->track_db))    return priv->tracks[ds->id];  return NULL;}// return value://     0 = EOF or no stream found//     1 = successfully read a packetint demux_mov_fill_buffer(demuxer_t *demuxer,demux_stream_t* ds){    mov_priv_t* priv=demuxer->priv;    mov_track_t* trak=NULL;    float pts;    int x;    off_t pos;        trak = stream_track(priv, ds);    if (!trak) return 0;if(trak->samplesize){    // read chunk:    if(trak->pos>=trak->chunks_size) return 0; // EOF    stream_seek(demuxer->stream,trak->chunks[trak->pos].pos);    pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale;    if(trak->samplesize!=1)    {	mp_msg(MSGT_DEMUX, MSGL_DBG2, "WARNING! Samplesize(%d) != 1\n",	    trak->samplesize);	x=trak->chunks[trak->pos].size*trak->samplesize;    }    else	x=trak->chunks[trak->pos].size;//    printf("X = %d\n", x);    /* the following stuff is audio related */    if (trak->type == MOV_TRAK_AUDIO){      if(trak->stdata_len>=44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){        // stsd version 1 - we have audio compression ratio info:	x/=char2int(trak->stdata,28); // samples/packet//	x*=char2int(trak->stdata,32); // bytes/packet	x*=char2int(trak->stdata,36); // bytes/frame      } else {	if(ds->ss_div && ds->ss_mul){	    // workaround for buggy files like 7up-high-traffic-areas.mov,	    // with missing stsd v1 header containing compression rate	    x/=ds->ss_div; x*=ds->ss_mul; // compression ratio fix  ! HACK !	} else {	    x*=trak->nchannels;	    x*=trak->samplebytes;	}      }      mp_msg(MSGT_DEMUX, MSGL_DBG2, "Audio sample %d bytes pts %5.3f\n",trak->chunks[trak->pos].size*trak->samplesize,pts);    } /* MOV_TRAK_AUDIO */    pos=trak->chunks[trak->pos].pos;} else {    int frame=trak->pos;    // editlist support:    if(trak->type == MOV_TRAK_VIDEO && trak->editlist_size>=1){	// find the right editlist entry:	if(frame<trak->editlist[trak->editlist_pos].start_frame)	    trak->editlist_pos=0;	while(trak->editlist_pos<trak->editlist_size-1 &&	    frame>=trak->editlist[trak->editlist_pos+1].start_frame)		++trak->editlist_pos;	if(frame>=trak->editlist[trak->editlist_pos].start_frame+	    trak->editlist[trak->editlist_pos].frames) return 0; // EOF	// calc real frame index:	frame-=trak->editlist[trak->editlist_pos].start_frame;	frame+=trak->editlist[trak->editlist_pos].start_sample;	// calc pts:	pts=(float)(trak->samples[frame].pts+	    trak->editlist[trak->editlist_pos].pts_offset)/(float)trak->timescale;    } else {	if(frame>=trak->samples_size) return 0; // EOF	pts=(float)trak->samples[frame].pts/(float)trak->timescale;    }    // read sample:    stream_seek(demuxer->stream,trak->samples[frame].pos);    x=trak->samples[frame].size;    pos=trak->samples[frame].pos;}if(trak->pos==0 && trak->stream_header_len>0){    // we have to append the stream header...    demux_packet_t* dp=new_demux_packet(x+trak->stream_header_len);    memcpy(dp->buffer,trak->stream_header,trak->stream_header_len);    stream_read(demuxer->stream,dp->buffer+trak->stream_header_len,x);    free(trak->stream_header);    trak->stream_header = NULL;    trak->stream_header_len = 0;    dp->pts=pts;    dp->flags=0;    dp->pos=pos; // FIXME?    ds_add_packet(ds,dp);} else    ds_read_packet(ds,demuxer->stream,x,pts,pos,0);        ++trak->pos;    return 1;    }static float mov_seek_track(mov_track_t* trak,float pts,int flags){//    printf("MOV track seek called  %5.3f  \n",pts);    if(flags&2) pts*=trak->length; else pts*=(float)trak->timescale;if(trak->samplesize){    int sample=pts/trak->duration;//    printf("MOV track seek - chunk: %d  (pts: %5.3f  dur=%d)  \n",sample,pts,trak->duration);    if(!(flags&1)) sample+=trak->chunks[trak->pos].sample; // relative    trak->pos=0;    while(trak->pos<trak->chunks_size && trak->chunks[trak->pos].sample<sample) ++trak->pos;    pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale;} else {    unsigned int ipts;    if(!(flags&1)) pts+=trak->samples[trak->pos].pts;    if(pts<0) pts=0;    ipts=pts;    //printf("MOV track seek - sample: %d  \n",ipts);    for(trak->pos=0;trak->pos<trak->samples_size;++trak->pos){	if(trak->samples[trak->pos].pts>=ipts) break; // found it!    }    if(trak->keyframes_size){	// find nearest keyframe	int i;	for(i=0;i<trak->keyframes_size;i++){	    if(trak->keyframes[i]>=trak->pos) break;	}	if(i>0 && (trak->keyframes[i]-trak->pos) > (trak->pos-trak->keyframes[i-1]))	  --i;	trak->pos=trak->keyframes[i];//	printf("nearest keyframe: %d  \n",trak->pos);    }    pts=(float)trak->samples[trak-

⌨️ 快捷键说明

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