static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
                            const DVprofile *sys)
{
    int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
    uint16_t lc, rc;
    const uint8_t* as_pack;
    uint8_t *pcm, ipcm;
    as_pack = dv_extract_pack(frame, dv_audio_source);
    if (!as_pack)    /* No audio ? */
        return 0;
    smpls =  as_pack[1] & 0x3f;       /* samples in this frame - min. samples */
    freq  = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
    quant =  as_pack[4] & 0x07;       /* 0 - 16bit linear, 1 - 12bit nonlinear */
    if (quant > 1)
        return -1; /* unsupported quantization */
    if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
    size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
    half_ch = sys->difseg_size / 2;
    /* We work with 720p frames split in half, thus even frames have
     * channels 0,1 and odd 2,3. */
    ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
    /* for each DIF channel */
    for (chan = 0; chan < sys->n_difchan; chan++) {
        av_assert0(ipcm<4);
        pcm = ppcm[ipcm++];
        if (!pcm)
            break;
        /* for each DIF segment */
        for (i = 0; i < sys->difseg_size; i++) {
            frame += 6 * 80; /* skip DIF segment header */
            if (quant == 1 && i == half_ch) {
                /* next stereo channel (12bit mode only) */
                av_assert0(ipcm<4);
                pcm = ppcm[ipcm++];
                if (!pcm)
                    break;
            /* for each AV sequence */
            for (j = 0; j < 9; j++) {
                for (d = 8; d < 80; d += 2) {
                    if (quant == 0) {  /* 16bit quantization */
                        of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
                        if (of*2 >= size)
                            continue;
                        pcm[of*2]   = frame[d+1]; // FIXME: maybe we have to admit
                        pcm[of*2+1] = frame[d];   //        that DV is a big-endian PCM
                        if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
                            pcm[of*2+1] = 0;
                    } else {           /* 12bit quantization */
                        lc = ((uint16_t)frame[d]   << 4) |
                             ((uint16_t)frame[d+2] >> 4);
                        rc = ((uint16_t)frame[d+1] << 4) |
                             ((uint16_t)frame[d+2] & 0x0f);
                        lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
                        rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
                        of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
                        if (of*2 >= size)
                            continue;
                        pcm[of*2]   = lc & 0xff; // FIXME: maybe we have to admit
                        pcm[of*2+1] = lc >> 8;   //        that DV is a big-endian PCM
                        of = sys->audio_shuffle[i%half_ch+half_ch][j] +
                            (d - 8) / 3 * sys->audio_stride;
                        pcm[of*2]   = rc & 0xff; // FIXME: maybe we have to admit
                        pcm[of*2+1] = rc >> 8;   //        that DV is a big-endian PCM
                        ++d;
                frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
    return size;
static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
                            const DVprofile *sys)
{
    int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
    uint16_t lc, rc;
    const uint8_t* as_pack;
    uint8_t *pcm, ipcm;
    as_pack = dv_extract_pack(frame, dv_audio_source);
    if (!as_pack)    
        return 0;
    smpls =  as_pack[1] & 0x3f;       
    freq  = (as_pack[4] >> 3) & 0x07; 
    quant =  as_pack[4] & 0x07;       
    if (quant > 1)
        return -1; 
    if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
    size = (sys->audio_min_samples[freq] + smpls) * 4; 
    half_ch = sys->difseg_size / 2;
    

    ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
    
    for (chan = 0; chan < sys->n_difchan; chan++) {
        av_assert0(ipcm<4);
        pcm = ppcm[ipcm++];
        if (!pcm)
            break;
        
        for (i = 0; i < sys->difseg_size; i++) {
            frame += 6 * 80; 
            if (quant == 1 && i == half_ch) {
                
                av_assert0(ipcm<4);
                pcm = ppcm[ipcm++];
                if (!pcm)
                    break;
            
            for (j = 0; j < 9; j++) {
                for (d = 8; d < 80; d += 2) {
                    if (quant == 0) {  
                        of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
                        if (of*2 >= size)
                            continue;
                        pcm[of*2]   = frame[d+1]; 
                        pcm[of*2+1] = frame[d];   
                        if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
                            pcm[of*2+1] = 0;
                    } else {           
                        lc = ((uint16_t)frame[d]   << 4) |
                             ((uint16_t)frame[d+2] >> 4);
                        rc = ((uint16_t)frame[d+1] << 4) |
                             ((uint16_t)frame[d+2] & 0x0f);
                        lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
                        rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
                        of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
                        if (of*2 >= size)
                            continue;
                        pcm[of*2]   = lc & 0xff; 
                        pcm[of*2+1] = lc >> 8;   
                        of = sys->audio_shuffle[i%half_ch+half_ch][j] +
                            (d - 8) / 3 * sys->audio_stride;
                        pcm[of*2]   = rc & 0xff; 
                        pcm[of*2+1] = rc >> 8;   
                        ++d;
                frame += 16 * 80; 
    return size;
static int FUNC_0(uint8_t* VAR_0, uint8_t* VAR_1[4],
                            const DVprofile *VAR_2)
{
    int VAR_3, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12;
    uint16_t lc, rc;
    const uint8_t* VAR_13;
    uint8_t *pcm, ipcm;
    VAR_13 = dv_extract_pack(VAR_0, dv_audio_source);
    if (!VAR_13)    
        return 0;
    VAR_9 =  VAR_13[1] & 0x3f;       
    VAR_10  = (VAR_13[4] >> 3) & 0x07; 
    VAR_11 =  VAR_13[4] & 0x07;       
    if (VAR_11 > 1)
        return -1; 
    if (VAR_10 >= FF_ARRAY_ELEMS(dv_audio_frequency))
    VAR_3 = (VAR_2->audio_min_samples[VAR_10] + VAR_9) * 4; 
    VAR_12 = VAR_2->difseg_size / 2;
    

    ipcm = (VAR_2->height == 720 && !(VAR_0[1] & 0x0C)) ? 2 : 0;
    
    for (VAR_4 = 0; VAR_4 < VAR_2->n_difchan; VAR_4++) {
        av_assert0(ipcm<4);
        pcm = VAR_1[ipcm++];
        if (!pcm)
            break;
        
        for (VAR_5 = 0; VAR_5 < VAR_2->difseg_size; VAR_5++) {
            VAR_0 += 6 * 80; 
            if (VAR_11 == 1 && VAR_5 == VAR_12) {
                
                av_assert0(ipcm<4);
                pcm = VAR_1[ipcm++];
                if (!pcm)
                    break;
            
            for (VAR_6 = 0; VAR_6 < 9; VAR_6++) {
                for (VAR_7 = 8; VAR_7 < 80; VAR_7 += 2) {
                    if (VAR_11 == 0) {  
                        VAR_8 = VAR_2->audio_shuffle[VAR_5][VAR_6] + (VAR_7 - 8) / 2 * VAR_2->audio_stride;
                        if (VAR_8*2 >= VAR_3)
                            continue;
                        pcm[VAR_8*2]   = VAR_0[VAR_7+1]; 
                        pcm[VAR_8*2+1] = VAR_0[VAR_7];   
                        if (pcm[VAR_8*2+1] == 0x80 && pcm[VAR_8*2] == 0x00)
                            pcm[VAR_8*2+1] = 0;
                    } else {           
                        lc = ((uint16_t)VAR_0[VAR_7]   << 4) |
                             ((uint16_t)VAR_0[VAR_7+2] >> 4);
                        rc = ((uint16_t)VAR_0[VAR_7+1] << 4) |
                             ((uint16_t)VAR_0[VAR_7+2] & 0x0f);
                        lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
                        rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
                        VAR_8 = VAR_2->audio_shuffle[VAR_5%VAR_12][VAR_6] + (VAR_7 - 8) / 3 * VAR_2->audio_stride;
                        if (VAR_8*2 >= VAR_3)
                            continue;
                        pcm[VAR_8*2]   = lc & 0xff; 
                        pcm[VAR_8*2+1] = lc >> 8;   
                        VAR_8 = VAR_2->audio_shuffle[VAR_5%VAR_12+VAR_12][VAR_6] +
                            (VAR_7 - 8) / 3 * VAR_2->audio_stride;
                        pcm[VAR_8*2]   = rc & 0xff; 
                        pcm[VAR_8*2+1] = rc >> 8;   
                        ++VAR_7;
                VAR_0 += 16 * 80; 
    return VAR_3;
static int FUNC_0(uint8_t* VAR_0, uint8_t* VAR_1[4],
const DVprofile *VAR_2)
{ int VAR_3, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10, VAR_11, VAR_12; uint16_t lc, rc; const uint8_t* VAR_13; uint8_t *pcm, ipcm; VAR_13 = dv_extract_pack(VAR_0, dv_audio_source); if (!VAR_13)
return 0; VAR_9 =  VAR_13[1] & 0x3f; VAR_10  = (VAR_13[4] >> 3) & 0x07; VAR_11 =  VAR_13[4] & 0x07; if (VAR_11 > 1)
return -1; if (VAR_10 >= FF_ARRAY_ELEMS(dv_audio_frequency))
VAR_3 = (VAR_2->audio_min_samples[VAR_10] + VAR_9) * 4; VAR_12 = VAR_2->difseg_size / 2; ipcm = (VAR_2->height == 720 && !(VAR_0[1] & 0x0C)) ? 2 : 0; for (VAR_4 = 0; VAR_4 < VAR_2->n_difchan; VAR_4++) { av_assert0(ipcm<4); pcm = VAR_1[ipcm++]; if (!pcm)
break; for (VAR_5 = 0; VAR_5 < VAR_2->difseg_size; VAR_5++) { VAR_0 += 6 * 80; if (VAR_11 == 1 && VAR_5 == VAR_12) { av_assert0(ipcm<4); pcm = VAR_1[ipcm++]; if (!pcm)
break; for (VAR_6 = 0; VAR_6 < 9; VAR_6++) { for (VAR_7 = 8; VAR_7 < 80; VAR_7 += 2) { if (VAR_11 == 0) { VAR_8 = VAR_2->audio_shuffle[VAR_5][VAR_6] + (VAR_7 - 8) / 2 * VAR_2->audio_stride; if (VAR_8*2 >= VAR_3)
continue; pcm[VAR_8*2]   = VAR_0[VAR_7+1]; pcm[VAR_8*2+1] = VAR_0[VAR_7]; if (pcm[VAR_8*2+1] == 0x80 && pcm[VAR_8*2] == 0x00)
pcm[VAR_8*2+1] = 0; } else { lc = ((uint16_t)VAR_0[VAR_7]   << 4) |
((uint16_t)VAR_0[VAR_7+2] >> 4); rc = ((uint16_t)VAR_0[VAR_7+1] << 4) |
((uint16_t)VAR_0[VAR_7+2] & 0x0f); lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); VAR_8 = VAR_2->audio_shuffle[VAR_5%VAR_12][VAR_6] + (VAR_7 - 8) / 3 * VAR_2->audio_stride; if (VAR_8*2 >= VAR_3)
continue; pcm[VAR_8*2]   = lc & 0xff; pcm[VAR_8*2+1] = lc >> 8; VAR_8 = VAR_2->audio_shuffle[VAR_5%VAR_12+VAR_12][VAR_6] +
(VAR_7 - 8) / 3 * VAR_2->audio_stride; pcm[VAR_8*2]   = rc & 0xff; pcm[VAR_8*2+1] = rc >> 8; ++VAR_7; VAR_0 += 16 * 80; return VAR_3;