// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_smjpeg_fill_buffer(demuxer_t *demux, demux_stream_t *ds) { int dtype, dsize, dpts; demux->filepos = stream_tell(demux->stream); dtype = stream_read_dword_le(demux->stream); dpts = stream_read_dword(demux->stream); dsize = stream_read_dword(demux->stream); switch(dtype) { case mmioFOURCC('s','n','d','D'): /* fixme, but no decoder implemented yet */ ds_read_packet(demux->audio, demux->stream, dsize, (float)dpts/1000.0, demux->filepos, 0); break; case mmioFOURCC('v','i','d','D'): ds_read_packet(demux->video, demux->stream, dsize, (float)dpts/1000.0, demux->filepos, 0); break; case mmioFOURCC('D','O','N','E'): return 1; default: return 0; } return 1; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_roq_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) { sh_video_t *sh_video = demuxer->video->sh; roq_data_t *roq_data = (roq_data_t *)demuxer->priv; roq_chunk_t roq_chunk; if (roq_data->current_chunk >= roq_data->total_chunks) return 0; roq_chunk = roq_data->chunks[roq_data->current_chunk]; // make sure we're at the right place in the stream and fetch the chunk stream_seek(demuxer->stream, roq_chunk.chunk_offset); if (roq_chunk.chunk_type == CHUNK_TYPE_AUDIO) ds_read_packet(demuxer->audio, demuxer->stream, roq_chunk.chunk_size, 0, roq_chunk.chunk_offset, 0); else ds_read_packet(demuxer->video, demuxer->stream, roq_chunk.chunk_size, roq_chunk.video_chunk_number / sh_video->fps, roq_chunk.chunk_offset, 0); roq_data->current_chunk++; return 1; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_fli_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds){ fli_frames_t *frames = (fli_frames_t *)demuxer->priv; sh_video_t *sh_video = demuxer->video->sh; // see if the end has been reached if (frames->current_frame >= frames->num_frames) return 0; // fetch the frame from the file // first, position the file properly since ds_read_packet() doesn't // seem to do it, even though it takes a file offset as a parameter stream_seek(demuxer->stream, frames->filepos[frames->current_frame]); ds_read_packet(demuxer->video, demuxer->stream, frames->frame_size[frames->current_frame], frames->current_frame/sh_video->fps, frames->filepos[frames->current_frame], 0 /* what flags? -> demuxer.h (alex) */ ); // get the next frame ready frames->current_frame++; return 1; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_lmlm4_fill_buffer(demuxer_t *demux, demux_stream_t *ds) { FrameInfo frameInfo; double pts; int id=1; int ret; //hdr: demux->filepos = stream_tell(demux->stream); mp_msg(MSGT_DEMUX, MSGL_DBG2, "fpos = %"PRId64"\n", (int64_t)demux->filepos); ret=getFrame(demux, &frameInfo); if(ret<=0) return ret; // EOF/error pts=demux->video->sh ? frames*((sh_video_t*)(demux->video->sh))->frametime : 0; switch(frameInfo.frameType) { case FRAMETYPE_AUDIO_MPEG1L2: mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Audio Packet\n"); if (!video) { stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize); mp_msg(MSGT_DEMUX, MSGL_V, "Skip Audio Packet\n"); return -1; //goto hdr; } if(demux->audio->id==-1) { if(!demux->a_streams[id]) new_sh_audio(demux,id, NULL); demux->audio->id=id; demux->audio->sh=demux->a_streams[id]; ((sh_audio_t*)(demux->audio->sh))->format=0x50; // mpeg audio layer 1/2 } if(demux->audio->id==id) ds_read_packet(demux->audio, demux->stream, frameInfo.frameSize, pts, demux->filepos, 0); else stream_skip(demux->stream,frameInfo.frameSize); break; case FRAMETYPE_I: if (!video) { video = 1; mp_dbg(MSGT_DEMUX, MSGL_DBG2, "First Video Packet\n"); } case FRAMETYPE_P: frames=(frames+1)&(1024*1024-1); // wrap around at 4 hrs to avoid inaccurate float calculations if (!video) { stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize); mp_msg(MSGT_DEMUX, MSGL_V, "Skip Video P Packet\n"); return -1; //goto hdr; } mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Video Packet\n"); if(demux->video->id==-1) { if(!demux->v_streams[id]) new_sh_video(demux,id); demux->video->id=id; demux->video->sh=demux->v_streams[id]; ((sh_video_t*)(demux->video->sh))->format=0x10000004; // mpeg4-ES } if(demux->video->id==id) ds_read_packet(demux->video, demux->stream, frameInfo.frameSize, pts, demux->filepos, 0); break; default: stream_skip(demux->stream,frameInfo.frameSize); } stream_skip(demux->stream, frameInfo.paddingSize); return 1; }
static int demux_avi_read_packet(demuxer_t *demux,demux_stream_t *ds,unsigned int id,unsigned int len,int idxpos,int flags){ avi_priv_t *priv=demux->priv; int skip; float pts=0; mp_dbg(MSGT_DEMUX,MSGL_DBG3,"demux_avi.read_packet: %X\n",id); if(ds==demux->audio){ if(priv->pts_corrected==0){ if(priv->pts_has_video){ // we have video pts now float delay=0; if(((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec) delay=(float)priv->pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec; mp_msg(MSGT_DEMUX,MSGL_V,"XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",priv->avi_audio_pts,priv->pts_corr_bytes,delay); //priv->pts_correction=-priv->avi_audio_pts+delay; priv->pts_correction=delay-priv->avi_audio_pts; priv->avi_audio_pts+=priv->pts_correction; priv->pts_corrected=1; } else priv->pts_corr_bytes+=len; } if(pts_from_bps){ pts = priv->audio_block_no * (float)((sh_audio_t*)demux->audio->sh)->audio.dwScale / (float)((sh_audio_t*)demux->audio->sh)->audio.dwRate; } else pts=priv->avi_audio_pts; //+priv->pts_correction; priv->avi_audio_pts=0; // update blockcount: priv->audio_block_no+=priv->audio_block_size ? ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1; } else if(ds==demux->video){ // video if(priv->skip_video_frames>0){ // drop frame (seeking) --priv->skip_video_frames; ds=NULL; } pts = priv->avi_video_pts = priv->video_pack_no * (float)((sh_video_t*)demux->video->sh)->video.dwScale / (float)((sh_video_t*)demux->video->sh)->video.dwRate; priv->avi_audio_pts=priv->avi_video_pts+priv->pts_correction; priv->pts_has_video=1; if(ds) ++priv->video_pack_no; } skip=(len+1)&(~1); // total bytes in this chunk if(ds){ mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Read %d data bytes from packet %04X\n",len,id); ds_read_packet(ds,demux->stream,len,pts,idxpos,flags); skip-=len; } skip = FFMAX(skip, 0); if (avi_stream_id(id) > 99 && id != mmioFOURCC('J','U','N','K')) skip = FFMIN(skip, 65536); if(skip){ mp_dbg(MSGT_DEMUX,MSGL_DBG2,"DEMUX_AVI: Skipping %d bytes from packet %04X\n",skip,id); stream_skip(demux->stream,skip); } return ds?1:0; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_film_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) { int i; unsigned char byte_swap; int cvid_size; sh_video_t *sh_video = demuxer->video->sh; sh_audio_t *sh_audio = demuxer->audio->sh; film_data_t *film_data = (film_data_t *)demuxer->priv; film_chunk_t film_chunk; int length_fix_bytes; demux_packet_t* dp; // see if the end has been reached if (film_data->current_chunk >= film_data->total_chunks) return 0; film_chunk = film_data->chunks[film_data->current_chunk]; // position stream and fetch chunk stream_seek(demuxer->stream, film_chunk.chunk_offset); // load the chunks manually (instead of using ds_read_packet()), since // they require some adjustment // (all ones in syncinfo1 indicates an audio chunk) if (film_chunk.syncinfo1 == 0xFFFFFFFF) { if(demuxer->audio->id>=-1){ // audio not disabled dp = new_demux_packet(film_chunk.chunk_size); if (stream_read(demuxer->stream, dp->buffer, film_chunk.chunk_size) != film_chunk.chunk_size) return 0; dp->pts = film_chunk.pts; dp->pos = film_chunk.chunk_offset; dp->flags = 0; // adjust the data before queuing it: // 8-bit: signed -> unsigned // 16-bit: big-endian -> little-endian if (sh_audio->wf->wBitsPerSample == 8) for (i = 0; i < film_chunk.chunk_size; i++) dp->buffer[i] += 128; else for (i = 0; i < film_chunk.chunk_size; i += 2) { byte_swap = dp->buffer[i]; dp->buffer[i] = dp->buffer[i + 1]; dp->buffer[i + 1] = byte_swap; } /* for SegaSaturn .cpk file, translate audio data if stereo */ if (sh_audio->wf->nChannels == 2) { if (sh_audio->wf->wBitsPerSample == 8) { unsigned char* tmp = dp->buffer; unsigned char buf[film_chunk.chunk_size]; for(i = 0; i < film_chunk.chunk_size/2; i++) { buf[i*2] = tmp[i]; buf[i*2+1] = tmp[film_chunk.chunk_size/2+i]; } memcpy( tmp, buf, film_chunk.chunk_size ); } else {/* for 16bit */ unsigned short* tmp = dp->buffer; unsigned short buf[film_chunk.chunk_size/2]; for(i = 0; i < film_chunk.chunk_size/4; i++) { buf[i*2] = tmp[i]; buf[i*2+1] = tmp[film_chunk.chunk_size/4+i]; } memcpy( tmp, buf, film_chunk.chunk_size ); } } // append packet to DS stream ds_add_packet(demuxer->audio, dp); } } else { // if the demuxer is dealing with CVID data, deal with it a special way if (sh_video->format == mmioFOURCC('c', 'v', 'i', 'd')) { if (film_data->film_version) length_fix_bytes = 2; else length_fix_bytes = 6; // account for the fix bytes when allocating the buffer dp = new_demux_packet(film_chunk.chunk_size - length_fix_bytes); // these CVID data chunks have a few extra bytes; skip them if (stream_read(demuxer->stream, dp->buffer, 10) != 10) return 0; stream_skip(demuxer->stream, length_fix_bytes); if (stream_read(demuxer->stream, dp->buffer + 10, film_chunk.chunk_size - (10 + length_fix_bytes)) != (film_chunk.chunk_size - (10 + length_fix_bytes))) return 0; dp->pts = film_chunk.pts; dp->pos = film_chunk.chunk_offset; dp->flags = (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0; // fix the CVID chunk size cvid_size = film_chunk.chunk_size - length_fix_bytes; dp->buffer[1] = (cvid_size >> 16) & 0xFF; dp->buffer[2] = (cvid_size >> 8) & 0xFF; dp->buffer[3] = (cvid_size >> 0) & 0xFF; // append packet to DS stream ds_add_packet(demuxer->video, dp); } else { ds_read_packet(demuxer->video, demuxer->stream, film_chunk.chunk_size, film_chunk.pts, film_chunk.chunk_offset, (film_chunk.syncinfo1 & 0x80000000) ? 1 : 0); } }