static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2,
                            const DVprofile *sys)
{
    int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
    uint16_t lc, rc;
    const uint8_t* as_pack;
    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;
    size = (sys->audio_min_samples[freq] + smpls) * 4;
    half_ch = sys->difseg_size/2;
    for (chan = 0; chan < sys->n_difchan; chan++) {
        for (i = 0; i < sys->difseg_size; i++) {
            frame += 6 * 80;
            if (quant == 1 && i == half_ch) {
                if (!pcm2)
                    break;
                else
                    pcm = pcm2;
            }
            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;
            }
        }
        if(!pcm2)
            break;
        pcm = pcm2;
    }
    return size;
}
['static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)\n{\n    MOVContext *mov = s->priv_data;\n    MOVStreamContext *sc = 0;\n    AVIndexEntry *sample = 0;\n    int64_t best_dts = INT64_MAX;\n    int i;\n retry:\n    for (i = 0; i < s->nb_streams; i++) {\n        AVStream *st = s->streams[i];\n        MOVStreamContext *msc = st->priv_data;\n        if (st->discard != AVDISCARD_ALL && msc->pb && msc->current_sample < msc->sample_count) {\n            AVIndexEntry *current_sample = &st->index_entries[msc->current_sample];\n            int64_t dts = av_rescale(current_sample->timestamp * (int64_t)msc->time_rate,\n                                     AV_TIME_BASE, msc->time_scale);\n            dprintf(s, "stream %d, sample %d, dts %"PRId64"\\n", i, msc->current_sample, dts);\n            if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||\n                (!url_is_streamed(s->pb) &&\n                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&\n                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||\n                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {\n                sample = current_sample;\n                best_dts = dts;\n                sc = msc;\n            }\n        }\n    }\n    if (!sample) {\n        mov->found_mdat = 0;\n        if (!url_is_streamed(s->pb) ||\n            mov_read_default(mov, s->pb, (MOV_atom_t){ 0, 0, INT64_MAX }) < 0 ||\n            url_feof(s->pb))\n            return -1;\n        dprintf(s, "read fragments, offset 0x%llx\\n", url_ftell(s->pb));\n        goto retry;\n    }\n    sc->current_sample++;\n    if (url_fseek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {\n        av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\\n",\n               sc->ffindex, sample->pos);\n        return -1;\n    }\n    av_get_packet(sc->pb, pkt, sample->size);\n#ifdef CONFIG_DV_DEMUXER\n    if (mov->dv_demux && sc->dv_audio_container) {\n        dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);\n        av_free(pkt->data);\n        pkt->size = 0;\n        if (dv_get_packet(mov->dv_demux, pkt) < 0)\n            return -1;\n    }\n#endif\n    pkt->stream_index = sc->ffindex;\n    pkt->dts = sample->timestamp;\n    if (sc->ctts_data) {\n        assert(sc->ctts_data[sc->sample_to_ctime_index].duration % sc->time_rate == 0);\n        pkt->pts = pkt->dts + sc->ctts_data[sc->sample_to_ctime_index].duration / sc->time_rate;\n        sc->sample_to_ctime_sample++;\n        if (sc->sample_to_ctime_index < sc->ctts_count &&\n            sc->ctts_data[sc->sample_to_ctime_index].count == sc->sample_to_ctime_sample) {\n            sc->sample_to_ctime_index++;\n            sc->sample_to_ctime_sample = 0;\n        }\n    } else {\n        pkt->pts = pkt->dts;\n    }\n    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;\n    pkt->pos = sample->pos;\n    dprintf(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\\n",\n            pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);\n    return 0;\n}', 'int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)\n{\n    int ret= av_new_packet(pkt, size);\n    if(ret<0)\n        return ret;\n    pkt->pos= url_ftell(s);\n    ret= get_buffer(s, pkt->data, size);\n    if(ret<=0)\n        av_free_packet(pkt);\n    else\n        pkt->size= ret;\n    return ret;\n}', 'int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,\n                      uint8_t* buf, int buf_size)\n{\n    int size, i;\n    if (buf_size < DV_PROFILE_BYTES ||\n        !(c->sys = dv_frame_profile(buf)) ||\n        buf_size < c->sys->frame_size) {\n          return -1;\n    }\n    size = dv_extract_audio_info(c, buf);\n    for (i=0; i<c->ach; i++) {\n       c->audio_pkt[i].size = size;\n       c->audio_pkt[i].pts  = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;\n    }\n    dv_extract_audio(buf, c->audio_buf[0], c->audio_buf[1], c->sys);\n    c->abytes += size;\n    size = dv_extract_video_info(c, buf);\n    av_init_packet(pkt);\n    pkt->data     = buf;\n    pkt->size     = size;\n    pkt->flags   |= PKT_FLAG_KEY;\n    pkt->stream_index = c->vst->id;\n    pkt->pts      = c->frames;\n    c->frames++;\n    return size;\n}', 'static inline const DVprofile* dv_frame_profile(const uint8_t* frame)\n{\n    if ((frame[3] & 0x80) == 0) {\n        if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) {\n            return &dv_profiles[3];\n        } else {\n            return &dv_profiles[0];\n        }\n    } else {\n        if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) {\n            return &dv_profiles[4];\n        } else if ((frame[5] & 0x07) == 0) {\n            return &dv_profiles[1];\n        } else\n            return &dv_profiles[2];\n    }\n}', 'static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)\n{\n    const uint8_t* as_pack;\n    int freq, stype, smpls, quant, i, ach;\n    as_pack = dv_extract_pack(frame, dv_audio_source);\n    if (!as_pack || !c->sys) {\n        c->ach = 0;\n        return 0;\n    }\n    smpls = as_pack[1] & 0x3f;\n    freq = (as_pack[4] >> 3) & 0x07;\n    stype = (as_pack[3] & 0x1f);\n    quant = as_pack[4] & 0x07;\n    ach = (stype == 2 || (quant && (freq == 2))) ? 2 : 1;\n    for (i=0; i<ach; i++) {\n       if (!c->ast[i]) {\n           c->ast[i] = av_new_stream(c->fctx, 0);\n           if (!c->ast[i])\n               break;\n           av_set_pts_info(c->ast[i], 64, 1, 30000);\n           c->ast[i]->codec->codec_type = CODEC_TYPE_AUDIO;\n           c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;\n           av_init_packet(&c->audio_pkt[i]);\n           c->audio_pkt[i].size     = 0;\n           c->audio_pkt[i].data     = c->audio_buf[i];\n           c->audio_pkt[i].stream_index = c->ast[i]->index;\n           c->audio_pkt[i].flags |= PKT_FLAG_KEY;\n       }\n       c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];\n       c->ast[i]->codec->channels = 2;\n       c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;\n       c->ast[i]->start_time = 0;\n    }\n    c->ach = i;\n    return (c->sys->audio_min_samples[freq] + smpls) * 4;  ;\n}', 'static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)\n{\n    int offs;\n    switch (t) {\n    case dv_audio_source:\n          offs = (80*6 + 80*16*3 + 3);\n          break;\n    case dv_audio_control:\n          offs = (80*6 + 80*16*4 + 3);\n          break;\n    case dv_video_control:\n          offs = (80*5 + 48 + 5);\n          break;\n    default:\n          return NULL;\n    }\n    return (frame[offs] == t ? &frame[offs] : NULL);\n}', 'static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2,\n                            const DVprofile *sys)\n{\n    int size, chan, i, j, d, of, smpls, freq, quant, half_ch;\n    uint16_t lc, rc;\n    const uint8_t* as_pack;\n    as_pack = dv_extract_pack(frame, dv_audio_source);\n    if (!as_pack)\n        return 0;\n    smpls = as_pack[1] & 0x3f;\n    freq = (as_pack[4] >> 3) & 0x07;\n    quant = as_pack[4] & 0x07;\n    if (quant > 1)\n        return -1;\n    size = (sys->audio_min_samples[freq] + smpls) * 4;\n    half_ch = sys->difseg_size/2;\n    for (chan = 0; chan < sys->n_difchan; chan++) {\n        for (i = 0; i < sys->difseg_size; i++) {\n            frame += 6 * 80;\n            if (quant == 1 && i == half_ch) {\n                if (!pcm2)\n                    break;\n                else\n                    pcm = pcm2;\n            }\n            for (j = 0; j < 9; j++) {\n                for (d = 8; d < 80; d += 2) {\n                    if (quant == 0) {\n                        of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride;\n                        if (of*2 >= size)\n                            continue;\n                        pcm[of*2] = frame[d+1];\n                        pcm[of*2+1] = frame[d];\n                        if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)\n                            pcm[of*2+1] = 0;\n                    } else {\n                        lc = ((uint16_t)frame[d] << 4) |\n                             ((uint16_t)frame[d+2] >> 4);\n                        rc = ((uint16_t)frame[d+1] << 4) |\n                             ((uint16_t)frame[d+2] & 0x0f);\n                        lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));\n                        rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));\n                        of = sys->audio_shuffle[i%half_ch][j] + (d - 8)/3 * sys->audio_stride;\n                        if (of*2 >= size)\n                            continue;\n                        pcm[of*2] = lc & 0xff;\n                        pcm[of*2+1] = lc >> 8;\n                        of = sys->audio_shuffle[i%half_ch+half_ch][j] +\n                            (d - 8)/3 * sys->audio_stride;\n                        pcm[of*2] = rc & 0xff;\n                        pcm[of*2+1] = rc >> 8;\n                        ++d;\n                    }\n                }\n                frame += 16 * 80;\n            }\n        }\n        if(!pcm2)\n            break;\n        pcm = pcm2;\n    }\n    return size;\n}']