private int processPacket(final boolean readPage) {
   while (true) {
     if (this.m_decodeReady) {
       final int result = this.m_oggStreamState.packetout(this.m_oggPacket);
       if (result > 0) {
         long granulepos = this.m_oggPacket.granulepos;
         if (this.m_block.synthesis(this.m_oggPacket) == 0) {
           this.m_dspState.synthesis_blockin(this.m_block);
           if (granulepos != -1L) {
             final int link = this.m_vorbisStream.isSeekable() ? this.m_currentLink : 0;
             final int samples = this.m_dspState.synthesis_pcmout(null, null);
             granulepos = Math.max(0L, granulepos - samples);
             for (int i = 0; i < link; ++i) {
               granulepos += this.m_pcmLengths[i];
             }
             this.m_pcmOffset = granulepos;
           }
           return 1;
         }
       }
     }
     if (!readPage) {
       return 0;
     }
     if (this.getNextPage(this.m_oggPage, -1L) < 0) {
       return 0;
     }
     if (this.m_decodeReady && this.m_currentSerialno != this.m_oggPage.serialno()) {
       this.decodeClear();
     }
     if (!this.m_decodeReady) {
       if (this.m_vorbisStream.isSeekable()) {
         this.m_currentSerialno = this.m_oggPage.serialno();
         int j;
         for (j = 0; j < this.m_links && this.m_serialnos[j] != this.m_currentSerialno; ++j) {}
         if (j == this.m_links) {
           return -1;
         }
         this.m_currentLink = j;
         this.m_oggStreamState.init(this.m_currentSerialno);
         this.m_oggStreamState.reset();
       } else {
         final int[] serialnos = {0};
         final int ret =
             this.fetchHeaders(this.m_info[0], this.m_comments[0], serialnos, this.m_oggPage);
         this.m_currentSerialno = serialnos[0];
         if (ret != 0) {
           return ret;
         }
         ++this.m_currentLink;
       }
       this.makeDecodeReady();
     }
     this.m_oggStreamState.pagein(this.m_oggPage);
   }
 }