Пример #1
0
static PyObject*
DVDA_Title_next_track(decoders_DVDA_Title *self, PyObject *args)
{
    unsigned PTS_ticks;
    DVDA_Packet next_packet;
    struct bs_buffer* packet_data = self->packet_data;
    unsigned i;

    if (!PyArg_ParseTuple(args, "I", &PTS_ticks))
        return NULL;

    /*ensure previous track has been exhausted, if any*/
    if (self->pcm_frames_remaining) {
        PyErr_SetString(PyExc_ValueError,
                        "current track has not been exhausted");
        return NULL;
    }

    /*read the next packet*/
    if (read_audio_packet(self->packet_reader,
                          &next_packet, packet_data)) {
        PyErr_SetString(PyExc_IOError,
                        "I/O error reading initialization packet");
        return NULL;
    }
#else
int
DVDA_Title_next_track(decoders_DVDA_Title *self, unsigned PTS_ticks)
{
    DVDA_Packet next_packet;
    struct bs_buffer* packet_data = self->packet_data;
    unsigned i;

    if (self->pcm_frames_remaining) {
        fprintf(stderr, "current track has not been exhausted\n");
        return 0;
    }

    if (read_audio_packet(self->packet_reader,
                          &next_packet, packet_data)) {
        fprintf(stderr, "I/O error reading initialization packet\n");
        return 0;
    }
#endif

    if (next_packet.codec_ID == PCM_CODEC_ID) {
        /*if the packet is PCM, initialize Title's stream attributes
          (bits-per-sample, sample rate, channel assignment/mask)
          with values taken from the first packet*/

        /*PCM stores stream attributes in the second padding block*/
        self->bits_per_sample =
            dvda_bits_per_sample(next_packet.PCM.group_1_bps);
        self->sample_rate =
            dvda_sample_rate(next_packet.PCM.group_1_rate);
        self->channel_assignment =
            next_packet.PCM.channel_assignment;
        self->channel_count =
            dvda_channel_count(next_packet.PCM.channel_assignment);
        self->channel_mask =
            dvda_channel_mask(next_packet.PCM.channel_assignment);

        self->frame_codec = PCM;

        init_aobpcm_decoder(&(self->pcm_decoder),
                            self->bits_per_sample,
                            self->channel_count);

        buf_extend(packet_data, self->frames);

    } else if (next_packet.codec_ID == MLP_CODEC_ID) {
        /*if the packet is MLP,
          check if the first frame starts with a major sync*/
        enum {PACKET_DATA};
        BitstreamReader* r = br_open_buffer(packet_data, BS_BIG_ENDIAN);
        r->mark(r, PACKET_DATA);
        if (!setjmp(*br_try(r))) {
            unsigned sync_words;
            unsigned stream_type;

            r->parse(r, "32p 24u 8u", &sync_words, &stream_type);
            if ((sync_words == 0xF8726F) && (stream_type == 0xBB)) {
                /*if so, discard any unconsumed packet data
                  and initialize Title's stream attributes
                  with values taken from the major sync*/

                unsigned group_1_bps;
                unsigned group_2_bps;
                unsigned group_1_rate;
                unsigned group_2_rate;

                r->parse(r, "4u 4u 4u 4u 11p 5u 48p",
                         &group_1_bps, &group_2_bps,
                         &group_1_rate, &group_2_rate,
                         &(self->channel_assignment));

                self->bits_per_sample =
                    dvda_bits_per_sample(group_1_bps);
                self->sample_rate =
                    dvda_sample_rate(group_1_rate);
                self->channel_count =
                    dvda_channel_count(self->channel_assignment);
                self->channel_mask =
                    dvda_channel_mask(self->channel_assignment);
                self->frame_codec = MLP;
                self->mlp_decoder->major_sync_read = 0;

                r->rewind(r, PACKET_DATA);
                r->unmark(r, PACKET_DATA);
                br_etry(r);
                r->close(r);

                buf_reset(self->frames);
                buf_extend(packet_data, self->frames);
            } else {
                /*if not, append packet data to any unconsumed data
                  and leave Title's stream attributes as they were*/

                r->rewind(r, PACKET_DATA);
                r->unmark(r, PACKET_DATA);
                br_etry(r);
                r->close(r);

                buf_extend(packet_data, self->frames);
            }
        } else {
            /*if I/O error reading major sync,
              append packet data to any unconsumed data
              and leave Title's stream attributes as they were*/

            r->rewind(r, PACKET_DATA);
            r->unmark(r, PACKET_DATA);
            br_etry(r);
            r->close(r);

            buf_extend(packet_data, self->frames);
        }

    } else {
#ifndef STANDALONE
        PyErr_SetString(PyExc_ValueError, "unknown codec ID");
        return NULL;
#else
        return 0;
#endif
    }

    /*convert PTS ticks to PCM frames based on sample rate*/
    self->pcm_frames_remaining = (unsigned)round((double)PTS_ticks *
                                                 (double)self->sample_rate /
                                                 (double)PTS_PER_SECOND);

    /*initalize codec's framelist with the proper number of channels*/
    if (self->codec_framelist->len != self->channel_count) {
        self->codec_framelist->reset(self->codec_framelist);
        for (i = 0; i < self->channel_count; i++)
            self->codec_framelist->append(self->codec_framelist);
    }

#ifndef STANDALONE
    Py_INCREF(Py_None);
    return Py_None;
#else
    return 1;
#endif
}
static PyObject*
TrackReader_sample_rate(dvda_TrackReader *self, void *closure)
{
    return Py_BuildValue("I", dvda_sample_rate(self->reader));
}