qcap: Add Avi Mux IBaseFilter::Stop implementation.

This commit is contained in:
Piotr Caban 2014-02-26 13:36:45 +01:00 committed by Alexandre Julliard
parent fea6fedf29
commit dddc278b4d
1 changed files with 137 additions and 2 deletions

View File

@ -444,8 +444,143 @@ static HRESULT queue_sample(AviMux *avimux, AviMuxIn *avimuxin, IMediaSample *sa
static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
{
AviMux *This = impl_from_IBaseFilter(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
HRESULT hr;
int i;
TRACE("(%p)\n", This);
if(This->filter.state == State_Stopped)
return S_OK;
if(This->out->stream) {
AVIEXTHEADER dmlh;
RIFFCHUNK rc;
RIFFLIST rl;
int idx1_off, empty_stream;
empty_stream = This->out->cur_stream;
for(i=empty_stream+1; ; i++) {
if(i >= This->input_pin_no-1)
i = 0;
if(i == empty_stream)
break;
This->out->cur_stream = i;
hr = flush_queue(This, This->in[This->out->cur_stream], TRUE);
if(FAILED(hr))
return hr;
}
idx1_off = This->out->size;
rc.fcc = ckidAVIOLDINDEX;
rc.cb = This->idx1_entries * sizeof(*This->idx1);
hr = out_write(This, &rc, sizeof(rc));
if(FAILED(hr))
return hr;
hr = out_write(This, This->idx1, This->idx1_entries * sizeof(*This->idx1));
if(FAILED(hr))
return hr;
/* native writes 8 '\0' characters after the end of RIFF data */
i = 0;
hr = out_write(This, &i, sizeof(i));
if(FAILED(hr))
return hr;
hr = out_write(This, &i, sizeof(i));
if(FAILED(hr))
return hr;
for(i=0; i<This->input_pin_no; i++) {
if(!This->in[i]->pin.pin.pConnectedTo)
continue;
hr = out_seek(This, This->in[i]->ix_off);
if(FAILED(hr))
return hr;
This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].qwOffset = This->in[i]->ix_off;
This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwSize = sizeof(This->in[i]->ix_data);
This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwDuration = This->in[i]->strh.dwLength;
if(This->in[i]->indx->nEntriesInUse) {
This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwDuration -=
This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse-1].dwDuration;
}
This->in[i]->indx->nEntriesInUse++;
hr = out_write(This, This->in[i]->ix, sizeof(This->in[i]->ix_data));
if(FAILED(hr))
return hr;
}
hr = out_seek(This, 0);
if(FAILED(hr))
return hr;
rl.fcc = FCC('R','I','F','F');
rl.cb = This->out->size-sizeof(RIFFCHUNK)-2*sizeof(int);
rl.fccListType = FCC('A','V','I',' ');
hr = out_write(This, &rl, sizeof(rl));
if(FAILED(hr))
return hr;
rl.fcc = FCC('L','I','S','T');
rl.cb = This->out->movi_off - sizeof(RIFFLIST) - sizeof(RIFFCHUNK);
rl.fccListType = FCC('h','d','r','l');
hr = out_write(This, &rl, sizeof(rl));
if(FAILED(hr))
return hr;
/* FIXME: set This->avih.dwMaxBytesPerSec value */
This->avih.dwTotalFrames = (This->stop-This->start) / 10 / This->avih.dwMicroSecPerFrame;
hr = out_write(This, &This->avih, sizeof(This->avih));
if(FAILED(hr))
return hr;
for(i=0; i<This->input_pin_no; i++) {
if(!This->in[i]->pin.pin.pConnectedTo)
continue;
rl.cb = sizeof(FOURCC) + sizeof(AVISTREAMHEADER) + sizeof(RIFFCHUNK) +
This->in[i]->strf->cb + sizeof(This->in[i]->indx_data);
rl.fccListType = ckidSTREAMLIST;
hr = out_write(This, &rl, sizeof(rl));
if(FAILED(hr))
return hr;
hr = out_write(This, &This->in[i]->strh, sizeof(AVISTREAMHEADER));
if(FAILED(hr))
return hr;
hr = out_write(This, This->in[i]->strf, sizeof(RIFFCHUNK) + This->in[i]->strf->cb);
if(FAILED(hr))
return hr;
hr = out_write(This, This->in[i]->indx, sizeof(This->in[i]->indx_data));
if(FAILED(hr))
return hr;
}
rl.cb = sizeof(dmlh) + sizeof(FOURCC);
rl.fccListType = ckidODML;
hr = out_write(This, &rl, sizeof(rl));
if(FAILED(hr))
return hr;
memset(&dmlh, 0, sizeof(dmlh));
dmlh.fcc = ckidAVIEXTHEADER;
dmlh.cb = sizeof(dmlh) - sizeof(RIFFCHUNK);
dmlh.dwGrandFrames = This->in[0]->strh.dwLength;
hr = out_write(This, &dmlh, sizeof(dmlh));
rl.cb = idx1_off - This->out->movi_off - sizeof(RIFFCHUNK);
rl.fccListType = FCC('m','o','v','i');
out_write(This, &rl, sizeof(rl));
out_flush(This);
IStream_Release(This->out->stream);
This->out->stream = NULL;
}
This->filter.state = State_Stopped;
return S_OK;
}
static HRESULT WINAPI AviMux_Pause(IBaseFilter *iface)