DecapsAVI.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:22k
- #include "DecapsAVI.h"
- static void long2str(char *dst, int n)
- {
- dst[0] = (n ) & 0xff;
- dst[1] = (n >> 8) & 0xff;
- dst[2] = (n >> 16) & 0xff;
- dst[3] = (n >> 24) & 0xff;
- }
- unsigned long str2ulong(char *str)
- {
- unsigned long result;
- result = ( ((unsigned long) str[0] & 0xFF) | ( ((unsigned long)str[1] &0xFF) << 8) |
- (((unsigned long) str[2] & 0xFF) << 16) | ( ((unsigned long) str[3] & 0xFF) << 24) );
- return result;
- }
- static unsigned long str2ushort(char *str)
- {
- return ( str[0] | (str[1]<<8) );
- }
- media_type_t MediaDecapsAVI::GetType()
- {
- return MEDIA_TYPE_DECAPS;
- }
- char *MediaDecapsAVI::GetName()
- {
- return "AVI Demuxer";
- }
- MP_RESULT MediaDecapsAVI::Connect(MediaItem *item)
- {
- if(item->GetType() == MEDIA_TYPE_INPUT) {
- this->input = (MediaItemInput *) item;
- }
- this->video_pos = 0;
- this->audio_posc = 0;
- this->audio_posb = 0;
- this->idx = NULL;
- this->video_index = NULL;
- this->audio_index = NULL;
- if(this->IsAVI()) {
-
- if(this->FillHeader(1)) {
-
- return MP_RESULT_OK;
- }
- else {
- this->input->Seek(0, INPUT_SEEK_SET);
- this->IsAVI();
-
- if(this->FillHeader(0)) {
-
- return MP_RESULT_OK;
- }
- }
- }
-
- return MP_RESULT_ERROR;
- }
- MP_RESULT MediaDecapsAVI::ReleaseConnections()
- {
- this->input = NULL;
- if(this->idx != NULL)
- free(this->idx);
- if(this->video_index != NULL)
- free(this->video_index);
-
- if(this->audio_index != NULL)
- free(this->audio_index);
- this->idx = NULL;
- this->video_index = NULL;
- this->audio_index = NULL;
- this->audio_strn = 0;
- this->video_strn = 0;
- memset(&this->waveformatex, 0, sizeof(MPEGLAYER3WAVEFORMAT));
- memset(&this->bitmapinfoheader, 0, sizeof(BITMAPINFOHEADER));
-
- return MP_RESULT_OK;
- }
- DWORD MediaDecapsAVI::GetCaps()
- {
- return 0;
- }
- MP_RESULT MediaDecapsAVI::Configure(HINSTANCE hInstance, HWND hwnd)
- {
- return MP_RESULT_ERROR;
- }
- MediaDecapsAVI::MediaDecapsAVI()
- {
- this->video_pos = 0;
- this->audio_posc = 0;
- this->audio_posb = 0;
- this->idx = NULL;
- this->video_index = NULL;
- this->audio_index = NULL;
- this->hIOMutex = CreateMutex (NULL, FALSE, NULL);
- this->input = NULL;
- }
- MediaDecapsAVI::~MediaDecapsAVI()
- {
- CloseHandle(this->hIOMutex);
- }
- int MediaDecapsAVI::IsAVI()
- {
- MediaBuffer *mb = new MediaBuffer();
- mb->Alloc(12);
- if(this->input != NULL) {
-
- if( this->input->Read(mb, 12) != 12 ) {
-
- delete mb;
- return 0;
- }
-
- if( strncmp((char *) mb->GetData(), "RIFF", 4) !=0 ||
- strncmp(((char *) mb->GetData()) + 8, "AVI ", 4) !=0 ) {
- return 0;
- }
-
- delete mb;
- return 1;
- }
-
- return 0;
- }
- int MediaDecapsAVI::SampleSize()
- {
- int s;
-
- s = ((this->a_bits + 7) / 8) * this->a_chans;
-
- if(s == 0)
- s = 1;
-
- return s;
- }
- int MediaDecapsAVI::FillHeader(int getIndex)
- {
- unsigned long n, rate;
- long scale, idx_type;
- char *hdrl_data;
- long i, hdrl_len = 0;
- long nvi, nai, ioff;
- long tot;
- int lasttag = 0;
- int vids_strh_seen = 0;
- int vids_strf_seen = 0;
- int auds_strh_seen = 0;
- int auds_strf_seen = 0;
- int num_stream = 0;
- MediaBuffer *mb = new MediaBuffer();
-
- if(this->input == NULL)
- return MP_RESULT_ERROR;
- mb->Alloc(256);
-
- hdrl_data = 0;
-
- while(1)
- {
- if( this->input->Read(mb, 8) != 8 )
- break;
-
- n = str2ulong(((char *) mb->GetData()) + 4);
- n = PAD_EVEN(n);
-
- if(strncmp((char *) mb->GetData(), "LIST", 4) == 0)
- {
-
- if( this->input->Read(mb, 4) != 4 ) {
- mb->Free();
- return 0;
- }
-
- n -= 4;
-
- if(strncmp((char *) mb->GetData(), "hdrl", 4) == 0)
- {
-
- MediaBuffer *mbh;
- hdrl_len = n;
- char buffer[256];
- sprintf(buffer, "size = %d", n);
- mbh = new MediaBuffer();
- mbh->Alloc(n);
- hdrl_data = (char *) new char[n];
-
- if(hdrl_data == NULL) {
-
- mb->Free();
- return 0;
- }
-
- if( this->input->Read(mbh, n) != n ) {
-
- mb->Free();
- return 0;
- }
- memcpy(hdrl_data, mbh->GetData(), n);
- mbh->Free();
- }
- else if(strncmp((char *) mb->GetData(), "movi", 4) == 0)
- {
- this->movi_start = this->input->Seek(0, INPUT_SEEK_CUR);
-
- this->input->Seek(n, INPUT_SEEK_CUR);
- }
- else
- this->input->Seek(n, INPUT_SEEK_CUR);
- }
- else if(strncmp((char *) mb->GetData(),"idx1",4) == 0)
- {
-
- this->n_idx = this->max_idx = n/16;
- this->idx = (char((*)[16]) ) new char[n];
-
- if(this->idx == NULL) {
-
- mb->Free();
- return 0;
- }
-
- unsigned long read;
- MediaBuffer *mbi = new MediaBuffer();
- mbi->Alloc(n);
- if( (read = this->input->Read(mbi, n)) != n ) {
-
- break;
- }
- memcpy(this->idx, mbi->GetData(), n);
- mbi->Free();
- }
- else {
-
- this->input->Seek(n, INPUT_SEEK_CUR);
- }
- }
-
- if(!hdrl_data) {
-
- mb->Free();
- return 0;
- }
-
- if(!this->movi_start) {
-
- mb->Free();
- return 0;
- }
-
-
- for(i=0; i < hdrl_len; )
- {
-
- if(strncmp(hdrl_data + i, "LIST", 4)==0)
- {
- i+= 12;
- continue;
- }
-
- n = str2ulong(hdrl_data+i+4);
- n = PAD_EVEN(n);
-
-
- if(strncmp(hdrl_data + i, "strh", 4)==0)
- {
- i += 8;
- if(strncmp(hdrl_data + i, "vids", 4) == 0 && !vids_strh_seen)
- {
- memcpy(this->compressor,hdrl_data+i+4,4);
-
- this->compressor[4] = 0;
-
- scale = str2ulong(hdrl_data+i+20);
- rate = str2ulong(hdrl_data+i+24);
-
- if(scale!=0)
- this->fps = (double)rate/(double)scale;
-
- this->video_frames = str2ulong(hdrl_data+i+32);
- this->video_strn = num_stream;
-
- vids_strh_seen = 1;
- lasttag = 1;
- }
- else if (strncmp (hdrl_data + i, "auds", 4) == 0 && ! auds_strh_seen)
- {
- this->audio_bytes = str2ulong(hdrl_data + i + 32)*this->SampleSize();
- this->audio_strn = num_stream;
-
- auds_strh_seen = 1;
- lasttag = 2;
- }
- else
- lasttag = 0;
- num_stream++;
- }
- else if(strncmp(hdrl_data + i, "strf", 4)==0)
- {
- i += 8;
- if(lasttag == 1)
- {
-
- memcpy(&this->bitmapinfoheader,
- hdrl_data + i,
- sizeof(BITMAPINFOHEADER));
-
- this->width = str2ulong(hdrl_data+i+4);
- this->height = str2ulong(hdrl_data+i+8);
- vids_strf_seen = 1;
- }
- else if(lasttag == 2)
- {
- memcpy(&this->waveformatex,
- hdrl_data + i,
- sizeof(MPEGLAYER3WAVEFORMAT));
- this->a_fmt = str2ushort(hdrl_data + i );
- this->a_chans = str2ushort(hdrl_data + i + 2);
- this->a_rate = str2ulong (hdrl_data + i + 4);
- this->a_bits = str2ushort(hdrl_data + i + 14) == 0 ? 16 : str2ushort(hdrl_data + i + 14);
-
- auds_strf_seen = 1;
- }
- lasttag = 0;
- }
- else
- {
- i += 8;
- lasttag = 0;
- }
-
- i += n;
- }
-
- free(hdrl_data);
-
- if(!vids_strh_seen || !vids_strf_seen || this->video_frames==0) {
-
- mb->Free();
- return 0;
- }
-
- this->video_tag[0] = this->video_strn/10 + '0';
- this->video_tag[1] = this->video_strn%10 + '0';
- this->video_tag[2] = 'd';
- this->video_tag[3] = 'b';
-
- if(!this->a_chans)
- this->audio_strn = 99;
-
- this->audio_tag[0] = this->audio_strn/10 + '0';
- this->audio_tag[1] = this->audio_strn%10 + '0';
- this->audio_tag[2] = 'w';
- this->audio_tag[3] = 'b';
-
- this->input->Seek(this->movi_start, INPUT_SEEK_SET);
-
- if(!getIndex)
- return 1;
-
-
- idx_type = 0;
-
- if(this->idx)
- {
- unsigned long pos, len;
-
-
- for(i = 0; i < this->n_idx; i++) {
- if( strncmp(this->idx[i], this->video_tag, 3) == 0 )
- break;
- }
-
- if(i >= this->n_idx)
- return 0;
-
- pos = str2ulong(this->idx[i] + 8);
- len = str2ulong(this->idx[i] + 12);
-
- this->input->Seek(pos, INPUT_SEEK_SET);
-
- if(this->input->Read(mb, 8)!=8)
- return 0;
-
- if( strncmp((char *) mb->GetData(), this->idx[i], 4) == 0 && str2ulong((char *) mb->GetData() + 4) == len )
- {
-
- idx_type = 1;
- }
- else
- {
- this->input->Seek(pos + this->movi_start - 4,INPUT_SEEK_SET);
-
- if(this->input->Read(mb, 8) != 8)
- return 0;
-
- if( strncmp((char *) mb->GetData(), this->idx[i], 4) == 0 && str2ulong((char *) mb->GetData() + 4) == len )
- {
-
- idx_type = 2;
- }
- }
- }
-
- if(idx_type == 0)
- {
-
- this->input->Seek(this->movi_start, INPUT_SEEK_SET);
-
- this->max_idx = 4096;
- this->n_idx = 0;
- this->idx = (char((*)[16]) ) new char[this->max_idx];
-
- while(1)
- {
-
- if( this->input->Read(mb, 8) != 8 )
- break;
-
- n = str2ulong((char *) mb->GetData() + 4);
-
-
- if(strncmp((char *) mb->GetData(), "LIST", 4) == 0)
- {
- this->input->Seek(4, INPUT_SEEK_CUR);
- continue;
- }
-
-
- if( ((((char *) mb->GetData())[2]=='d' || ((char *) mb->GetData())[2]=='D') &&
- (((char *) mb->GetData())[3]=='b' || ((char *) mb->GetData())[3]=='B' ||
- ((char *) mb->GetData())[3]=='c' || ((char *) mb->GetData())[3]=='C') ) ||
- ((((char *) mb->GetData())[2]=='w' || ((char *) mb->GetData())[2]=='W') &&
- (((char *) mb->GetData())[3]=='b' || ((char *) mb->GetData())[3]=='B') ) )
- {
- this->AddIndexEntry(((char *) mb->GetData()),
- 0,
- this->input->Seek(0, INPUT_SEEK_CUR) - 8,
- n);
- }
-
- this->input->Seek(PAD_EVEN(n), INPUT_SEEK_CUR);
- }
- idx_type = 1;
- }
-
-
- nvi = 0;
- nai = 0;
-
- for(i=0; i < this->n_idx; i++)
- {
- if(strncmp(this->idx[i], this->video_tag, 3) == 0)
- nvi++;
-
- if(strncmp(this->idx[i], this->audio_tag, 4) == 0)
- nai++;
- }
-
- this->video_frames = nvi;
- this->audio_chunks = nai;
-
- if(this->video_frames == 0) {
-
- mb->Free();
- return 0;
- }
- this->video_index = (video_index_entry *) new char[(nvi*sizeof(video_index_entry))];
-
- if(this->video_index == 0) {
-
- mb->Free();
- return 0;
- }
- if(this->audio_chunks)
- {
- this->audio_index = (audio_index_entry *) new char[(nai*sizeof(audio_index_entry))];
-
- if(this->audio_index == 0) {
- mb->Free();
- return 0;
- }
- }
-
- nvi = 0;
- nai = 0;
- tot = 0;
-
- ioff = idx_type == 1 ? 8 : this->movi_start+4;
-
- for(i=0; i < this->n_idx; i++)
- {
- if(strncmp(this->idx[i], this->video_tag, 3) == 0)
- {
- this->video_index[nvi].flags = str2ulong(this->idx[i]+ 4);
- this->video_index[nvi].pos = str2ulong(this->idx[i]+ 8)+ioff;
- this->video_index[nvi].len = str2ulong(this->idx[i]+12);
-
- nvi++;
- }
- if(strncmp(this->idx[i], this->audio_tag, 4) == 0)
- {
- this->audio_index[nai].pos = str2ulong(this->idx[i]+ 8)+ioff;
- this->audio_index[nai].len = str2ulong(this->idx[i]+12);
- this->audio_index[nai].tot = tot;
-
- tot += this->audio_index[nai].len;
-
- nai++;
- }
- }
-
- this->audio_bytes = tot;
-
-
- this->input->Seek(this->movi_start, INPUT_SEEK_SET);
-
- this->video_pos = 0;
- mb->Free();
-
- return 1;
- }
- int MediaDecapsAVI::AddIndexEntry(char *tag,
- long flags,
- long pos,
- long len)
- {
- void *ptr;
-
- if(this->n_idx*16 >= this->max_idx)
- {
- ptr = realloc((void *)this->idx,
- (this->max_idx + 4096) * 16);
-
- if(ptr == 0) {
- return -1;
- }
-
- this->max_idx += 4096;
- this->idx = (char((*)[16]) ) ptr;
- }
-
-
- memcpy(this->idx[this->n_idx], tag, 4);
-
- long2str(this->idx[this->n_idx]+ 4, flags);
-
- long2str(this->idx[this->n_idx]+ 8, pos);
-
- long2str(this->idx[this->n_idx]+12, len);
-
-
- this->n_idx++;
-
- return 0;
- }
- int MediaDecapsAVI::ReFillIndex()
- {
- unsigned long n;
- long idx_type;
- long i;
- long nvi, nai, ioff;
- long tot;
- MediaBuffer *mb = new MediaBuffer();
-
- if(this->input == NULL)
- return MP_RESULT_ERROR;
- mb->Alloc(256);
- this->input->Seek(this->movi_start, INPUT_SEEK_SET);
-
- this->max_idx = 4096;
- this->n_idx = 0;
- this->idx = (char((*)[16]) ) realloc(this->idx, this->max_idx*16);
-
- while(1)
- {
-
- if( this->input->Read(mb, 8) != 8 )
- break;
-
- n = str2ulong((char *) mb->GetData() + 4);
-
-
- if(strncmp((char *) mb->GetData(), "LIST", 4) == 0)
- {
- this->input->Seek(4, INPUT_SEEK_CUR);
- continue;
- }
-
-
- if( ((((char *) mb->GetData())[2]=='d' || ((char *) mb->GetData())[2]=='D') &&
- (((char *) mb->GetData())[3]=='b' || ((char *) mb->GetData())[3]=='B' ||
- ((char *) mb->GetData())[3]=='c' || ((char *) mb->GetData())[3]=='C') ) ||
- ((((char *) mb->GetData())[2]=='w' || ((char *) mb->GetData())[2]=='W') &&
- (((char *) mb->GetData())[3]=='b' || ((char *) mb->GetData())[3]=='B') ) )
- {
- this->AddIndexEntry(((char *) mb->GetData()),
- 0,
- this->input->Seek(0, INPUT_SEEK_CUR) - 8,
- n);
- }
-
- this->input->Seek(PAD_EVEN(n), INPUT_SEEK_CUR);
- }
- idx_type = 1;
-
-
- nvi = 0;
- nai = 0;
-
- for(i=0; i < this->n_idx; i++)
- {
- if(strncmp(this->idx[i], this->video_tag, 3) == 0)
- nvi++;
-
- if(strncmp(this->idx[i], this->audio_tag, 4) == 0)
- nai++;
- }
-
- this->video_frames = nvi;
- this->audio_chunks = nai;
-
- if(this->video_frames == 0)
- return 0;
-
- this->video_index = (video_index_entry *) realloc(this->video_index, nvi*sizeof(video_index_entry));
-
- if(this->video_index == 0)
- return 0;
-
- if(this->audio_chunks)
- {
- this->audio_index = (audio_index_entry *) realloc(this->audio_index, nai*sizeof(audio_index_entry));
-
- if(this->audio_index==0) {
- mb->Free();
- return 0;
- }
- }
-
- nvi = 0;
- nai = 0;
- tot = 0;
-
- ioff = idx_type == 1 ? 8 : this->movi_start+4;
-
- for(i=0; i < this->n_idx; i++)
- {
- if(strncmp(this->idx[i], this->video_tag, 3) == 0)
- {
- this->video_index[nvi].flags = str2ulong(this->idx[i]+ 4);
- this->video_index[nvi].pos = str2ulong(this->idx[i]+ 8)+ioff;
- this->video_index[nvi].len = str2ulong(this->idx[i]+12);
-
- nvi++;
- }
- if(strncmp(this->idx[i], this->audio_tag, 4) == 0)
- {
- this->audio_index[nai].pos = str2ulong(this->idx[i]+ 8)+ioff;
- this->audio_index[nai].len = str2ulong(this->idx[i]+12);
- this->audio_index[nai].tot = tot;
-
- tot += this->audio_index[nai].len;
-
- nai++;
- }
- }
-
- this->audio_bytes = tot;
- mb->Free();
- return 1;
- }
- BOOL MediaDecapsAVI::isKeyframe(long frame)
- {
- if(frame < 0 || frame > this->video_frames)
- frame = 0;
- if(!this->video_index)
- {
-
- return 1;
- }
- return this->video_index[frame].flags & AVIIF_KEYFRAME;
- }
- unsigned int MediaDecapsAVI::GetNumberOfVideoStreams()
- {
- return 1;
- }
- unsigned int MediaDecapsAVI::GetNumberOfAudioStreams()
- {
- if(this->audio_strn == 99)
- return 0;
-
- return this->audio_strn;
- }
- unsigned int MediaDecapsAVI::GetVideoWidth(unsigned int StreamId)
- {
- return this->width;
- }
- unsigned int MediaDecapsAVI::GetVideoHeight(unsigned int StreamId)
- {
- return this->height;
- }
- double MediaDecapsAVI::GetVideoFrameRate(unsigned int StreamId)
- {
- if(this->fps == 0)
- this->fps = 25;
- if(this->fps == 23)
- this->fps = 25;
- return this->fps;
- }
- char *MediaDecapsAVI::GetVideoCompression(unsigned int StreamId)
- {
- return this->compressor;
- }
- BITMAPINFOHEADER *MediaDecapsAVI::GetVideoHeader(unsigned int StreamId)
- {
- return &this->bitmapinfoheader;
- }
- unsigned long MediaDecapsAVI::GetCurrentVideoFrame(unsigned int StreamId)
- {
- return this->video_pos;
- }
- unsigned long MediaDecapsAVI::GetTotalVideoFrames(unsigned int StreamId)
- {
- return this->video_frames;
- }
- unsigned long MediaDecapsAVI::GetTotalVideoTime(unsigned int StreamId)
- {
- if(this->fps == 0) {
-
- return 0;
- }
- else {
-
- return (unsigned long) (this->video_frames * 1000 / (double) this->fps);
- }
- }
-
- unsigned int MediaDecapsAVI::GetAudioBits(unsigned int StreamId)
- {
- return this->a_bits;
- }
- unsigned int MediaDecapsAVI::GetAudioChannels(unsigned int StreamId)
- {
- return this->a_chans;
- }
- unsigned int MediaDecapsAVI::GetAudioFrequency(unsigned int StreamId)
- {
- return this->a_rate;
- }
- WAVEFORMATEX *MediaDecapsAVI::GetAudioFormat(unsigned int StreamId)
- {
- return (WAVEFORMATEX *) &this->waveformatex;
- }
- unsigned int MediaDecapsAVI::GetNextVideoFrameSize(unsigned int StreamId)
- {
- if(!this->video_index) {
- return 0;
- }
- return(this->video_index[this->video_pos].len);
- }
- unsigned int MediaDecapsAVI::ReadVideoFrame(unsigned int StreamId, MediaBuffer *mb)
- {
- unsigned int m;
- unsigned int n;
- if(!this->video_index || !mb) {
-
- return MP_RESULT_ERROR;
- }
- if(this->video_pos < 0 || this->video_pos >= this->video_frames - 1) {
- return MP_RESULT_ERROR;
- }
- WaitForSingleObject(this->hIOMutex, INFINITE);
- n = this->video_index[this->video_pos].len;
- this->input->Seek(this->video_index[this->video_pos].pos, INPUT_SEEK_SET);
- if(mb->GetSize() < n) {
-
- mb->ReAlloc(n);
- }
- if ((m = this->input->Read(mb, n)) != n) {
- this->video_pos++;
- ReleaseMutex(this->hIOMutex);
- char msg[256];
- sprintf(msg, "index %u and %u at %u", this->video_index[this->video_pos].len, this->video_index[this->video_pos].pos, this->video_pos);
- MessageBox(NULL, msg, "", MB_OK);
- sprintf(msg, "read %d on %u at %d on %d", m, n, this->video_pos, this->video_frames);
- MessageBox(NULL, msg, "", MB_OK);
-
- return n;
- }
- this->video_pos++;
-
- ReleaseMutex(this->hIOMutex);
- return MP_RESULT_OK;
- }
- unsigned int MediaDecapsAVI::ReadAudioData(unsigned int StreamId, char *buffer, unsigned int bytes)
- {
- unsigned int nr, pos, left = 0, todo, posc, posb, asked_bytes;
- MediaBuffer *mbi = new MediaBuffer();
- if(!this->audio_index || !buffer) {
-
- return MP_RESULT_ERROR;
- }
- asked_bytes = bytes;
- posc = this->audio_posc;
- posb = this->audio_posb;
- nr = 0;
- mbi->Alloc(bytes);
- WaitForSingleObject(this->hIOMutex, INFINITE);
- while(bytes > 0) {
- left = this->audio_index[this->audio_posc].len - this->audio_posb;
- if(left == 0) {
- if(this->audio_posc >= this->audio_chunks - 1) {
-
- ReleaseMutex(this->hIOMutex);
- this->audio_posb = posb;
- this->audio_posc = posc;
- return 0;
- }
- this->audio_posc++;
- this->audio_posb = 0;
- continue;
- }
- if(bytes < left)
- todo = bytes;
- else
- todo = left;
- pos = this->audio_index[this->audio_posc].pos + this->audio_posb;
-
- this->input->Seek(pos, INPUT_SEEK_SET);
- if (this->input->Read(mbi, todo) != todo) {
- ReleaseMutex(this->hIOMutex);
- this->audio_posb = posb;
- this->audio_posc = posc;
-
- return 0;
- }
- memcpy(buffer + nr, mbi->GetData(), todo);
- bytes -= todo;
- nr += todo;
- this->audio_posb += todo;
- }
- mbi->Free();
- delete mbi;
- ReleaseMutex(this->hIOMutex);
- return asked_bytes;
- }
- MP_RESULT MediaDecapsAVI::UpdateForSize()
- {
- this->ReFillIndex();
-
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::SeekAudio(unsigned int StreamId, long bytes)
- {
- long n0, n1, n;
- if(!this->audio_index) {
- return MP_RESULT_ERROR;
- }
- if(bytes < 0)
- bytes = 0;
- n0 = 0;
- n1 = this->audio_chunks;
- while(n0 < n1 - 1)
- {
- n = (n0 + n1) / 2;
- if(this->audio_index[n].tot > bytes)
- n1 = n;
- else
- n0 = n;
- }
- this->audio_posc = n0;
- if(this->audio_index[n0].len > 1000) {
- this->audio_posb = bytes - this->audio_index[n0].tot;
- }
- else {
- this->audio_posb = 0;
- }
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::SeekVideo(unsigned int StreamId, long frame)
- {
- if(!this->video_index) {
-
- return MP_RESULT_ERROR;
- }
- if (frame < 0 ) {
-
- frame = 0;
- }
-
- this->video_pos = frame;
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::ReSeekAudio(unsigned int StreamId)
- {
- double ratio;
- long audio_bytes;
- if(this->GetNumberOfAudioStreams() > 0) {
- WaitForSingleObject(this->hIOMutex, INFINITE);
- ratio = (double) ((double) this->video_pos / (double) this->video_frames);
-
- audio_bytes = (long) (ratio * this->audio_bytes);
- audio_bytes -= (audio_bytes % this->waveformatex.nBlockSize);
- this->SeekAudio(StreamId, audio_bytes);
- ReleaseMutex(this->hIOMutex);
- }
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::Seek(unsigned int videoStreamId, unsigned int audioStreamId, int percent)
- {
- long frame;
- double ratio;
- long audio_bytes;
-
- WaitForSingleObject(this->hIOMutex, INFINITE);
- frame = (long) (percent * this->video_frames / 100);
-
-
- while(!this->isKeyframe(frame) && frame < this->video_frames) {
- frame++;
- }
- if(frame >= this->video_frames)
- frame = 0;
-
- this->SeekVideo(videoStreamId, frame);
- if(this->GetNumberOfAudioStreams() > 0) {
-
- ratio = (double) ((double) frame / (double) this->video_frames);
-
-
- audio_bytes = (long) (ratio * this->audio_bytes);
- audio_bytes -= (audio_bytes % this->waveformatex.nBlockSize);
- this->SeekAudio(audioStreamId, audio_bytes);
- ReleaseMutex(this->hIOMutex);
- return MP_RESULT_OK;
- }
- ReleaseMutex(this->hIOMutex);
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::Rewind(unsigned int videoStreamId, unsigned int audioStreamId)
- {
- this->video_pos = 0;
- this->audio_posc = 0;
- this->audio_posb = 0;
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::SeekNextKeyFrame(unsigned int StreamId)
- {
- WaitForSingleObject(this->hIOMutex, INFINITE);
- this->video_pos++;
- while(!isKeyframe(this->video_pos) && this->video_pos < this->video_frames)
- this->video_pos++;
- ReleaseMutex(this->hIOMutex);
- return MP_RESULT_OK;
- }
- MP_RESULT MediaDecapsAVI::SeekPreviousKeyFrame(unsigned int StreamId)
- {
- WaitForSingleObject(this->hIOMutex, INFINITE);
-
- if(this->video_pos > 1) {
- this->video_pos--;
- this->video_pos--;
- }
- while(!isKeyframe(this->video_pos) && this->video_pos > 0)
- this->video_pos--;
- ReleaseMutex(this->hIOMutex);
- return MP_RESULT_OK;
- }