Changeset 371 for dsfilters/dec_mpc/src/mpc_filter.cpp
- Timestamp:
- 12/15/07 14:49:14 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
dsfilters/dec_mpc/src/mpc_filter.cpp
r370 r371 42 42 CUnknown *CMPCDecoder::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) 43 43 { 44 if (phr) *phr = NOERROR; 45 44 46 return new CMPCDecoder(pUnk, phr); 45 47 } 46 48 47 49 CMPCDecoder::CMPCDecoder(LPUNKNOWN pUnk, HRESULT *phr) : 48 CTransformFilter(_T("MPC Decoder"), pUnk, CLSID_MusepackDecoder) 49 { 50 CTransformFilter(_T("MPC Decoder"), pUnk, CLSID_MusepackDecoder), 51 demux(NULL), 52 decoder_specific(NULL), 53 decoder_specific_size(0) 54 { 55 if (phr) *phr = NOERROR; 56 50 57 m_pInput = new CTransformInputPin(NAME("Input"), this, phr, L"Input"); 51 58 m_pOutput = new CTransformOutputPin(NAME("Output"), this, phr, L"Output"); … … 108 115 if (pmt->formattype != FORMAT_WaveFormatEx) return E_FAIL; 109 116 110 WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat; 117 // keep a local copy so our decoder specific info doesn't go away 118 mtIn = *pmt; 119 120 WAVEFORMATEX *wfx = (WAVEFORMATEX*)mtIn.pbFormat; 111 121 112 122 // we assemble output format … … 116 126 wfOut.wFormatTag = WAVE_FORMAT_PCM; 117 127 wfOut.wBitsPerSample = 16; // currently only 16-bit 128 129 // get hold of decoder specific info 130 decoder_specific = ((BYTE*)wfx) + sizeof(WAVEFORMATEX); 131 decoder_specific_size = wfx->cbSize; 132 133 mpc_demux *dmx; 134 135 int ret = OpenDemux(&dmx, &stream_info); 136 if (ret < 0) { 137 mpc_demux_exit(dmx); 138 return E_FAIL; 139 } 140 141 // if the stream_info says something different... 142 if (stream_info.sample_freq != wfx->nSamplesPerSec || 143 stream_info.channels != wfx->nChannels 144 ) { 145 146 // update values 147 wfOut.nChannels = stream_info.channels; 148 wfOut.nSamplesPerSec = stream_info.sample_freq; 149 } 150 118 151 wfOut.nBlockAlign = (wfOut.wBitsPerSample * wfOut.nChannels) >> 3; 119 152 wfOut.nAvgBytesPerSec = wfOut.nBlockAlign * wfOut.nSamplesPerSec; 120 153 154 // done with the demuxer 155 mpc_demux_exit(dmx); 121 156 } 122 157 return NOERROR; … … 133 168 m_pOutput->Disconnect(); 134 169 } 170 171 // cancel out decoder specific info 172 decoder_specific = NULL; 173 decoder_specific_size = 0; 135 174 } 136 175 return __super::BreakConnect(dir); … … 195 234 HRESULT hr = __super::StartStreaming(); 196 235 if (FAILED(hr)) return hr; 236 237 ASSERT(!demux); 238 239 // now let's open the demuxer 240 int ret = OpenDemux(&demux, &stream_info); 241 if (ret < 0) return E_FAIL; 242 197 243 return hr; 198 244 } … … 202 248 HRESULT hr = __super::StopStreaming(); 203 249 if (FAILED(hr)) return hr; 250 251 // done with demuxer 252 mpc_demux_exit(demux); 253 demux = NULL; 254 204 255 return hr; 205 256 } 206 257 258 #define FLOAT_CLIP(x) (x < -1.0 ? -1.0 : x > 1.0 ? 1.0 : x) 259 260 static void convert_float_to_int16_c(float *src, short *dst, int count) 261 { 262 count -= 8; 263 while (count > 0) { 264 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 265 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 266 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 267 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 268 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 269 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 270 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 271 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 272 count -= 8; 273 } 274 count += 8; 275 276 // last few must be done one-by-one 277 while (count > 0) { 278 *dst++ = (short)(FLOAT_CLIP(*src) * 16380); src++; 279 count --; 280 } 281 } 282 207 283 HRESULT CMPCDecoder::Receive(IMediaSample *pSample) 208 284 { 209 285 if (!m_pOutput->IsConnected()) return NOERROR; 210 286 211 // todo: 212 return NOERROR; 213 } 214 215 216 287 // we receive whole AP packets so just decode the frames :D 288 BYTE *pdata = NULL; 289 long lsize = 0; 290 pSample->GetPointer(&pdata); 291 lsize = pSample->GetActualDataLength(); 292 293 // set the reader 294 reader.SetData(pdata, lsize); 295 reader.AppendSE(); 296 297 // manually clear the buffer for demuxer 298 demux->bytes_total = 0; 299 demux->bits_reader.buff = demux->buffer; 300 demux->bits_reader.count = 8; 301 demux->block_bits = 0; 302 demux->block_frames = 0; 303 304 // TODO: use some more clever way of doing this. 305 MPC_SAMPLE_FORMAT samples[1152 * 8]; 306 int dec_samples; 307 308 // handling timestamps 309 REFERENCE_TIME rtStart, rtStop; 310 __int64 current_sample = 0; 311 __int64 samples_to_skip = 0; 312 bool has_timestamp = false; 313 314 if (pSample->GetTime(&rtStart, &rtStop) == NOERROR) { 315 has_timestamp = true; 316 // calculate relative sample_time 317 current_sample = (rtStart * stream_info.sample_freq) / 10000000; 318 319 if (current_sample < 0) { 320 samples_to_skip = -current_sample; 321 } 322 } 323 324 // now scan through the frames 325 while (true) { 326 327 //--------------------------------------------------------------------- 328 // Decoding Part 329 //--------------------------------------------------------------------- 330 331 mpc_frame_info frame; 332 mpc_status err; 333 334 frame.buffer = (MPC_SAMPLE_FORMAT*)samples; 335 336 // decode one frame 337 err = mpc_demux_decode(demux, &frame); 338 if (err != MPC_STATUS_OK) break; 339 if (frame.bits == -1) break; // done. 340 341 //--------------------------------------------------------------------- 342 // Skipping samples... 343 //--------------------------------------------------------------------- 344 345 MPC_SAMPLE_FORMAT *src_samples = frame.buffer; 346 int decoded_time_samples = frame.samples; 347 348 if (has_timestamp) { 349 if (samples_to_skip > 0) { 350 351 // skip sample counters 352 __int64 to_skip = min(frame.samples, samples_to_skip); 353 decoded_time_samples -= to_skip; 354 current_sample += to_skip; 355 src_samples += (to_skip * stream_info.channels); 356 } 357 } 358 359 // if there's nothing left, continue 360 if (decoded_time_samples <= 0) continue; 361 362 // total number of decoded samples 363 dec_samples = decoded_time_samples * stream_info.channels; 364 365 //--------------------------------------------------------------------- 366 // Convert and deliver 367 //--------------------------------------------------------------------- 368 369 // deliver decoded data 370 IMediaSample *sample; 371 HRESULT hr; 372 hr = GetDeliveryBuffer(&sample); 373 if (FAILED(hr)) break; // perhaps allocator is decommited 374 375 BYTE *outp; 376 sample->GetPointer(&outp); 377 378 // this should definitely be true 379 ASSERT(sample->GetSize() >= (dec_samples * sizeof(short))); 380 381 // do format conversion 382 #ifdef MPC_FIXED_POINT 383 // TODO: find ranges in headers somewhere 384 #else 385 convert_float_to_int16_c((float*)src_samples, (short*)outp, dec_samples); 386 sample->SetActualDataLength(dec_samples * sizeof(short)); 387 #endif 388 389 // IMediaSample properties 390 if (has_timestamp) { 391 REFERENCE_TIME tstart, tstop; 392 tstart = (current_sample * 10000000) / stream_info.sample_freq; 393 tstop = ((current_sample+decoded_time_samples) * 10000000) / stream_info.sample_freq; 394 sample->SetTime(&tstart, &tstop); 395 } 396 sample->SetSyncPoint(TRUE); 397 sample->SetDiscontinuity(FALSE); 398 399 // advance time 400 current_sample += decoded_time_samples; 401 402 hr = m_pOutput->Deliver(sample); 403 sample->Release(); 404 405 // something went wrong. stop decoding. 406 if (FAILED(hr)) break; 407 } 408 409 return NOERROR; 410 } 411 412 int CMPCDecoder::OpenDemux(mpc_demux **dmx, mpc_streaminfo *si) 413 { 414 // some data needed 415 if (!decoder_specific || decoder_specific_size <= 0) return -1; 416 417 reader.SetData(decoder_specific, decoder_specific_size); 418 (*dmx) = mpc_demux_init(&reader.rd); 419 if (!(*dmx)) return -1; 420 421 mpc_demux_get_info((*dmx), si); 422 return 0; 423 } 424 425 426 //----------------------------------------------------------------------------- 427 // 428 // CMPCReader class 429 // 430 //----------------------------------------------------------------------------- 431 432 static mpc_int32_t mpc_read_proc(mpc_reader *p_reader, void *ptr, mpc_int32_t size) 433 { 434 CMPCReader *instance = (CMPCReader*)p_reader->data; 435 ASSERT(instance); 436 return instance->Read(ptr, size); 437 } 438 439 static mpc_bool_t mpc_seek_proc(mpc_reader *p_reader, mpc_int32_t offset) 440 { 441 CMPCReader *instance = (CMPCReader*)p_reader->data; 442 ASSERT(instance); 443 return instance->Seek(offset); 444 } 445 446 static mpc_int32_t mpc_tell_proc(mpc_reader *p_reader) 447 { 448 CMPCReader *instance = (CMPCReader*)p_reader->data; 449 ASSERT(instance); 450 return instance->Tell(); 451 } 452 453 static mpc_int32_t mpc_get_size_proc(mpc_reader *p_reader) 454 { 455 CMPCReader *instance = (CMPCReader*)p_reader->data; 456 ASSERT(instance); 457 return instance->GetSize(); 458 } 459 460 static mpc_bool_t mpc_canseek_proc(mpc_reader *p_reader) 461 { 462 CMPCReader *instance = (CMPCReader*)p_reader->data; 463 ASSERT(instance); 464 return instance->CanSeek(); 465 } 466 467 CMPCReader::CMPCReader() 468 { 469 buf = (BYTE*)malloc(256*1024); // 256 KB should be enough 470 size = 0; 471 472 rd.data = (void*)this; 473 rd.read = mpc_read_proc; 474 rd.seek = mpc_seek_proc; 475 rd.tell = mpc_tell_proc; 476 rd.get_size = mpc_get_size_proc; 477 rd.canseek = mpc_canseek_proc; 478 } 479 480 CMPCReader::~CMPCReader() 481 { 482 free(buf); 483 } 484 485 int CMPCReader::Read(void *buf, int size) 486 { 487 // return the number of bytes read 488 int toread_max = min(this->size - this->pos, size); 489 memcpy(buf, this->buf + this->pos, toread_max); 490 this->pos += toread_max; 491 return toread_max; 492 } 493 494 bool CMPCReader::Seek(int offset) 495 { 496 // sorry no seeking here 497 return false; 498 } 499 500 int CMPCReader::Tell() 501 { 502 // that's where we are 503 return pos; 504 } 505 506 int CMPCReader::GetSize() 507 { 508 // size of our supplied buffer 509 return size; 510 } 511 512 bool CMPCReader::CanSeek() 513 { 514 // no. we are not seekable. upstream demuxer is. 515 return false; 516 } 517 518 void CMPCReader::SetData(BYTE *data, int size) 519 { 520 ASSERT(size < 256*1024); 521 memcpy(buf, data, size); 522 this->size = size; 523 this->pos = 0; 524 } 525 526 void CMPCReader::AppendSE() 527 { 528 BYTE *out = buf + size; 529 out[0] = 'S'; 530 out[1] = 'E'; 531 out[2] = 0x03; 532 size += 3; 533 } 534 535 536 537 538 539 540 541
Note: See TracChangeset
for help on using the changeset viewer.