| | 87 | |
|---|
| | 88 | CFStringRef myApp = MY_APP_DOMAIN; |
|---|
| | 89 | CFPreferencesAppSynchronize(myApp); |
|---|
| | 90 | CFTypeRef pass = CFPreferencesCopyAppValue(PASSTHROUGH_KEY, myApp); |
|---|
| | 91 | if(pass != NULL) |
|---|
| | 92 | { |
|---|
| | 93 | CFTypeID type = CFGetTypeID(pass); |
|---|
| | 94 | if(type == CFStringGetTypeID()) |
|---|
| | 95 | dtsPassthrough = CFStringGetIntValue((CFStringRef)pass); |
|---|
| | 96 | else if(type == CFNumberGetTypeID()) |
|---|
| | 97 | CFNumberGetValue((CFNumberRef)pass, kCFNumberIntType, &dtsPassthrough); |
|---|
| | 98 | else |
|---|
| | 99 | dtsPassthrough = 0; |
|---|
| | 100 | CFRelease(pass); |
|---|
| | 101 | } |
|---|
| | 102 | else |
|---|
| | 103 | dtsPassthrough = 0; |
|---|
| | 379 | #define AV_RL16(x) EndianU16_LtoN(*(uint16_t *)(x)) |
|---|
| | 380 | #define AV_RB16(x) EndianU16_BtoN(*(uint16_t *)(x)) |
|---|
| | 381 | |
|---|
| | 382 | int produceDTSPassthroughPackets(Byte *outputBuffer, int *outBufUsed, uint8_t *packet, int packetSize, int channelCount) |
|---|
| | 383 | { |
|---|
| | 384 | if(packetSize < 96) |
|---|
| | 385 | return 0; |
|---|
| | 386 | |
|---|
| | 387 | uint32_t mrk = AV_RB16(packet) << 16 | AV_RB16(packet + 2); |
|---|
| | 388 | unsigned int frameSize = 0; |
|---|
| | 389 | unsigned int blockCount = 0; |
|---|
| | 390 | bool repackage = 0; |
|---|
| | 391 | |
|---|
| | 392 | switch (mrk) { |
|---|
| | 393 | case DCA_MARKER_RAW_BE: |
|---|
| | 394 | blockCount = (AV_RB16(packet + 4) >> 2) & 0x7f; |
|---|
| | 395 | frameSize = (AV_RB16(packet + 4) & 0x3) << 12 | (AV_RB16(packet + 6) >> 4) & 0xfff; |
|---|
| | 396 | repackage = 1; |
|---|
| | 397 | break; |
|---|
| | 398 | case DCA_MARKER_RAW_LE: |
|---|
| | 399 | blockCount = (AV_RL16(packet + 4) >> 2) & 0x7f; |
|---|
| | 400 | frameSize = (AV_RL16(packet + 4) & 0x3) << 12 | (AV_RL16(packet + 6) >> 4) & 0xfff; |
|---|
| | 401 | repackage = 1; |
|---|
| | 402 | break; |
|---|
| | 403 | case DCA_MARKER_14B_BE: |
|---|
| | 404 | case DCA_MARKER_14B_LE: |
|---|
| | 405 | default: |
|---|
| | 406 | return -1; |
|---|
| | 407 | } |
|---|
| | 408 | |
|---|
| | 409 | blockCount++; |
|---|
| | 410 | frameSize++; |
|---|
| | 411 | int originalFrameSize = frameSize; |
|---|
| | 412 | if(packetSize < frameSize) |
|---|
| | 413 | return 0; |
|---|
| | 414 | |
|---|
| | 415 | uint16_t newFrame[frameSize * 4 / 7]; |
|---|
| | 416 | if(repackage) |
|---|
| | 417 | { |
|---|
| | 418 | int spareBitCount = 0; |
|---|
| | 419 | uint16_t spareBits = 0; |
|---|
| | 420 | uint16_t *newFrameData = newFrame; |
|---|
| | 421 | int i; |
|---|
| | 422 | |
|---|
| | 423 | for(i=0; i<frameSize; i+= 2) |
|---|
| | 424 | { |
|---|
| | 425 | uint16_t readBits = (mrk == DCA_MARKER_RAW_BE) ? AV_RB16(packet + i) : AV_RL16(packet + i); |
|---|
| | 426 | uint16_t newData = spareBits | readBits >> (2 + spareBitCount); |
|---|
| | 427 | if(newData & 0x2000) |
|---|
| | 428 | *newFrameData = newData | 0xc000; |
|---|
| | 429 | else |
|---|
| | 430 | *newFrameData = newData; |
|---|
| | 431 | spareBits = (readBits << (12 - spareBitCount)) & 0x3fff; |
|---|
| | 432 | spareBitCount += 2; |
|---|
| | 433 | if(spareBitCount == 14) |
|---|
| | 434 | { |
|---|
| | 435 | if(spareBits & 0x2000) |
|---|
| | 436 | newFrameData[1] = spareBits | 0xc000; |
|---|
| | 437 | else |
|---|
| | 438 | newFrameData[1] = spareBits; |
|---|
| | 439 | spareBitCount = 0; |
|---|
| | 440 | spareBits = 0; |
|---|
| | 441 | newFrameData += 2; |
|---|
| | 442 | } |
|---|
| | 443 | else |
|---|
| | 444 | newFrameData++; |
|---|
| | 445 | } |
|---|
| | 446 | if(spareBitCount != 0) |
|---|
| | 447 | { |
|---|
| | 448 | spareBits << 14 - spareBitCount; |
|---|
| | 449 | if(spareBits & 0x2000) |
|---|
| | 450 | newFrameData[1] = spareBits | 0xc000; |
|---|
| | 451 | else |
|---|
| | 452 | newFrameData[1] = spareBits; |
|---|
| | 453 | newFrameData ++; |
|---|
| | 454 | } |
|---|
| | 455 | |
|---|
| | 456 | packet = (uint8_t *)newFrame; |
|---|
| | 457 | frameSize = (newFrameData - newFrame) * 2; |
|---|
| | 458 | } |
|---|
| | 459 | |
|---|
| | 460 | int totalSize = blockCount * 256 * channelCount / 4; |
|---|
| | 461 | if(channelCount == 2) |
|---|
| | 462 | { |
|---|
| | 463 | memcpy(outputBuffer, packet, frameSize); |
|---|
| | 464 | memset(outputBuffer+frameSize, 0, totalSize - frameSize); |
|---|
| | 465 | } |
|---|
| | 466 | else |
|---|
| | 467 | { |
|---|
| | 468 | memset(outputBuffer, 0, totalSize); |
|---|
| | 469 | int i; |
|---|
| | 470 | int offset = 2; |
|---|
| | 471 | for(i=0; i<frameSize; i+= 4) |
|---|
| | 472 | { |
|---|
| | 473 | memcpy(outputBuffer + offset, packet + i, 4); |
|---|
| | 474 | offset += 2 * channelCount; |
|---|
| | 475 | } |
|---|
| | 476 | } |
|---|
| | 477 | |
|---|
| | 478 | *outBufUsed = totalSize; |
|---|
| | 479 | |
|---|
| | 480 | return originalFrameSize; |
|---|
| | 481 | } |
|---|
| | 482 | |
|---|
| 390 | | int len = avcodec_decode_audio2(avContext, (int16_t *)outputBuffer, &outBufUsed, packet, packetSize); |
|---|
| | 517 | int len; |
|---|
| | 518 | if(dtsPassthrough) |
|---|
| | 519 | len = produceDTSPassthroughPackets(outputBuffer, &outBufUsed, packet, packetSize, avContext->channels); |
|---|
| | 520 | else |
|---|
| | 521 | len = avcodec_decode_audio2(avContext, (int16_t *)outputBuffer, &outBufUsed, packet, packetSize); |
|---|